// File: jswaff[P]prophet3/src/next.cpp
// Function: good_move(position*, unsigned long long)
bool good_move(position *p,move m) {
    if (m==BADMOVE) return false;

    square_t from_sq = get_from_sq(m);
    square_t to_sq = get_to_sq(m);
    piece_t mover = get_piece(m);
    piece_t captured_piece = get_captured_piece(m);

    if (from_sq < A8 || from_sq > H1 || to_sq < A8 || to_sq > H1) return false;

    // is the piece the correct color for the player on move?
    int32 piece_on_board = p->piece[from_sq];
    if (p->player==WHITE) {
        if (!is_white_piece(piece_on_board)) return false;
    } else {
        if (!is_black_piece(piece_on_board)) return false;
    }

    // is the piece on the from square correct?
    if (p->player==WHITE) {
        if (mover != piece_on_board) return false;
    } else {
        if (mover != -piece_on_board) return false;
    }

    if (mover==PAWN) {
        return good_pawn_move(p,m);
    }

    // validate captured piece is right color
    if (captured_piece != NO_PIECE) {
        if (p->player==WHITE) {
            if (is_not_black_piece(p->piece[to_sq])) return false;
        } else {
            if (is_not_white_piece(p->piece[to_sq])) return false;
        }
    } else {
        if (p->piece[to_sq] != NO_PIECE) return false;
    }

    if (mover==KNIGHT) {
        if (bb_knight_moves[from_sq] & bb_squares[to_sq]) return true;
    } else if (mover==BISHOP) {
        uint64 targets = p->player==WHITE ? ~p->white_pieces : ~p->black_pieces;
        if (get_bishop_moves(p,from_sq,targets) & bb_squares[to_sq]) return true;
    } else if (mover==ROOK) {
        uint64 targets = p->player==WHITE ? ~p->white_pieces : ~p->black_pieces;
        if (get_rook_moves(p,from_sq,targets) & bb_squares[to_sq]) return true;
    } else if (mover==QUEEN) {
        uint64 targets = p->player==WHITE ? ~p->white_pieces : ~p->black_pieces;
        if (get_queen_moves(p,from_sq,targets) & bb_squares[to_sq]) return true;
    } else if (mover==KING) {
        if (bb_king_moves[from_sq] & bb_squares[to_sq]) return true;
        if (is_castle(m)) {
            if (to_sq==G1 && can_castle_wk(p)
                    && p->piece[F1]==NO_PIECE && p->piece[G1]==NO_PIECE
                    && !attacked(p,E1,BLACK) && !attacked(p,F1,BLACK)) {
                return true;
            } else if (to_sq==C1 && can_castle_wq(p)
                    && p->piece[D1]==NO_PIECE && p->piece[C1]==NO_PIECE && p->piece[B1]==NO_PIECE
                    && !attacked(p,E1,BLACK) && !attacked(p,D1,BLACK)) {
                return true;
            } else if (to_sq==G8 && can_castle_bk(p) && p->piece[F8]==NO_PIECE
                    && p->piece[G8]==NO_PIECE
                    && !attacked(p,E8,WHITE) && !attacked(p,F8,WHITE)) {
                return true;
            } else if (to_sq==C8 && can_castle_bq(p)
                    && p->piece[D8]==NO_PIECE && p->piece[C8]==NO_PIECE && p->piece[B8]==NO_PIECE
                    && !attacked(p,E8,WHITE) && !attacked(p,D8,WHITE)) {
                return true;
            }
        }
    }

    return false;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0xcf10
movb $0x0, -0x1(%rbp)
jmp 0xd3fb
movq -0x18(%rbp), %rdi
callq 0xaa80
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rdi
callq 0xaaa0
movl %eax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
callq 0xaac0
movl %eax, -0x24(%rbp)
movq -0x18(%rbp), %rdi
callq 0xab00
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x1c(%rbp)
jl 0xcf58
cmpl $0x3f, -0x1c(%rbp)
jg 0xcf58
cmpl $0x0, -0x20(%rbp)
jl 0xcf58
cmpl $0x3f, -0x20(%rbp)
jle 0xcf61
movb $0x0, -0x1(%rbp)
jmp 0xd3fb
movq -0x10(%rbp), %rax
movl -0x1c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x1, 0x138(%rax)
jne 0xcf92
movl -0x2c(%rbp), %edi
callq 0x14da0
testb $0x1, %al
jne 0xcf90
movb $0x0, -0x1(%rbp)
jmp 0xd3fb
jmp 0xcfa9
movl -0x2c(%rbp), %edi
callq 0x14dc0
testb $0x1, %al
jne 0xcfa7
movb $0x0, -0x1(%rbp)
jmp 0xd3fb
jmp 0xcfa9
movq -0x10(%rbp), %rax
cmpl $0x1, 0x138(%rax)
jne 0xcfc9
movl -0x24(%rbp), %eax
cmpl -0x2c(%rbp), %eax
je 0xcfc7
movb $0x0, -0x1(%rbp)
jmp 0xd3fb
jmp 0xcfe0
movl -0x24(%rbp), %eax
xorl %ecx, %ecx
subl -0x2c(%rbp), %ecx
cmpl %ecx, %eax
je 0xcfde
movb $0x0, -0x1(%rbp)
jmp 0xd3fb
jmp 0xcfe0
cmpl $0x1, -0x24(%rbp)
jne 0xcffd
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xd690
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0xd3fb
cmpl $0x0, -0x28(%rbp)
je 0xd052
movq -0x10(%rbp), %rax
cmpl $0x1, 0x138(%rax)
jne 0xd030
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
movl (%rax,%rcx,4), %edi
callq 0x14e00
testb $0x1, %al
jne 0xd025
jmp 0xd02e
movb $0x0, -0x1(%rbp)
jmp 0xd3fb
jmp 0xd050
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
movl (%rax,%rcx,4), %edi
callq 0x14de0
testb $0x1, %al
jne 0xd045
jmp 0xd04e
movb $0x0, -0x1(%rbp)
jmp 0xd3fb
jmp 0xd050
jmp 0xd06a
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
cmpl $0x0, (%rax,%rcx,4)
je 0xd068
movb $0x0, -0x1(%rbp)
jmp 0xd3fb
jmp 0xd06a
cmpl $0x2, -0x24(%rbp)
jne 0xd0a4
movl -0x1c(%rbp), %eax
movl %eax, %ecx
leaq 0xf87f4(%rip), %rax     # 0x105870
movq (%rax,%rcx,8), %rax
movl -0x20(%rbp), %ecx
movl %ecx, %edx
leaq 0xf85e4(%rip), %rcx     # 0x105670
andq (%rcx,%rdx,8), %rax
cmpq $0x0, %rax
je 0xd09f
movb $0x1, -0x1(%rbp)
jmp 0xd3fb
jmp 0xd3f7
cmpl $0x3, -0x24(%rbp)
jne 0xd11b
movq -0x10(%rbp), %rax
cmpl $0x1, 0x138(%rax)
jne 0xd0cc
movq -0x10(%rbp), %rax
movq 0x1a8(%rax), %rax
xorq $-0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0xd0df
movq -0x10(%rbp), %rax
movq 0x1b0(%rax), %rax
xorq $-0x1, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %esi
movq -0x38(%rbp), %rdx
callq 0x8fc0
movl -0x20(%rbp), %ecx
movl %ecx, %edx
leaq 0xf856d(%rip), %rcx     # 0x105670
andq (%rcx,%rdx,8), %rax
cmpq $0x0, %rax
je 0xd116
movb $0x1, -0x1(%rbp)
jmp 0xd3fb
jmp 0xd3f5
cmpl $0x4, -0x24(%rbp)
jne 0xd192
movq -0x10(%rbp), %rax
cmpl $0x1, 0x138(%rax)
jne 0xd143
movq -0x10(%rbp), %rax
movq 0x1a8(%rax), %rax
xorq $-0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0xd156
movq -0x10(%rbp), %rax
movq 0x1b0(%rax), %rax
xorq $-0x1, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %esi
movq -0x40(%rbp), %rdx
callq 0x9170
movl -0x20(%rbp), %ecx
movl %ecx, %edx
leaq 0xf84f6(%rip), %rcx     # 0x105670
andq (%rcx,%rdx,8), %rax
cmpq $0x0, %rax
je 0xd18d
movb $0x1, -0x1(%rbp)
jmp 0xd3fb
jmp 0xd3f3
cmpl $0x5, -0x24(%rbp)
jne 0xd209
movq -0x10(%rbp), %rax
cmpl $0x1, 0x138(%rax)
jne 0xd1ba
movq -0x10(%rbp), %rax
movq 0x1a8(%rax), %rax
xorq $-0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0xd1cd
movq -0x10(%rbp), %rax
movq 0x1b0(%rax), %rax
xorq $-0x1, %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %esi
movq -0x48(%rbp), %rdx
callq 0x9120
movl -0x20(%rbp), %ecx
movl %ecx, %edx
leaq 0xf847f(%rip), %rcx     # 0x105670
andq (%rcx,%rdx,8), %rax
cmpq $0x0, %rax
je 0xd204
movb $0x1, -0x1(%rbp)
jmp 0xd3fb
jmp 0xd3f1
cmpl $0x6, -0x24(%rbp)
jne 0xd3ef
movl -0x1c(%rbp), %eax
movl %eax, %ecx
leaq 0xf8851(%rip), %rax     # 0x105a70
movq (%rax,%rcx,8), %rax
movl -0x20(%rbp), %ecx
movl %ecx, %edx
leaq 0xf8441(%rip), %rcx     # 0x105670
andq (%rcx,%rdx,8), %rax
cmpq $0x0, %rax
je 0xd242
movb $0x1, -0x1(%rbp)
jmp 0xd3fb
movq -0x18(%rbp), %rdi
callq 0xab70
testb $0x1, %al
jne 0xd254
jmp 0xd3ed
cmpl $0x3e, -0x20(%rbp)
jne 0xd2b4
movq -0x10(%rbp), %rdi
callq 0xf1e0
testb $0x1, %al
jne 0xd269
jmp 0xd2b4
movq -0x10(%rbp), %rax
cmpl $0x0, 0xf4(%rax)
jne 0xd2b4
movq -0x10(%rbp), %rax
cmpl $0x0, 0xf8(%rax)
jne 0xd2b4
movq -0x10(%rbp), %rdi
movl $0x3c, %esi
xorl %edx, %edx
callq 0x4430
testb $0x1, %al
jne 0xd2b4
movq -0x10(%rbp), %rdi
movl $0x3d, %esi
xorl %edx, %edx
callq 0x4430
testb $0x1, %al
jne 0xd2b4
movb $0x1, -0x1(%rbp)
jmp 0xd3fb
cmpl $0x3a, -0x20(%rbp)
jne 0xd321
movq -0x10(%rbp), %rdi
callq 0xf200
testb $0x1, %al
jne 0xd2c9
jmp 0xd321
movq -0x10(%rbp), %rax
cmpl $0x0, 0xec(%rax)
jne 0xd321
movq -0x10(%rbp), %rax
cmpl $0x0, 0xe8(%rax)
jne 0xd321
movq -0x10(%rbp), %rax
cmpl $0x0, 0xe4(%rax)
jne 0xd321
movq -0x10(%rbp), %rdi
movl $0x3c, %esi
xorl %edx, %edx
callq 0x4430
testb $0x1, %al
jne 0xd321
movq -0x10(%rbp), %rdi
movl $0x3b, %esi
xorl %edx, %edx
callq 0x4430
testb $0x1, %al
jne 0xd321
movb $0x1, -0x1(%rbp)
jmp 0xd3fb
cmpl $0x6, -0x20(%rbp)
jne 0xd37e
movq -0x10(%rbp), %rdi
callq 0xf220
testb $0x1, %al
jne 0xd336
jmp 0xd37e
movq -0x10(%rbp), %rax
cmpl $0x0, 0x14(%rax)
jne 0xd37e
movq -0x10(%rbp), %rax
cmpl $0x0, 0x18(%rax)
jne 0xd37e
movq -0x10(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x4430
testb $0x1, %al
jne 0xd37e
movq -0x10(%rbp), %rdi
movl $0x5, %esi
movl $0x1, %edx
callq 0x4430
testb $0x1, %al
jne 0xd37e
movb $0x1, -0x1(%rbp)
jmp 0xd3fb
cmpl $0x2, -0x20(%rbp)
jne 0xd3e5
movq -0x10(%rbp), %rdi
callq 0xf240
testb $0x1, %al
jne 0xd393
jmp 0xd3e5
movq -0x10(%rbp), %rax
cmpl $0x0, 0xc(%rax)
jne 0xd3e5
movq -0x10(%rbp), %rax
cmpl $0x0, 0x8(%rax)
jne 0xd3e5
movq -0x10(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jne 0xd3e5
movq -0x10(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x4430
testb $0x1, %al
jne 0xd3e5
movq -0x10(%rbp), %rdi
movl $0x3, %esi
movl $0x1, %edx
callq 0x4430
testb $0x1, %al
jne 0xd3e5
movb $0x1, -0x1(%rbp)
jmp 0xd3fb
jmp 0xd3e7
jmp 0xd3e9
jmp 0xd3eb
jmp 0xd3ed
jmp 0xd3ef
jmp 0xd3f1
jmp 0xd3f3
jmp 0xd3f5
jmp 0xd3f7
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)