// File: ATOMIC-LICHESS[P]ATOMKRAFT/search.cpp
// Function: (anonymous namespace)::check_is_dangerous(Position&, Move, Value, Value, Value*)
bool check_is_dangerous(Position &pos, Move move, Value futilityBase, Value beta, Value *bestValue)
  {
    Bitboard b, occ, oldAtt, newAtt, kingAtt;
    Square from, to, ksq, victimSq;
    Piece pc;
    Color them;
    Value futilityValue, bv = *bestValue;

    from = move_from(move);
    to = move_to(move);
    them = opposite_color(pos.side_to_move());
    ksq = pos.king_square(them);
    kingAtt = pos.attacks_from<KING>(ksq);
    pc = pos.piece_on(from);

    occ = pos.occupied_squares() & ~(1ULL << from) & ~(1ULL << ksq);
    oldAtt = pos.attacks_from(pc, from, occ);
    newAtt = pos.attacks_from(pc,   to, occ);

    // Rule 1. Checks which give opponent's king at most one escape square are dangerous
    b = kingAtt & ~pos.pieces_of_color(them) & ~newAtt & ~(1ULL << to);

    if (!(b && (b & (b - 1))))
        return true;
    
    STARTOLD
    // Rule 2. Queen contact check is very dangerous
    if (   type_of_piece(pc) == QUEEN
        && bit_is_set(kingAtt, to))
        return true;
    ENDOLD
    
    STARTNEW
    // Rule 2. Queen contact check is very dangerous
    // Rook contact checks are very dangerous too!
    if (   (type_of_piece(pc) == QUEEN || type_of_piece(pc) == ROOK)
        && bit_is_set(kingAtt, to))
        return true;
    ENDNEW
    
    // Rule 3. Creating new double threats with checks
    b = pos.pieces_of_color(them) & newAtt & ~oldAtt & ~(1ULL << ksq);

    while (b)
    {
        victimSq = pop_1st_bit(&b);
        futilityValue = futilityBase + pos.endgame_value_of_piece_on(victimSq);

        // Note that here we generate illegal "double move"!
        if (   futilityValue >= beta
            && pos.see_sign(make_move(from, victimSq)) >= 0)
            return true;

        if (futilityValue > bv)
            bv = futilityValue;
    }

    // Update bestValue only if check is not dangerous (because we will prune the move)
    *bestValue = bv;
    return false;
  }

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x78(%rsp)
movl %esi, 0x74(%rsp)
movl %edx, 0x70(%rsp)
movl %ecx, 0x6c(%rsp)
movq %r8, 0x60(%rsp)
movq 0x60(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x18(%rsp)
movl 0x74(%rsp), %edi
callq 0xf680
movl %eax, 0x34(%rsp)
movl 0x74(%rsp), %edi
callq 0xf690
movl %eax, 0x30(%rsp)
movq 0x78(%rsp), %rdi
callq 0xf5d0
movl %eax, %edi
callq 0x122b0
movl %eax, 0x20(%rsp)
movq 0x78(%rsp), %rdi
movl 0x20(%rsp), %esi
callq 0x1b250
movl %eax, 0x2c(%rsp)
movq 0x78(%rsp), %rdi
movl 0x2c(%rsp), %esi
callq 0x1b440
movq %rax, 0x38(%rsp)
movq 0x78(%rsp), %rdi
movl 0x34(%rsp), %esi
callq 0xf530
movl %eax, 0x24(%rsp)
movq 0x78(%rsp), %rdi
callq 0xf510
movl 0x34(%rsp), %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movl 0x2c(%rsp), %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, 0x50(%rsp)
movl 0x24(%rsp), %edi
movl 0x34(%rsp), %esi
movq 0x50(%rsp), %rdx
callq 0x38c00
movq %rax, 0x48(%rsp)
movl 0x24(%rsp), %edi
movl 0x30(%rsp), %esi
movq 0x50(%rsp), %rdx
callq 0x38c00
movq %rax, 0x40(%rsp)
movq 0x38(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x78(%rsp), %rdi
movl 0x20(%rsp), %esi
callq 0x298c0
movq %rax, %rcx
movq 0x10(%rsp), %rax
xorq $-0x1, %rcx
andq %rcx, %rax
movq 0x40(%rsp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movl 0x30(%rsp), %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, 0x58(%rsp)
cmpq $0x0, 0x58(%rsp)
je 0x4ded4
movq 0x58(%rsp), %rax
movq 0x58(%rsp), %rcx
subq $0x1, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
jne 0x4dee1
movb $0x1, 0x87(%rsp)
jmp 0x4dffb
movl 0x24(%rsp), %edi
callq 0x12990
cmpl $0x5, %eax
je 0x4defd
movl 0x24(%rsp), %edi
callq 0x12990
cmpl $0x4, %eax
jne 0x4df1e
movq 0x38(%rsp), %rdi
movl 0x30(%rsp), %esi
callq 0xd760
cmpq $0x0, %rax
je 0x4df1e
movb $0x1, 0x87(%rsp)
jmp 0x4dffb
movq 0x78(%rsp), %rdi
movl 0x20(%rsp), %esi
callq 0x298c0
andq 0x40(%rsp), %rax
movq 0x48(%rsp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movl 0x2c(%rsp), %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, 0x58(%rsp)
cmpq $0x0, 0x58(%rsp)
je 0x4dfe8
leaq 0x58(%rsp), %rdi
callq 0xd940
movl %eax, 0x28(%rsp)
movl 0x70(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0x78(%rsp), %rdi
movl 0x28(%rsp), %esi
callq 0x4ece0
movl 0xc(%rsp), %edi
movl %eax, %esi
callq 0x1b320
movl %eax, 0x1c(%rsp)
movl 0x1c(%rsp), %eax
cmpl 0x6c(%rsp), %eax
jl 0x4dfd1
movq 0x78(%rsp), %rax
movq %rax, (%rsp)
movl 0x34(%rsp), %edi
movl 0x28(%rsp), %esi
callq 0xf810
movq (%rsp), %rdi
movl %eax, %esi
callq 0x3d470
cmpl $0x0, %eax
jl 0x4dfd1
movb $0x1, 0x87(%rsp)
jmp 0x4dffb
movl 0x1c(%rsp), %eax
cmpl 0x18(%rsp), %eax
jle 0x4dfe3
movl 0x1c(%rsp), %eax
movl %eax, 0x18(%rsp)
jmp 0x4df58
movl 0x18(%rsp), %ecx
movq 0x60(%rsp), %rax
movl %ecx, (%rax)
movb $0x0, 0x87(%rsp)
movb 0x87(%rsp), %al
andb $0x1, %al
addq $0x88, %rsp
retq
nopl (%rax)