Add Pseudo Move Generator #12
@@ -146,11 +146,11 @@ void push_move(struct Move *out, int *count, int from, int to, uint8_t piece, ui
|
|||||||
most complicated movement patterns and behaviors in the game. Separating out the logic should
|
most complicated movement patterns and behaviors in the game. Separating out the logic should
|
||||||
hopefully make debugging easier.
|
hopefully make debugging easier.
|
||||||
*/
|
*/
|
||||||
void gen_white_pawn_quiet_pushes(const struct Board *b, struct Move *out, int *count) {
|
void gen_white_pawn_quiet_pushes(const struct Board *board, struct Move *out, int *count) {
|
||||||
const uint64_t occ = b->occ[BOTH];
|
const uint64_t occ = board->occ[BOTH];
|
||||||
const uint64_t empty = ~occ;
|
const uint64_t empty = ~occ;
|
||||||
|
|
||||||
const uint64_t pawns = b->pieces[P];
|
const uint64_t pawns = board->pieces[P];
|
||||||
|
|
||||||
// One-step pushes: shift pawns up by 8 onto empty squares
|
// One-step pushes: shift pawns up by 8 onto empty squares
|
||||||
uint64_t one_step = (pawns << 8) & empty;
|
uint64_t one_step = (pawns << 8) & empty;
|
||||||
@@ -177,11 +177,11 @@ void gen_white_pawn_quiet_pushes(const struct Board *b, struct Move *out, int *c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_black_pawn_quiet_pushes(const struct Board *b, struct Move *out, int *count) {
|
void gen_black_pawn_quiet_pushes(const struct Board *board, struct Move *out, int *count) {
|
||||||
const uint64_t occ = b->occ[BOTH];
|
const uint64_t occ = board->occ[BOTH];
|
||||||
const uint64_t empty = ~occ;
|
const uint64_t empty = ~occ;
|
||||||
|
|
||||||
const uint64_t pawns = b->pieces[p];
|
const uint64_t pawns = board->pieces[p];
|
||||||
|
|
||||||
// One-step pushes: shift pawns down by 8 onto empty squares
|
// One-step pushes: shift pawns down by 8 onto empty squares
|
||||||
uint64_t one_step = (pawns >> 8) & empty;
|
uint64_t one_step = (pawns >> 8) & empty;
|
||||||
@@ -208,10 +208,10 @@ void gen_black_pawn_quiet_pushes(const struct Board *b, struct Move *out, int *c
|
|||||||
|
|
||||||
// We will only allow pawns to promote to queen. Technically, they should be allowed
|
// We will only allow pawns to promote to queen. Technically, they should be allowed
|
||||||
// to promote to any of the following: Rook, Bishop, Knight, Queen.
|
// to promote to any of the following: Rook, Bishop, Knight, Queen.
|
||||||
void gen_white_pawn_push_promotions(const struct Board *b, struct Move *out, int *count) {
|
void gen_white_pawn_push_promotions(const struct Board *board, struct Move *out, int *count) {
|
||||||
const uint64_t occ = b->occ[BOTH];
|
const uint64_t occ = board->occ[BOTH];
|
||||||
const uint64_t empty = ~occ;
|
const uint64_t empty = ~occ;
|
||||||
const uint64_t pawns = b->pieces[P];
|
const uint64_t pawns = board->pieces[P];
|
||||||
|
|
||||||
// destinations on rank 8 reachable by a single push
|
// destinations on rank 8 reachable by a single push
|
||||||
uint64_t promos = ((pawns << 8) & empty) & RANK_8;
|
uint64_t promos = ((pawns << 8) & empty) & RANK_8;
|
||||||
@@ -223,10 +223,10 @@ void gen_white_pawn_push_promotions(const struct Board *b, struct Move *out, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_black_pawn_push_promotions(const struct Board *b, struct Move *out, int *count) {
|
void gen_black_pawn_push_promotions(const struct Board *board, struct Move *out, int *count) {
|
||||||
const uint64_t occ = b->occ[BOTH];
|
const uint64_t occ = board->occ[BOTH];
|
||||||
const uint64_t empty = ~occ;
|
const uint64_t empty = ~occ;
|
||||||
const uint64_t pawns = b->pieces[p];
|
const uint64_t pawns = board->pieces[p];
|
||||||
|
|
||||||
// destinations on rank 1 reachable by a single push
|
// destinations on rank 1 reachable by a single push
|
||||||
uint64_t promos = ((pawns >> 8) & empty) & RANK_1;
|
uint64_t promos = ((pawns >> 8) & empty) & RANK_1;
|
||||||
@@ -238,17 +238,17 @@ void gen_black_pawn_push_promotions(const struct Board *b, struct Move *out, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_white_pawn_capture_promotions(const struct Board *b, struct Move *out, int *count) {
|
void gen_white_pawn_capture_promotions(const struct Board *board, struct Move *out, int *count) {
|
||||||
const uint64_t opp = b->occ[BLACK];
|
const uint64_t opp = board->occ[BLACK];
|
||||||
// left capture (from white view): +7, mask off file A
|
// left capture (from white view): +7, mask off file A
|
||||||
uint64_t left = ((b->pieces[P] & ~FILE_A) << 7) & opp & RANK_8;
|
uint64_t left = ((board->pieces[P] & ~FILE_A) << 7) & opp & RANK_8;
|
||||||
while (left) {
|
while (left) {
|
||||||
int to = pop_lsb_index(&left);
|
int to = pop_lsb_index(&left);
|
||||||
int from = to - 7;
|
int from = to - 7;
|
||||||
push_move(out, count,from, to, P, Q, MF_CAPTURE | MF_PROMO);
|
push_move(out, count,from, to, P, Q, MF_CAPTURE | MF_PROMO);
|
||||||
}
|
}
|
||||||
// right capture: +9, mask off file H
|
// right capture: +9, mask off file H
|
||||||
uint64_t right = ((b->pieces[P] & ~FILE_H) << 9) & opp & RANK_8;
|
uint64_t right = ((board->pieces[P] & ~FILE_H) << 9) & opp & RANK_8;
|
||||||
while (right) {
|
while (right) {
|
||||||
int to = pop_lsb_index(&right);
|
int to = pop_lsb_index(&right);
|
||||||
int from = to - 9;
|
int from = to - 9;
|
||||||
@@ -256,17 +256,17 @@ void gen_white_pawn_capture_promotions(const struct Board *b, struct Move *out,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_black_pawn_capture_promotions(const struct Board *b, struct Move *out, int *count) {
|
void gen_black_pawn_capture_promotions(const struct Board *board, struct Move *out, int *count) {
|
||||||
const uint64_t opp = b->occ[WHITE];
|
const uint64_t opp = board->occ[WHITE];
|
||||||
// from black view, “left” is -7 (mask off file H before shifting)
|
// from black view, “left” is -7 (mask off file H before shifting)
|
||||||
uint64_t left = ((b->pieces[p] & ~FILE_H) >> 7) & opp & RANK_1;
|
uint64_t left = ((board->pieces[p] & ~FILE_H) >> 7) & opp & RANK_1;
|
||||||
while (left) {
|
while (left) {
|
||||||
int to = pop_lsb_index(&left);
|
int to = pop_lsb_index(&left);
|
||||||
int from = to + 7;
|
int from = to + 7;
|
||||||
push_move(out, count,from, to, p, q, MF_CAPTURE | MF_PROMO);
|
push_move(out, count,from, to, p, q, MF_CAPTURE | MF_PROMO);
|
||||||
}
|
}
|
||||||
// “right” is -9 (mask off file A)
|
// “right” is -9 (mask off file A)
|
||||||
uint64_t right = ((b->pieces[p] & ~FILE_A) >> 9) & opp & RANK_1;
|
uint64_t right = ((board->pieces[p] & ~FILE_A) >> 9) & opp & RANK_1;
|
||||||
while (right) {
|
while (right) {
|
||||||
int to = pop_lsb_index(&right);
|
int to = pop_lsb_index(&right);
|
||||||
int from = to + 9;
|
int from = to + 9;
|
||||||
@@ -274,9 +274,9 @@ void gen_black_pawn_capture_promotions(const struct Board *b, struct Move *out,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_white_pawn_captures(const struct Board *b, struct Move *out, int *count) {
|
void gen_white_pawn_captures(const struct Board *board, struct Move *out, int *count) {
|
||||||
const uint64_t pawns = b->pieces[P];
|
const uint64_t pawns = board->pieces[P];
|
||||||
const uint64_t opp = b->occ[BLACK];
|
const uint64_t opp = board->occ[BLACK];
|
||||||
|
|
||||||
// Normal captures (exclude promotion rank)
|
// Normal captures (exclude promotion rank)
|
||||||
uint64_t left_caps = ((pawns & ~FILE_A) << 7) & opp & ~RANK_8;
|
uint64_t left_caps = ((pawns & ~FILE_A) << 7) & opp & ~RANK_8;
|
||||||
@@ -295,24 +295,24 @@ void gen_white_pawn_captures(const struct Board *b, struct Move *out, int *count
|
|||||||
}
|
}
|
||||||
|
|
||||||
// En passant (destination is ep_square)
|
// En passant (destination is ep_square)
|
||||||
if (b->ep_square >= 0) {
|
if (board->ep_square >= 0) {
|
||||||
uint64_t ep = 1ULL << b->ep_square;
|
uint64_t ep = 1ULL << board->ep_square;
|
||||||
|
|
||||||
// From-squares that can capture onto ep (reverse of +7/+9)
|
// From-squares that can capture onto ep (reverse of +7/+9)
|
||||||
uint64_t ep_from = (((ep & ~FILE_H) >> 7) | ((ep & ~FILE_A) >> 9)) & pawns;
|
uint64_t ep_from = (((ep & ~FILE_H) >> 7) | ((ep & ~FILE_A) >> 9)) & pawns;
|
||||||
|
|
||||||
while (ep_from) {
|
while (ep_from) {
|
||||||
int from = pop_lsb_index(&ep_from);
|
int from = pop_lsb_index(&ep_from);
|
||||||
int to = b->ep_square;
|
int to = board->ep_square;
|
||||||
// EP never promotes, so no promo piece; still a capture
|
// EP never promotes, so no promo piece; still a capture
|
||||||
push_move(out, count,from, to, P, 0, MF_CAPTURE | MF_ENPASSANT);
|
push_move(out, count,from, to, P, 0, MF_CAPTURE | MF_ENPASSANT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_black_pawn_captures(const struct Board *b, struct Move *out, int *count) {
|
void gen_black_pawn_captures(const struct Board *board, struct Move *out, int *count) {
|
||||||
const uint64_t pawns = b->pieces[p];
|
const uint64_t pawns = board->pieces[p];
|
||||||
const uint64_t opp = b->occ[WHITE];
|
const uint64_t opp = board->occ[WHITE];
|
||||||
|
|
||||||
// Normal captures (exclude promotion rank)
|
// Normal captures (exclude promotion rank)
|
||||||
uint64_t left_caps = ((pawns & ~FILE_H) >> 7) & opp & ~RANK_1; // from black POV, "left" is -7
|
uint64_t left_caps = ((pawns & ~FILE_H) >> 7) & opp & ~RANK_1; // from black POV, "left" is -7
|
||||||
@@ -330,15 +330,15 @@ void gen_black_pawn_captures(const struct Board *b, struct Move *out, int *count
|
|||||||
}
|
}
|
||||||
|
|
||||||
// En passant
|
// En passant
|
||||||
if (b->ep_square >= 0) {
|
if (board->ep_square >= 0) {
|
||||||
uint64_t ep = 1ULL << b->ep_square;
|
uint64_t ep = 1ULL << board->ep_square;
|
||||||
|
|
||||||
// From-squares that can capture onto ep (reverse of -7/-9)
|
// From-squares that can capture onto ep (reverse of -7/-9)
|
||||||
uint64_t ep_from = (((ep & ~FILE_A) << 7) | ((ep & ~FILE_H) << 9)) & pawns;
|
uint64_t ep_from = (((ep & ~FILE_A) << 7) | ((ep & ~FILE_H) << 9)) & pawns;
|
||||||
|
|
||||||
while (ep_from) {
|
while (ep_from) {
|
||||||
int from = pop_lsb_index(&ep_from);
|
int from = pop_lsb_index(&ep_from);
|
||||||
int to = b->ep_square;
|
int to = board->ep_square;
|
||||||
push_move(out, count,from, to, p, 0, MF_CAPTURE | MF_ENPASSANT);
|
push_move(out, count,from, to, p, 0, MF_CAPTURE | MF_ENPASSANT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,12 +351,12 @@ void gen_black_pawn_captures(const struct Board *b, struct Move *out, int *count
|
|||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void gen_knight_moves(const struct Board *b, struct Move *out, int *count, bool captures_only) {
|
void gen_knight_moves(const struct Board *board, struct Move *out, int *count, bool captures_only) {
|
||||||
enum Color side = b->side_to_move;
|
enum Color side = board->side_to_move;
|
||||||
uint64_t own = b->occ[side];
|
uint64_t own = board->occ[side];
|
||||||
uint64_t opp = b->occ[side ^ 1];
|
uint64_t opp = board->occ[side ^ 1];
|
||||||
uint8_t pid = (side == WHITE) ? N : n;
|
uint8_t pid = (side == WHITE) ? N : n;
|
||||||
uint64_t bb = (side == WHITE) ? b->pieces[N] : b->pieces[n];
|
uint64_t bb = (side == WHITE) ? board->pieces[N] : board->pieces[n];
|
||||||
|
|
||||||
while (bb) {
|
while (bb) {
|
||||||
int from = pop_lsb_index(&bb);
|
int from = pop_lsb_index(&bb);
|
||||||
@@ -404,13 +404,13 @@ void gen_bishop_moves(const struct Board *board, struct Move *out, int *count, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_rook_moves(const struct Board *b, struct Move *out, int *count, bool captures_only) {
|
void gen_rook_moves(const struct Board *board, struct Move *out, int *count, bool captures_only) {
|
||||||
enum Color side = b->side_to_move;
|
enum Color side = board->side_to_move;
|
||||||
uint64_t own = b->occ[side];
|
uint64_t own = board->occ[side];
|
||||||
uint64_t opp = b->occ[side ^ 1];
|
uint64_t opp = board->occ[side ^ 1];
|
||||||
uint64_t occ = b->occ[BOTH];
|
uint64_t occ = board->occ[BOTH];
|
||||||
uint8_t pid = (side == WHITE) ? R : r;
|
uint8_t pid = (side == WHITE) ? R : r;
|
||||||
uint64_t bb = (side == WHITE) ? b->pieces[R] : b->pieces[r];
|
uint64_t bb = (side == WHITE) ? board->pieces[R] : board->pieces[r];
|
||||||
|
|
||||||
while (bb) {
|
while (bb) {
|
||||||
int from = pop_lsb_index(&bb);
|
int from = pop_lsb_index(&bb);
|
||||||
@@ -431,13 +431,13 @@ void gen_rook_moves(const struct Board *b, struct Move *out, int *count, bool ca
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_queen_moves(const struct Board *b, struct Move *out, int *count, bool captures_only) {
|
void gen_queen_moves(const struct Board *board, struct Move *out, int *count, bool captures_only) {
|
||||||
enum Color side = b->side_to_move;
|
enum Color side = board->side_to_move;
|
||||||
uint64_t own = b->occ[side];
|
uint64_t own = board->occ[side];
|
||||||
uint64_t opp = b->occ[side ^ 1];
|
uint64_t opp = board->occ[side ^ 1];
|
||||||
uint64_t occ = b->occ[BOTH];
|
uint64_t occ = board->occ[BOTH];
|
||||||
uint8_t pid = (side == WHITE) ? Q : q;
|
uint8_t pid = (side == WHITE) ? Q : q;
|
||||||
uint64_t bb = (side == WHITE) ? b->pieces[Q] : b->pieces[q];
|
uint64_t bb = (side == WHITE) ? board->pieces[Q] : board->pieces[q];
|
||||||
|
|
||||||
while (bb) {
|
while (bb) {
|
||||||
int from = pop_lsb_index(&bb);
|
int from = pop_lsb_index(&bb);
|
||||||
@@ -458,12 +458,12 @@ void gen_queen_moves(const struct Board *b, struct Move *out, int *count, bool c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_king_moves(struct Board *b, struct Move *out, int *count, bool captures_only) {
|
void gen_king_moves(struct Board *board, struct Move *out, int *count, bool captures_only) {
|
||||||
enum Color side = b->side_to_move;
|
enum Color side = board->side_to_move;
|
||||||
uint64_t own = b->occ[side];
|
uint64_t own = board->occ[side];
|
||||||
uint64_t opp = b->occ[side ^ 1];
|
uint64_t opp = board->occ[side ^ 1];
|
||||||
uint8_t pid = (side == WHITE) ? K : k;
|
uint8_t pid = (side == WHITE) ? K : k;
|
||||||
uint64_t kk = (side == WHITE) ? b->pieces[K] : b->pieces[k];
|
uint64_t kk = (side == WHITE) ? board->pieces[K] : board->pieces[k];
|
||||||
|
|
||||||
if (!kk) return;
|
if (!kk) return;
|
||||||
int from = first_set_index(kk);
|
int from = first_set_index(kk);
|
||||||
@@ -483,26 +483,26 @@ void gen_king_moves(struct Board *b, struct Move *out, int *count, bool captures
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!captures_only) {
|
if (!captures_only) {
|
||||||
uint64_t occ = b->occ[BOTH];
|
uint64_t occ = board->occ[BOTH];
|
||||||
if (side == WHITE) {
|
if (side == WHITE) {
|
||||||
if ((b->castling_rights & CASTLE_WK) && !(occ & WK_EMPTY_MASK)) {
|
if ((board->castling_rights & CASTLE_WK) && !(occ & WK_EMPTY_MASK)) {
|
||||||
push_move(out, count,E1, WK_TO, K, 0, MF_CASTLE);
|
push_move(out, count,E1, WK_TO, K, 0, MF_CASTLE);
|
||||||
}
|
}
|
||||||
if ((b->castling_rights & CASTLE_WQ) && !(occ & WQ_EMPTY_MASK)) {
|
if ((board->castling_rights & CASTLE_WQ) && !(occ & WQ_EMPTY_MASK)) {
|
||||||
push_move(out, count,E1, WQ_TO, K, 0, MF_CASTLE);
|
push_move(out, count,E1, WQ_TO, K, 0, MF_CASTLE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((b->castling_rights & CASTLE_BK) && !(occ & BK_EMPTY_MASK)) {
|
if ((board->castling_rights & CASTLE_BK) && !(occ & BK_EMPTY_MASK)) {
|
||||||
push_move(out, count,E8, BK_TO, k, 0, MF_CASTLE);
|
push_move(out, count,E8, BK_TO, k, 0, MF_CASTLE);
|
||||||
}
|
}
|
||||||
if ((b->castling_rights & CASTLE_BQ) && !(occ & BQ_EMPTY_MASK)) {
|
if ((board->castling_rights & CASTLE_BQ) && !(occ & BQ_EMPTY_MASK)) {
|
||||||
push_move(out, count,E8, BQ_TO, k, 0, MF_CASTLE);
|
push_move(out, count,E8, BQ_TO, k, 0, MF_CASTLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_board(const struct Board *b) {
|
void print_board(const struct Board *board) {
|
||||||
const char PIECE_CH[12] = {
|
const char PIECE_CH[12] = {
|
||||||
'P','N','B','R','Q','K',
|
'P','N','B','R','Q','K',
|
||||||
'p','n','b','r','q','k'
|
'p','n','b','r','q','k'
|
||||||
@@ -512,7 +512,7 @@ void print_board(const struct Board *b) {
|
|||||||
for (int i = 0; i < 64; ++i) grid[i] = '.';
|
for (int i = 0; i < 64; ++i) grid[i] = '.';
|
||||||
|
|
||||||
for (int p = 0; p < 12; ++p) {
|
for (int p = 0; p < 12; ++p) {
|
||||||
uint64_t bb = b->pieces[p];
|
uint64_t bb = board->pieces[p];
|
||||||
while (bb) {
|
while (bb) {
|
||||||
int sq = pop_lsb_index(&bb);
|
int sq = pop_lsb_index(&bb);
|
||||||
grid[sq] = PIECE_CH[p];
|
grid[sq] = PIECE_CH[p];
|
||||||
|
|||||||
Reference in New Issue
Block a user