// File: bjohnsonfl[P]Overhead-Chess-Engine-/position.cpp
// Function: position::legal(move) const
bool position::legal (move m) const
{
    /*
     Much inspiration from stockfish in this function
     A move is legal if the king is not exposed or left in check.
     In movegeneration, only castling tests for legality, all other moves must be checked.
     If our king is in check, evasions are created, but we need to check that the king doesnt move into check.
     All king moves, except castling, needs to make sure it doesnt move into check.
     All other moves cannot be pinned except moving torwards or away from the king.
     En Passent needs to be checked for exposing the 5th (4th for black) rank in check.
     */
    
    player us  = get_sideToPlay();
    player them = player(!us);
    square from = source_sq(m);
    square to = destination_sq(m);
    square kingSq = get_king_sq(us);
    bitboard kingSqBB = get_king(us);
    bitboard piece = squareBitMask[from];
    
    //King moves
    if(kingSqBB & piece)
    {
      return (move_flag(m) == castling) || !(squareAttackedBy(to) & get_pieces(them));
    }
    
    if(move_flag(m) == enPass)
    {
        bitboard newOccupied = 0;
        square theirPawn = empty;
        theirPawn = square_to_rank(to) == rank_6 ? square( get_enPassent() + south ) :
                                                   square( get_enPassent() + nort );
        newOccupied = get_pieces() ^ squareBitMask[from] ^ squareBitMask[to] ^ squareBitMask[theirPawn];
        //printBitboard(newOccupied);
        bitboard rookQueen = sliderAttacks(kingSq, newOccupied, p_rook) & get_pieces(p_rook, p_queen) & get_pieces(them);
        bitboard bishopQueen = sliderAttacks(kingSq, newOccupied, p_bishop) & get_pieces(p_bishop, p_queen) & get_pieces(them);
        return !rookQueen && !bishopQueen;
    }
    
    return !(get_pinned(us) & squareBitMask[from]) || (lineSqBitMask[from][to] & kingSqBB);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x60(%rbp)
callq 0x75c0
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x1c(%rbp)
movl -0x14(%rbp), %edi
callq 0x7860
movl %eax, -0x20(%rbp)
movl -0x14(%rbp), %edi
callq 0x7870
movq -0x60(%rbp), %rdi
movl %eax, -0x24(%rbp)
movl -0x18(%rbp), %esi
callq 0x7640
movq -0x60(%rbp), %rdi
movl %eax, -0x28(%rbp)
movl -0x18(%rbp), %esi
callq 0x77f0
movq %rax, -0x30(%rbp)
movl -0x20(%rbp), %eax
movl %eax, %ecx
leaq 0x931c(%rip), %rax      # 0x12ea0
movq (%rax,%rcx,8), %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
andq -0x38(%rbp), %rax
cmpq $0x0, %rax
je 0x9bed
movl -0x14(%rbp), %edi
callq 0x78b0
movl %eax, %ecx
movb $0x1, %al
cmpl $0x2, %ecx
movb %al, -0x61(%rbp)
je 0x9be0
movq -0x60(%rbp), %rdi
movl -0x24(%rbp), %esi
callq 0x98b0
movq -0x60(%rbp), %rdi
movq %rax, -0x70(%rbp)
movl -0x1c(%rbp), %esi
callq 0x7600
movq %rax, %rcx
movq -0x70(%rbp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
setne %al
xorb $-0x1, %al
movb %al, -0x61(%rbp)
movb -0x61(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x9db5
movl -0x14(%rbp), %edi
callq 0x78b0
cmpl $0x1, %eax
jne 0x9d52
movq $0x0, -0x40(%rbp)
movl $0x40, -0x44(%rbp)
movl -0x24(%rbp), %edi
callq 0x59d0
cmpl $0x5, %eax
jne 0x9c2b
movq -0x60(%rbp), %rdi
callq 0x75e0
addl $-0x8, %eax
movl %eax, -0x74(%rbp)
jmp 0x9c3a
movq -0x60(%rbp), %rdi
callq 0x75e0
addl $0x8, %eax
movl %eax, -0x74(%rbp)
movq -0x60(%rbp), %rdi
movl -0x74(%rbp), %eax
movl %eax, -0x44(%rbp)
callq 0x7690
movl -0x20(%rbp), %ecx
movl %ecx, %edx
leaq 0x924b(%rip), %rcx      # 0x12ea0
xorq (%rcx,%rdx,8), %rax
movl -0x24(%rbp), %ecx
movl %ecx, %edx
leaq 0x923b(%rip), %rcx      # 0x12ea0
xorq (%rcx,%rdx,8), %rax
movl -0x44(%rbp), %ecx
movl %ecx, %edx
leaq 0x922b(%rip), %rcx      # 0x12ea0
xorq (%rcx,%rdx,8), %rax
movq %rax, -0x40(%rbp)
movl -0x28(%rbp), %edi
movq -0x40(%rbp), %rsi
movl $0x3, %edx
callq 0x57b0
movq -0x60(%rbp), %rdi
movq %rax, -0x98(%rbp)
movl $0x3, %esi
movl $0x4, %edx
callq 0x7700
movq -0x60(%rbp), %rdi
movq %rax, %rcx
movq -0x98(%rbp), %rax
andq %rcx, %rax
movq %rax, -0x90(%rbp)
movl -0x1c(%rbp), %esi
callq 0x7600
movq %rax, %rcx
movq -0x90(%rbp), %rax
andq %rcx, %rax
movq %rax, -0x50(%rbp)
movl -0x28(%rbp), %edi
movq -0x40(%rbp), %rsi
movl $0x2, %edx
callq 0x57b0
movq -0x60(%rbp), %rdi
movq %rax, -0x88(%rbp)
movl $0x2, %esi
movl $0x4, %edx
callq 0x7700
movq -0x60(%rbp), %rdi
movq %rax, %rcx
movq -0x88(%rbp), %rax
andq %rcx, %rax
movq %rax, -0x80(%rbp)
movl -0x1c(%rbp), %esi
callq 0x7600
movq %rax, %rcx
movq -0x80(%rbp), %rax
andq %rcx, %rax
movq %rax, -0x58(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x50(%rbp)
movb %al, -0x75(%rbp)
jne 0x9d48
cmpq $0x0, -0x58(%rbp)
setne %al
xorb $-0x1, %al
movb %al, -0x75(%rbp)
movb -0x75(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x9db5
movq -0x60(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0xa2a0
movq %rax, %rcx
movl -0x20(%rbp), %eax
movl %eax, %edx
leaq 0x9133(%rip), %rax      # 0x12ea0
andq (%rax,%rdx,8), %rcx
movb $0x1, %al
cmpq $0x0, %rcx
movb %al, -0x99(%rbp)
je 0x9daa
movl -0x20(%rbp), %eax
movl %eax, %ecx
leaq 0x12815(%rip), %rax     # 0x1c5a0
shlq $0x9, %rcx
addq %rcx, %rax
movl -0x24(%rbp), %ecx
movq (%rax,%rcx,8), %rax
andq -0x30(%rbp), %rax
cmpq $0x0, %rax
setne %al
movb %al, -0x99(%rbp)
movb -0x99(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)