// File: /workspace/github_cpp_makefile_star2_O2/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 0x8c4e
movq %rsi, %r15
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x736b
movl %eax, %ebp
movq %r15, %rdi
callq 0x7372
movl %eax, %r14d
movq %r15, %rdi
callq 0x737c
movl %eax, %r12d
movq %r15, %rdi
callq 0x7390
movl %eax, %r13d
movl %r14d, %eax
orl %ebp, %eax
cmpl $0x3f, %eax
ja 0x8c4e
movl %ebp, %ecx
movq %rbx, %rax
movq %rcx, 0x10(%rsp)
movl (%rbx,%rcx,4), %ebx
movq %rax, 0x8(%rsp)
cmpl $0x1, 0x138(%rax)
jne 0x8a54
movl %ebx, %edi
callq 0xdba0
jmp 0x8a5b
movl %ebx, %edi
callq 0xdba6
testb %al, %al
je 0x8c4e
movq 0x8(%rsp), %rax
movl 0x138(%rax), %eax
cmpl $0x1, %eax
jne 0x8a7d
cmpl %ebx, %r12d
je 0x8a86
jmp 0x8c4e
addl %r12d, %ebx
jne 0x8c4e
cmpl $0x1, %r12d
jne 0x8aa7
movq 0x8(%rsp), %rdi
movq %r15, %rsi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x8f07
movl %r14d, %ebx
movq 0x8(%rsp), %rcx
movl (%rcx,%rbx,4), %edi
testl %r13d, %r13d
je 0x8ac3
cmpl $0x1, %eax
jne 0x8acd
callq 0xdbb2
jmp 0x8ad2
testl %edi, %edi
jne 0x8c4e
jmp 0x8ada
callq 0xdbac
testb %al, %al
jne 0x8c4e
addl $-0x2, %r12d
cmpl $0x4, %r12d
ja 0x8c4e
leaq 0x201e5(%rip), %rax     # 0x28cd4
movslq (%rax,%r12,4), %rcx
addq %rax, %rcx
jmpq *%rcx
leaq 0xf4bb1(%rip), %rax     # 0xfd6b0
leaq 0xf49aa(%rip), %rcx     # 0xfd4b0
movq (%rcx,%rbx,8), %rcx
movb $0x1, %bpl
movq 0x10(%rsp), %rdx
testq %rcx, (%rax,%rdx,8)
jne 0x8c50
jmp 0x8c4e
leaq 0xf4d88(%rip), %rax     # 0xfd8b0
leaq 0xf4981(%rip), %rcx     # 0xfd4b0
movq (%rcx,%rbx,8), %rcx
movb $0x1, %bpl
movq 0x10(%rsp), %rdx
testq %rcx, (%rax,%rdx,8)
jne 0x8c50
movq %r15, %rdi
callq 0x73ae
testb %al, %al
je 0x8c4e
cmpl $0x2, %r14d
je 0x8cff
cmpl $0x6, %r14d
je 0x8c61
cmpl $0x3a, %r14d
je 0x8ca0
cmpl $0x3e, %r14d
jne 0x8c4e
movq 0x8(%rsp), %rdi
callq 0xa0ba
testb %al, %al
je 0x8c4e
movq 0x8(%rsp), %rax
cmpl $0x0, 0xf4(%rax)
jne 0x8c4e
movq 0x8(%rsp), %rax
cmpl $0x0, 0xf8(%rax)
jne 0x8c4e
pushq $0x3c
popq %rsi
movq 0x8(%rsp), %rdi
xorl %edx, %edx
callq 0x3791
testb %al, %al
jne 0x8c4e
pushq $0x3d
jmp 0x8cf5
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 0x63e8
jmp 0x8c3e
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 0x63b6
jmp 0x8c3e
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 0x62e4
leaq 0xf486b(%rip), %rcx     # 0xfd4b0
movb $0x1, %bpl
testq %rax, (%rcx,%rbx,8)
jne 0x8c50
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%rsp), %rdi
callq 0xa0ce
testb %al, %al
je 0x8c4e
movq 0x8(%rsp), %rax
cmpl $0x0, 0x14(%rax)
jne 0x8c4e
movq 0x8(%rsp), %rax
cmpl $0x0, 0x18(%rax)
jne 0x8c4e
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq 0x8(%rsp), %rdi
callq 0x3791
testb %al, %al
jne 0x8c4e
pushq $0x5
jmp 0x8d58
movq 0x8(%rsp), %rdi
callq 0xa0c3
testb %al, %al
je 0x8c4e
movq 0x8(%rsp), %rax
cmpl $0x0, 0xec(%rax)
jne 0x8c4e
movq 0x8(%rsp), %rax
cmpl $0x0, 0xe8(%rax)
jne 0x8c4e
movq 0x8(%rsp), %rax
cmpl $0x0, 0xe4(%rax)
jne 0x8c4e
pushq $0x3c
popq %rsi
movq 0x8(%rsp), %rdi
xorl %edx, %edx
callq 0x3791
testb %al, %al
jne 0x8c4e
pushq $0x3b
popq %rsi
movq 0x8(%rsp), %rdi
xorl %edx, %edx
jmp 0x8d61
movq 0x8(%rsp), %rdi
callq 0xa0da
testb %al, %al
je 0x8c4e
movq 0x8(%rsp), %rax
cmpl $0x0, 0xc(%rax)
jne 0x8c4e
movq 0x8(%rsp), %rax
cmpl $0x0, 0x8(%rax)
jne 0x8c4e
movq 0x8(%rsp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x8c4e
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq 0x8(%rsp), %rdi
callq 0x3791
testb %al, %al
jne 0x8c4e
pushq $0x3
popq %rsi
pushq $0x1
popq %rdx
movq 0x8(%rsp), %rdi
callq 0x3791
testb %al, %al
jne 0x8c4e
jmp 0x8c50