// File: /workspace/github_cpp_makefile_star2_O1/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
pushq %rax
xorps %xmm0, %xmm0
movaps %xmm0, -0x10(%rsp)
movaps %xmm0, -0x20(%rsp)
movaps %xmm0, -0x30(%rsp)
movaps %xmm0, -0x40(%rsp)
movaps %xmm0, -0x50(%rsp)
movaps %xmm0, -0x60(%rsp)
movaps %xmm0, -0x70(%rsp)
movaps %xmm0, -0x80(%rsp)
movl %esi, %ecx
shrl $0x6, %ecx
andl $0x3f, %ecx
leaq 0xe1293(%rip), %rax     # 0xf8a70
movl %esi, %edx
andl $0x3f, %edx
movq (%rax,%rdx,8), %r11
cmpl $0x0, 0x188(%rdi,%rdx,4)
movzwl %cx, %edx
je 0x17822
andl $0x7000, %esi           # imm = 0x7000
cmpl $0x4000, %esi           # imm = 0x4000
jne 0x1780b
movl $0x352, -0x80(%rsp)     # imm = 0x352
jmp 0x1783b
movl 0x188(%rdi,%rdx,4), %ecx
leaq 0x6b87(%rip), %rsi      # 0x1e3a0
movl (%rsi,%rcx,4), %ecx
movl %ecx, -0x80(%rsp)
jmp 0x1783b
movq 0x30(%rdi), %rcx
leaq 0xe1243(%rip), %rax     # 0xf8a70
testq %rcx, (%rax,%rdx,8)
je 0x177f3
movl $0x64, -0x80(%rsp)
testq %r11, %r11
je 0x17ad4
movl (%rdi), %r10d
leaq 0x288(%rdi), %rsi
leal (,%rdx,8), %ebx
leaq 0x103024(%rip), %rcx    # 0x11a880
movq 0x2a0(%rdi), %r14
orq 0x2d0(%rdi), %r14
movq 0x2d8(%rdi), %r8
orq 0x2a8(%rdi), %r8
orq %r8, %r14
movq (%rcx,%rbx), %rcx
andq %r14, %rcx
leaq 0x102df7(%rip), %r9     # 0x11a680
movq 0x2c8(%rdi), %r15
orq 0x298(%rdi), %r15
orq %r8, %r15
movq (%r9,%rbx), %r8
andq %r15, %r8
orq %rcx, %r8
leaq (%r10,%r10,2), %rcx
shlq $0x4, %rcx
movq (%rsi,%rcx), %rcx
movl 0x4(%rdi), %r9d
leaq (%r9,%r9,2), %r12
shlq $0x9, %r9
leaq 0xe17ad(%rip), %r13     # 0xf9070
addq %r13, %r9
andq (%rbx,%r9), %rcx
shlq $0x4, %r12
movq (%rsi,%r12), %r9
movq %r10, %r12
shlq $0x9, %r12
addq %r13, %r12
andq (%rbx,%r12), %r9
orq %rcx, %r9
movq 0x2c0(%rdi), %r12
orq 0x290(%rdi), %r12
leaq 0x4248(%rip), %rcx      # 0x1bb40
andq (%rcx,%rbx), %r12
orq %r9, %r12
leaq 0x3f3a(%rip), %rcx      # 0x1b840
movq 0x80(%rdi), %r9
orq 0x78(%rdi), %r9
movq (%rcx,%rbx), %r13
andq %r9, %r13
leaq 0x3d21(%rip), %rcx      # 0x1b640
imulq (%rcx,%rbx), %r13
leaq 0xd8e5(%rip), %rbp      # 0x25210
leal (,%rdx,4), %eax
leaq 0x3c07(%rip), %rcx      # 0x1b540
movb (%rcx,%rax), %cl
shrq %cl, %r13
movq (%rbp,%rbx), %rcx
andq (%rcx,%r13,8), %r15
orq %r12, %r15
leaq 0x39ee(%rip), %rcx      # 0x1b340
movq (%rcx,%rbx), %r12
andq %r9, %r12
leaq 0x37e0(%rip), %rcx      # 0x1b140
imulq (%rcx,%rbx), %r12
leaq 0x36d4(%rip), %rcx      # 0x1b040
movb (%rcx,%rax), %cl
shrq %cl, %r12
leaq 0xda97(%rip), %rax      # 0x25410
movq (%rax,%rbx), %rax
andq (%rax,%r12,8), %r14
movq 0x2e0(%rdi), %rcx
orq 0x2b0(%rdi), %rcx
leaq 0x43aa(%rip), %rax      # 0x1bd40
andq (%rax,%rbx), %rcx
orq %r14, %rcx
orq %r15, %rcx
xorl %ebx, %ebx
leaq 0x69f7(%rip), %r14      # 0x1e3a0
leaq 0xf22c0(%rip), %r12     # 0x109c70
movl %r10d, %ebp
bsfq %r11, %r10
movl 0x188(%rdi,%r10,4), %r13d
movl (%r14,%r13,4), %eax
movl -0x80(%rsp,%rbx,4), %r15d
subl %r15d, %eax
movl %eax, -0x7c(%rsp,%rbx,4)
incq %rbx
negl %r15d
cmpl %r15d, %eax
cmovgl %eax, %r15d
testl %r15d, %r15d
js 0x17ad6
xorq %r11, %rcx
xorq %r11, %r9
cmpl $0x1, %r13d
je 0x17a34
andq %r9, %r8
shll $0x9, %r10d
addq 0xd569(%rip), %r10      # 0x24f68
movq (%r10,%rdx,8), %r10
andq %r8, %r10
testq %r10, %r10
je 0x17a34
leaq -0x1(%r10), %rax
andq %r10, %rax
bsfq %r10, %r11
movl %r11d, %r15d
shll $0x9, %r15d
addq %r12, %r15
movq %rax, %r10
testq %r9, (%r15,%rdx,8)
jne 0x17a06
leaq 0xe1040(%rip), %rax     # 0xf8a70
orq (%rax,%r11,8), %rcx
xorl %r10d, %r10d
testl %ebp, %ebp
sete %r10b
testq %rcx, 0x78(%rdi,%r10,8)
je 0x17ad6
leaq (%r10,%r10,2), %r11
movl %r11d, %eax
shll $0x4, %eax
movq (%rsi,%rax), %r13
andq %rcx, %r13
jne 0x17a9b
movl %r11d, %eax
shll $0x4, %eax
movq 0x8(%rsi,%rax), %r13
andq %rcx, %r13
jne 0x17a9b
movl %r11d, %eax
shll $0x4, %eax
movq 0x10(%rsi,%rax), %r13
andq %rcx, %r13
jne 0x17a9b
movl %r11d, %eax
shll $0x4, %eax
movq 0x18(%rsi,%rax), %r13
andq %rcx, %r13
jne 0x17a9b
movl %r11d, %eax
shll $0x4, %eax
movq 0x20(%rsi,%rax), %r13
andq %rcx, %r13
je 0x17aaf
movq %r13, %r11
negq %r11
andq %r13, %r11
testq %r11, %r11
jne 0x179b0
jmp 0x17ad6
xorl %eax, %eax
testl %ebp, %ebp
setne %al
testq %rcx, 0x78(%rdi,%rax,8)
jne 0x17ad6
shll $0x4, %r11d
movq 0x28(%rsi,%r11), %rax
andq %rcx, %rax
movq %rax, %r11
negq %r11
andq %rax, %r11
jmp 0x17aa4
xorl %ebx, %ebx
cmpl $0x2, %ebx
jl 0x17b09
movl %ebx, %eax
movl -0x84(%rsp,%rax,4), %ecx
incq %rax
xorl %edx, %edx
subl -0x8c(%rsp,%rax,4), %edx
cmpl %edx, %ecx
cmovgl %ecx, %edx
negl %edx
movl %edx, -0x8c(%rsp,%rax,4)
decq %rax
movl %edx, %ecx
cmpq $0x2, %rax
jg 0x17ae7
movl -0x80(%rsp), %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq