// File: /workspace/github_cpp_makefile_star2_O2/SethKasmann[P]clever-girl/src/state.cpp
// Function: State::see(unsigned short) const
int State::see(Move m) const
{
    Prop prop;
    Color color;
    Square src, dst, mayAttack;
    PieceType target;
    U64 attackers, from, occupancy, xRay, potential;
    int gain[32] = { 0 };
    int d = 0;

    color = mUs;
    src = getSrc(m);
    dst = getDst(m);
    from = square_bb[src];
    // Check if the move is en passant.
    if (onSquare(src) == pawn && square_bb[dst] & mEnPassant)
        gain[d] = PieceValue[pawn];
    else if (getPiecePromo(m) == queen)
        gain[d] = Queen_wt - Pawn_wt;
    else
        gain[d] = PieceValue[onSquare(dst)];
    occupancy = getOccupancyBB();
    attackers = allAttackers(dst);
    // Get X ray attacks and add in pawns from attackers.
    xRay = getXRayAttacks(dst);

    while (from)
    {
        // Update the target piece and the square it came from.
        src = get_lsb(from);
        target = onSquare(src);

        // Update the depth and color.
        d++;

        // Storing the potential gain, if defended.
        gain[d] = PieceValue[target] - gain[d - 1];

        // Prune if the gain cannot be improved.
        if (std::max(-gain[d - 1], gain[d]) < 0)
            break;

        // Remove the from bit to simulate making the move.
        attackers ^= from;
        occupancy ^= from;

        // If the target is not a night, piece movement could cause a discovered
        // attacker.
        if (target != knight)
        {
            xRay &= occupancy;
            // Create a bitboard of potential discovered attackers.
            potential = coplanar[src][dst] & xRay;
            while (potential)
            {
                mayAttack = pop_lsb(potential);
                // If no bits are between the new square and the dst, there
                // is a new attacker.
                if (!(between[mayAttack][dst] & occupancy))
                {
                    attackers |= square_bb[mayAttack];
                    break;
                }
            }
        }

        // Get the next piece for the opposing player.
        color = !color;
        if (!(attackers & getOccupancyBB(color)))
            break;

        if (attackers & getPieceBB<pawn>(color))
            from = get_lsb_bb(attackers & getPieceBB<pawn>(color));
        else if (attackers & getPieceBB<knight>(color))
            from = get_lsb_bb(attackers & getPieceBB<knight>(color));
        else if (attackers & getPieceBB<bishop>(color))
            from = get_lsb_bb(attackers & getPieceBB<bishop>(color));
        else if (attackers & getPieceBB<rook>(color))
            from = get_lsb_bb(attackers & getPieceBB<rook>(color));
        else if (attackers & getPieceBB<queen>(color))
            from = get_lsb_bb(attackers & getPieceBB<queen>(color));
        else
        {
            from = get_lsb_bb(attackers & getPieceBB<king>(color));
            // Break if the king would be attacked.
            if (attackers & getOccupancyBB(!color))
                break;
        }
    }

    // Negamax the gain array to determine the final SEE value.
    while (--d > 0)
        gain[d - 1] = -std::max(-gain[d - 1], gain[d]);

    return gain[0];
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
xorps %xmm0, %xmm0
movaps %xmm0, 0x80(%rsp)
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
movl %esi, %r8d
shrl $0x6, %r8d
andl $0x3f, %r8d
movl %esi, %eax
andl $0x3f, %eax
cmpl $0x0, 0x188(%rdi,%rax,4)
movl %r8d, %r12d
je 0x134c6
andl $0x7000, %esi           # imm = 0x7000
cmpw $0x4000, %si            # imm = 0x4000
jne 0x134ae
movl $0x352, 0x10(%rsp)      # imm = 0x352
movl $0x352, %ebx            # imm = 0x352
jmp 0x134e2
movl 0x188(%rdi,%r12,4), %ecx
leaq 0x5e13(%rip), %rdx      # 0x192d0
movl (%rdx,%rcx,4), %ebx
movl %ebx, 0x10(%rsp)
jmp 0x134e2
movq 0x30(%rdi), %rcx
leaq 0x1135af(%rip), %rdx    # 0x126a80
testq %rcx, (%rdx,%r12,8)
je 0x13492
movl $0x64, 0x10(%rsp)
pushq $0x64
popq %rbx
movl (%rdi), %r15d
leaq 0x113594(%rip), %rcx    # 0x126a80
movq (%rcx,%rax,8), %rbp
movq 0x80(%rdi), %r13
orq 0x78(%rdi), %r13
movl %r8d, %esi
movq %rdi, (%rsp)
movl %r8d, 0x8(%rsp)
callq 0x14318
movq %rax, %r14
movq (%rsp), %rdi
movl 0x8(%rsp), %esi
callq 0x1440e
movq (%rsp), %r9
leaq 0x288(%r9), %rdx
xorl %ecx, %ecx
leaq 0x5da0(%rip), %rsi      # 0x192d0
leaq 0x12c749(%rip), %rdi    # 0x13fc80
leaq 0x124742(%rip), %r8     # 0x137c80
testq %rbp, %rbp
je 0x1365c
bsfq %rbp, %r10
movl 0x188(%r9,%r10,4), %r11d
movl (%rsi,%r11,4), %r9d
subl %ebx, %r9d
movl %r9d, 0x14(%rsp,%rcx,4)
incq %rcx
negl %ebx
cmpl %ebx, %r9d
cmovgl %r9d, %ebx
testl %ebx, %ebx
js 0x1365c
xorq %rbp, %r14
xorq %rbp, %r13
cmpl $0x1, %r11d
je 0x135be
andq %r13, %rax
shll $0x9, %r10d
addq %rdi, %r10
movq (%r10,%r12,8), %r10
andq %rax, %r10
testq %r10, %r10
je 0x135be
leaq -0x1(%r10), %rbx
andq %r10, %rbx
bsfq %r10, %r11
movl %r11d, %ebp
shll $0x9, %ebp
addq %r8, %rbp
movq %rbx, %r10
testq %r13, (%rbp,%r12,8)
jne 0x13590
leaq 0x1134c6(%rip), %r10    # 0x126a80
orq (%r10,%r11,8), %r14
xorl %r10d, %r10d
testl %r15d, %r15d
sete %r10b
movq (%rsp), %r11
testq %r14, 0x78(%r11,%r10,8)
je 0x1365c
imulq $0x30, %r10, %r11
movq (%rdx,%r11), %rbx
andq %r14, %rbx
jne 0x1360c
movq 0x8(%rdx,%r11), %rbx
andq %r14, %rbx
jne 0x1360c
movq 0x10(%rdx,%r11), %rbx
andq %r14, %rbx
jne 0x1360c
movq 0x18(%rdx,%r11), %rbx
andq %r14, %rbx
jne 0x1360c
movq 0x20(%rdx,%r11), %rbx
andq %r14, %rbx
je 0x13624
movq %rbx, %rbp
negq %rbp
andq %rbx, %rbp
movl %r9d, %ebx
movl %r10d, %r15d
movq (%rsp), %r9
jmp 0x1353e
xorl %ebx, %ebx
testl %r15d, %r15d
setne %bl
movq %rbx, 0x8(%rsp)
movq 0x28(%rdx,%r11), %r11
andq %r14, %r11
movq %r11, %rbp
negq %rbp
andq %r11, %rbp
movl %r9d, %ebx
movl %r10d, %r15d
movq (%rsp), %r9
movq 0x8(%rsp), %r10
testq %r14, 0x78(%r9,%r10,8)
je 0x1353e
movl %ecx, %eax
cmpl $0x2, %eax
jl 0x1367d
xorl %ecx, %ecx
subl 0x8(%rsp,%rax,4), %ecx
movl 0xc(%rsp,%rax,4), %edx
cmpl %ecx, %edx
cmovgl %edx, %ecx
negl %ecx
movl %ecx, 0x8(%rsp,%rax,4)
decq %rax
jmp 0x1365e
movl 0x10(%rsp), %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop