// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
testq %rsi, %rsi
je 0x937c
movq %rsi, %r15
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x7854
movl %eax, %ebp
movq %r15, %rdi
callq 0x785b
movl %eax, %r14d
movq %r15, %rdi
callq 0x7865
movl %eax, %r12d
movq %r15, %rdi
callq 0x7879
movl %eax, %r13d
movl %r14d, %eax
orl %ebp, %eax
cmpl $0x3f, %eax
ja 0x937c
movl %ebp, %ecx
movq %rbx, %rax
movq %rcx, 0x10(%rsp)
movl (%rbx,%rcx,4), %ebx
movq %rax, 0x8(%rsp)
cmpl $0x1, 0x138(%rax)
jne 0x9185
movl %ebx, %edi
callq 0xe769
jmp 0x918c
movl %ebx, %edi
callq 0xe76f
testb %al, %al
je 0x937c
movq 0x8(%rsp), %rax
movl 0x138(%rax), %eax
cmpl $0x1, %eax
jne 0x91ae
cmpl %ebx, %r12d
je 0x91b7
jmp 0x937c
addl %r12d, %ebx
jne 0x937c
cmpl $0x1, %r12d
jne 0x91d8
movq 0x8(%rsp), %rdi
movq %r15, %rsi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9679
movl %r14d, %ebx
movq 0x8(%rsp), %rcx
movl (%rcx,%rbx,4), %edi
testl %r13d, %r13d
je 0x91f4
cmpl $0x1, %eax
jne 0x91fe
callq 0xe77b
jmp 0x9203
testl %edi, %edi
jne 0x937c
jmp 0x920b
callq 0xe775
testb %al, %al
jne 0x937c
addl $-0x2, %r12d
cmpl $0x4, %r12d
ja 0x937c
leaq 0x21b04(%rip), %rax     # 0x2ad24
movslq (%rax,%r12,4), %rcx
addq %rax, %rcx
jmpq *%rcx
leaq 0xf1480(%rip), %rax     # 0xfa6b0
leaq 0xf1279(%rip), %rcx     # 0xfa4b0
movq (%rcx,%rbx,8), %rcx
movb $0x1, %bpl
movq 0x10(%rsp), %rdx
testq %rcx, (%rax,%rdx,8)
jne 0x937e
jmp 0x937c
leaq 0xf1657(%rip), %rax     # 0xfa8b0
leaq 0xf1250(%rip), %rcx     # 0xfa4b0
movq (%rcx,%rbx,8), %rcx
movb $0x1, %bpl
movq 0x10(%rsp), %rdx
testq %rcx, (%rax,%rdx,8)
jne 0x937e
movq %r15, %rdi
callq 0x7897
testb %al, %al
je 0x937c
cmpl $0x39, %r14d
jg 0x938f
cmpl $0x2, %r14d
je 0x93ed
cmpl $0x6, %r14d
jne 0x937c
movq 0x8(%rsp), %rdi
callq 0xa935
testb %al, %al
je 0x937c
movq 0x8(%rsp), %rax
cmpl $0x0, 0x14(%rax)
jne 0x937c
movq 0x8(%rsp), %rax
cmpl $0x0, 0x18(%rax)
jne 0x937c
movq 0x8(%rsp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x393b
testb %al, %al
jne 0x937c
movq 0x8(%rsp), %rdi
movl $0x5, %esi
jmp 0x944e
xorl %eax, %eax
movq 0x8(%rsp), %rdi
cmpl $0x1, 0x138(%rdi)
setne %al
movq 0x1a8(%rdi,%rax,8), %rdx
notq %rdx
movl %ebp, %esi
callq 0x6828
jmp 0x936c
xorl %eax, %eax
movq 0x8(%rsp), %rdi
cmpl $0x1, 0x138(%rdi)
setne %al
movq 0x1a8(%rdi,%rax,8), %rdx
notq %rdx
movl %ebp, %esi
callq 0x67f6
jmp 0x936c
xorl %eax, %eax
movq 0x8(%rsp), %rdi
cmpl $0x1, 0x138(%rdi)
setne %al
movq 0x1a8(%rdi,%rax,8), %rdx
notq %rdx
movl %ebp, %esi
callq 0x6708
leaq 0xf113d(%rip), %rcx     # 0xfa4b0
movb $0x1, %bpl
testq %rax, (%rcx,%rbx,8)
jne 0x937e
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x3a, %r14d
je 0x9455
cmpl $0x3e, %r14d
jne 0x937c
movq 0x8(%rsp), %rdi
callq 0xa921
testb %al, %al
je 0x937c
movq 0x8(%rsp), %rax
cmpl $0x0, 0xf4(%rax)
jne 0x937c
movq 0x8(%rsp), %rax
cmpl $0x0, 0xf8(%rax)
jne 0x937c
movq 0x8(%rsp), %rdi
movl $0x3c, %esi
xorl %edx, %edx
callq 0x393b
testb %al, %al
jne 0x937c
movq 0x8(%rsp), %rdi
movl $0x3d, %esi
jmp 0x94c0
movq 0x8(%rsp), %rdi
callq 0xa941
testb %al, %al
je 0x937c
movq 0x8(%rsp), %rax
cmpl $0x0, 0xc(%rax)
jne 0x937c
movq 0x8(%rsp), %rax
cmpl $0x0, 0x8(%rax)
jne 0x937c
movq 0x8(%rsp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x937c
movq 0x8(%rsp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x393b
testb %al, %al
jne 0x937c
movq 0x8(%rsp), %rdi
movl $0x3, %esi
movl $0x1, %edx
jmp 0x94c2
movq 0x8(%rsp), %rdi
callq 0xa92a
testb %al, %al
je 0x937c
movq 0x8(%rsp), %rax
cmpl $0x0, 0xec(%rax)
jne 0x937c
movq 0x8(%rsp), %rax
cmpl $0x0, 0xe8(%rax)
jne 0x937c
movq 0x8(%rsp), %rax
cmpl $0x0, 0xe4(%rax)
jne 0x937c
movq 0x8(%rsp), %rdi
movl $0x3c, %esi
xorl %edx, %edx
callq 0x393b
testb %al, %al
jne 0x937c
movq 0x8(%rsp), %rdi
movl $0x3b, %esi
xorl %edx, %edx
callq 0x393b
testb %al, %al
jne 0x937c
jmp 0x937e