// File: /workspace/github_cpp_makefile_star2_O1/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 0x925e
movq %rsi, %r15
movq %rdi, %r14
movq %rsi, %rdi
callq 0x77b0
movl %eax, %ebp
movq %r15, %rdi
callq 0x77b7
movl %eax, %ebx
movq %r15, %rdi
callq 0x77c1
movl %eax, %r12d
movq %r15, %rdi
callq 0x77d5
movl %eax, %r13d
movl %ebx, %eax
orl %ebp, %eax
cmpl $0x3f, %eax
ja 0x925e
movl %ebx, 0xc(%rsp)
movl %ebp, %ebx
movq %r14, %rax
movl (%r14,%rbx,4), %r14d
movq %rax, 0x10(%rsp)
cmpl $0x1, 0x138(%rax)
jne 0x90cb
movl %r14d, %edi
callq 0xe823
jmp 0x90d3
movl %r14d, %edi
callq 0xe829
testb %al, %al
je 0x925e
movq 0x10(%rsp), %rax
movl 0x138(%rax), %eax
cmpl $0x1, %eax
jne 0x90f5
cmpl %r14d, %r12d
je 0x90fe
jmp 0x925e
addl %r12d, %r14d
jne 0x925e
cmpl $0x1, %r12d
jne 0x911f
movq 0x10(%rsp), %rdi
movq %r15, %rsi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x95cb
movl 0xc(%rsp), %r14d
movq 0x10(%rsp), %rcx
movl (%rcx,%r14,4), %edi
testl %r13d, %r13d
je 0x913e
cmpl $0x1, %eax
jne 0x9148
callq 0xe835
jmp 0x914d
testl %edi, %edi
jne 0x925e
jmp 0x9155
callq 0xe82f
testb %al, %al
jne 0x925e
addl $-0x2, %r12d
cmpl $0x4, %r12d
ja 0x925e
leaq 0x21b3a(%rip), %rax     # 0x2aca4
movslq (%rax,%r12,4), %rcx
addq %rax, %rcx
jmpq *%rcx
leaq 0xf1536(%rip), %rax     # 0xfa6b0
leaq 0xf132f(%rip), %rcx     # 0xfa4b0
movq (%rcx,%r14,8), %rcx
movb $0x1, %bpl
testq %rcx, (%rax,%rbx,8)
jne 0x9260
jmp 0x925e
leaq 0xf1712(%rip), %rax     # 0xfa8b0
leaq 0xf130b(%rip), %rcx     # 0xfa4b0
movq (%rcx,%r14,8), %rcx
movb $0x1, %bpl
testq %rcx, (%rax,%rbx,8)
jne 0x9260
movq %r15, %rdi
callq 0x77f3
testb %al, %al
je 0x925e
movl 0xc(%rsp), %eax
cmpl $0x39, %eax
jg 0x9271
cmpl $0x2, %eax
jne 0x9340
jmp 0x93a3
xorl %eax, %eax
movq 0x10(%rsp), %rdi
cmpl $0x1, 0x138(%rdi)
setne %al
movq 0x1a8(%rdi,%rax,8), %rdx
notq %rdx
movl %ebp, %esi
callq 0x677c
jmp 0x924e
xorl %eax, %eax
movq 0x10(%rsp), %rdi
cmpl $0x1, 0x138(%rdi)
setne %al
movq 0x1a8(%rdi,%rax,8), %rdx
notq %rdx
movl %ebp, %esi
callq 0x674a
jmp 0x924e
xorl %eax, %eax
movq 0x10(%rsp), %rdi
cmpl $0x1, 0x138(%rdi)
setne %al
movq 0x1a8(%rdi,%rax,8), %rdx
notq %rdx
movl %ebp, %esi
callq 0x665c
leaq 0xf125b(%rip), %rcx     # 0xfa4b0
movb $0x1, %bpl
testq %rax, (%rcx,%r14,8)
jne 0x9260
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x3a, %eax
je 0x92e3
cmpl $0x3e, 0xc(%rsp)
jne 0x925e
movq 0x10(%rsp), %rbx
movq %rbx, %rdi
callq 0xa966
testb %al, %al
je 0x92c6
cmpl $0x0, 0xf4(%rbx)
jne 0x92c6
cmpl $0x0, 0xf8(%rbx)
jne 0x92c6
movq %rbx, %rdi
movl $0x3c, %esi
xorl %edx, %edx
callq 0x392f
testb %al, %al
jne 0x92c6
movq %rbx, %rdi
movl $0x3d, %esi
xorl %edx, %edx
callq 0x392f
testb %al, %al
je 0x9260
cmpl $0x2, 0xc(%rsp)
je 0x93a3
cmpl $0x6, 0xc(%rsp)
je 0x934b
cmpl $0x3a, 0xc(%rsp)
jne 0x925e
movq 0x10(%rsp), %rbx
movq %rbx, %rdi
callq 0xa96f
testb %al, %al
je 0x9339
cmpl $0x0, 0xec(%rbx)
jne 0x9339
cmpl $0x0, 0xe8(%rbx)
jne 0x9339
cmpl $0x0, 0xe4(%rbx)
jne 0x9339
movq %rbx, %rdi
movl $0x3c, %esi
xorl %edx, %edx
callq 0x392f
testb %al, %al
jne 0x9339
movq %rbx, %rdi
movl $0x3b, %esi
xorl %edx, %edx
callq 0x392f
testb %al, %al
je 0x9260
cmpl $0x2, 0xc(%rsp)
je 0x93a3
cmpl $0x6, 0xc(%rsp)
jne 0x925e
movq 0x10(%rsp), %rbx
movq %rbx, %rdi
callq 0xa97a
testb %al, %al
je 0x9398
cmpl $0x0, 0x14(%rbx)
jne 0x9398
cmpl $0x0, 0x18(%rbx)
jne 0x9398
movq %rbx, %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x392f
testb %al, %al
jne 0x9398
movq %rbx, %rdi
movl $0x5, %esi
movl $0x1, %edx
callq 0x392f
testb %al, %al
je 0x9260
cmpl $0x2, 0xc(%rsp)
jne 0x925e
movq 0x10(%rsp), %rdi
callq 0xa986
testb %al, %al
je 0x925e
movq 0x10(%rsp), %rax
cmpl $0x0, 0xc(%rax)
jne 0x925e
movq 0x10(%rsp), %rax
cmpl $0x0, 0x8(%rax)
jne 0x925e
movq 0x10(%rsp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x925e
movq 0x10(%rsp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x392f
testb %al, %al
jne 0x925e
movq 0x10(%rsp), %rdi
movl $0x3, %esi
movl $0x1, %edx
callq 0x392f
testb %al, %al
jne 0x925e
jmp 0x9260