From 058f12c699c9183f93f280ad7eb54c8a1b25f523 Mon Sep 17 00:00:00 2001 From: Aargh Rai Date: Tue, 2 Jun 2026 17:39:09 +0530 Subject: added move flags will try stockfish later dw --- src/engine/bitboard.c | 20 ---------- src/engine/bitboard.h | 26 +++++++++--- src/engine/moves.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++ src/engine/moves.h | 35 +++++++++++++++- src/engine/moves/bishop.c | 22 +++++----- src/engine/moves/king.c | 10 ++++- src/engine/moves/knight.c | 11 ++++- src/engine/moves/pawn.c | 50 ++++++++++++----------- src/engine/moves/rook.c | 21 ++++++---- src/engine/moves/vec.c | 17 ++++---- 10 files changed, 234 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/engine/bitboard.c b/src/engine/bitboard.c index 80cdb78..565f425 100644 --- a/src/engine/bitboard.c +++ b/src/engine/bitboard.c @@ -47,26 +47,6 @@ bool check_valid_position(position_t position) { return true; } -bitboard_t whites(position_t position) { - return - position.bitboards[WHITE_KING] | - position.bitboards[WHITE_QUEEN] | - position.bitboards[WHITE_ROOK] | - position.bitboards[WHITE_BISHOP] | - position.bitboards[WHITE_KNIGHT] | - position.bitboards[WHITE_PAWN]; -} - -bitboard_t blacks(position_t position) { - return - position.bitboards[BLACK_KING] | - position.bitboards[BLACK_QUEEN] | - position.bitboards[BLACK_ROOK] | - position.bitboards[BLACK_BISHOP] | - position.bitboards[BLACK_KNIGHT] | - position.bitboards[BLACK_PAWN]; -} - void print_bitboard(bitboard_t bitboard) { printf("Bitboard(%" PRIu64 ")\n", bitboard); for (int i = 7; i >= 0; i--) { diff --git a/src/engine/bitboard.h b/src/engine/bitboard.h index 8515f5d..ecd8c35 100644 --- a/src/engine/bitboard.h +++ b/src/engine/bitboard.h @@ -23,10 +23,10 @@ enum { }; enum { - WHITE_SHORT_CASTLE = 1 << 0, - WHITE_LONG_CASTLE = 1 << 1, - BLACK_SHORT_CASTLE = 1 << 2, - BLACK_LONG_CASTLE = 1 << 3, + WHITE_SHORT_CASTLE = 1 << 0, + WHITE_LONG_CASTLE = 1 << 1, + BLACK_SHORT_CASTLE = 1 << 2, + BLACK_LONG_CASTLE = 1 << 3, }; enum { @@ -65,8 +65,22 @@ typedef struct { position_t position_starting(); void assert_valid_position(position_t position); bool check_valid_position(position_t position); -bitboard_t whites(position_t position); -bitboard_t blacks(position_t position); +#define whites(position) \ + position.bitboards[WHITE_KING] | \ + position.bitboards[WHITE_QUEEN] | \ + position.bitboards[WHITE_ROOK] | \ + position.bitboards[WHITE_BISHOP] | \ + position.bitboards[WHITE_KNIGHT] | \ + position.bitboards[WHITE_PAWN] + +#define blacks(position) \ + position.bitboards[BLACK_KING] | \ + position.bitboards[BLACK_QUEEN] | \ + position.bitboards[BLACK_ROOK] | \ + position.bitboards[BLACK_BISHOP] | \ + position.bitboards[BLACK_KNIGHT] | \ + position.bitboards[BLACK_PAWN] + void print_bitboard(bitboard_t bitboard); diff --git a/src/engine/moves.c b/src/engine/moves.c index ac9fbba..d338cc2 100644 --- a/src/engine/moves.c +++ b/src/engine/moves.c @@ -1,3 +1,5 @@ +#include "moves.h" +#include "bitboard.h" #include "moves/vec.c" #include "moves/king.c" #include "moves/knight.c" @@ -5,6 +7,7 @@ #include "moves/rook.c" #include "moves/bishop.c" #include "moves/queen.c" +#include void get_moves(moves_t* moves, position_t position) { get_pawn_moves(moves, position); @@ -14,3 +17,100 @@ void get_moves(moves_t* moves, position_t position) { get_bishop_moves(moves, position); get_queen_moves(moves, position); } + +int find_piece_on_square(position_t* p, int square) { + if ((p->bitboards[WHITE_KING] >> square) & 1) return WHITE_KING; + if ((p->bitboards[WHITE_QUEEN] >> square) & 1) return WHITE_QUEEN; + if ((p->bitboards[WHITE_ROOK] >> square) & 1) return WHITE_ROOK; + if ((p->bitboards[WHITE_BISHOP] >> square) & 1) return WHITE_BISHOP; + if ((p->bitboards[WHITE_KNIGHT] >> square) & 1) return WHITE_KNIGHT; + if ((p->bitboards[WHITE_PAWN] >> square) & 1) return WHITE_PAWN; + if ((p->bitboards[BLACK_KING] >> square) & 1) return BLACK_KING; + if ((p->bitboards[BLACK_QUEEN] >> square) & 1) return BLACK_QUEEN; + if ((p->bitboards[BLACK_ROOK] >> square) & 1) return BLACK_ROOK; + if ((p->bitboards[BLACK_BISHOP] >> square) & 1) return BLACK_BISHOP; + if ((p->bitboards[BLACK_KNIGHT] >> square) & 1) return BLACK_KNIGHT; + if ((p->bitboards[BLACK_PAWN] >> square) & 1) return BLACK_PAWN; + assert(0); +} + +void position_make_move(position_t* position, move_t* move) { + if (move->flags & MOVE_LONG_CASTLE) { + if (position->turn == WHITE_TURN) { + assert(position->bitboards[WHITE_KING] == 16); + assert((position->bitboards[WHITE_ROOK] >> 0) & 1); + + position->bitboards[WHITE_KING] = 2; + position->bitboards[WHITE_ROOK] += 3; + } else if (position->turn == BLACK_TURN) { + assert(position->bitboards[BLACK_KING] == 1152921504606846976ULL); + assert((position->bitboards[BLACK_ROOK] >> 56) & 1); + + position->bitboards[BLACK_KING] = 144115188075855872ULL; + position->bitboards[WHITE_ROOK] &= ~((bitboard_t)1 << 56); + position->bitboards[WHITE_ROOK] |= (bitboard_t)1 << 58; + } + return; + } + if (move->flags & MOVE_SHORT_CASTLE) { + if (position->turn == WHITE_TURN) { + assert(position->bitboards[WHITE_KING] == 16); + assert((position->bitboards[WHITE_ROOK] >> 7) & 1); + + position->bitboards[WHITE_KING] = 64; + position->bitboards[WHITE_ROOK] &= ~((bitboard_t)1 << 7); + position->bitboards[WHITE_ROOK] |= (bitboard_t)1 << 5; + } else if (position->turn == BLACK_TURN) { + assert(position->bitboards[BLACK_KING] == 1152921504606846976ULL); + assert((position->bitboards[BLACK_ROOK] >> 63) & 1); + + position->bitboards[WHITE_KING] = 4611686018427387904ULL; + position->bitboards[WHITE_ROOK] &= ~((bitboard_t)1 << 63); + position->bitboards[WHITE_ROOK] |= (bitboard_t)1 << 61; + } + return; + } + + int piece_type = find_piece_on_square(position, move->from); + position->bitboards[piece_type] &= ~(1 << move->from); + if (move->flags & MOVE_PROMOTE_Q) { + int q_type = position->turn == WHITE_TURN ? WHITE_QUEEN : BLACK_QUEEN; + position->bitboards[q_type] |= 1 << move->to; + return; + } + if (move->flags & MOVE_PROMOTE_R) { + int q_type = position->turn == WHITE_TURN ? WHITE_ROOK : BLACK_ROOK; + position->bitboards[q_type] |= 1 << move->to; + return; + } + if (move->flags & MOVE_PROMOTE_B) { + int q_type = position->turn == WHITE_TURN ? WHITE_BISHOP : BLACK_BISHOP; + position->bitboards[q_type] |= 1 << move->to; + return; + } + if (move->flags & MOVE_PROMOTE_N) { + int q_type = position->turn == WHITE_TURN ? WHITE_KNIGHT : BLACK_KNIGHT; + position->bitboards[q_type] |= 1 << move->to; + return; + } + if (move->flags & MOVE_EN_PASSANT) { + int target_sqr; + if (position->turn == WHITE_TURN) target_sqr = move->to - 8; + else target_sqr = move->to + 8; + + int to_remove_piece_type = find_piece_on_square(position, target_sqr); + position->bitboards[piece_type] |= 1 << move->to; + position->bitboards[to_remove_piece_type] &= ~(1 << target_sqr); + return; + } + + if (move->flags & MOVE_CAPTURE) { + int to_remove_piece_type = find_piece_on_square(position, move->to); + position->bitboards[to_remove_piece_type] &= ~(1 << move->to); + } + + // i can't put this above the find_piece_on_square function, because there + // is a possibility that piece_type would resolve to the piece that is being + // moved, which would mess with the ~(1 << to_sqr) + position->bitboards[piece_type] |= 1 << move->to; +} diff --git a/src/engine/moves.h b/src/engine/moves.h index b63b9e2..bd88eeb 100644 --- a/src/engine/moves.h +++ b/src/engine/moves.h @@ -6,9 +6,27 @@ typedef u8 square_t; +// think about the chess move notation +// e4, Nf6, Qh3+, Qe1#, a8=Q, i need to store the information needed to +// recreate this in move_t +enum { + MOVE_CAPTURE = 1, + MOVE_SHORT_CASTLE = 1 << 1, + MOVE_LONG_CASTLE = 1 << 2, + + // technically these promotation flags can be compressed to only use 2 bits.. + MOVE_PROMOTE_Q = 1 << 3, // 1 << 5 + MOVE_PROMOTE_R = 1 << 4, // 2 << 5 + MOVE_PROMOTE_B = 1 << 5, // 3 << 5 + MOVE_PROMOTE_N = 1 << 6, // 4 << 5 ? nvm it uses 3 + MOVE_EN_PASSANT = 1 << 7, + MOVE_CHECK = 1 << 8, +}; + typedef struct { square_t from; square_t to; + u16 flags; } move_t; void position_make_move(position_t* position, move_t* move); @@ -21,7 +39,22 @@ typedef struct { moves_t moves_init(); moves_t moves_init_wcapacity(u32 capacity); moves_t moves_empty(); -void add_move(moves_t* moves, square_t from, square_t to); + +struct add_move_params { + u16 flags; +}; +#define add_move(moves, from, to, ...) _add_move(\ + moves, \ + from, \ + to, \ + (struct add_move_params) { .flags = 0, __VA_ARGS__ }\ +) +void _add_move( + moves_t* moves, + square_t from, + square_t to, + struct add_move_params params +); void get_pawn_moves(moves_t* moves, position_t position); void get_knight_moves(moves_t* moves, position_t position); diff --git a/src/engine/moves/bishop.c b/src/engine/moves/bishop.c index 52b90b3..c51d405 100644 --- a/src/engine/moves/bishop.c +++ b/src/engine/moves/bishop.c @@ -14,10 +14,11 @@ void __forloop_bishop_moves_gen( int og_file = from % 8; // range: [0, 7] int rank = og_rank + 1, file = og_file + 1, index = rank * 8 + file; - + bitboard_t occupied; while ((rank < 8 && file < 8) && !occupied_by(friendly_pieces, index)) { - add_move(moves, from, index); - if (occupied_by(enemy_pieces, index)) { + occupied = occupied_by(enemy_pieces, index); + add_move(moves, from, index, .flags = occupied ? MOVE_CAPTURE : 0); + if (occupied) { break; } index = ++rank * 8 + ++file; @@ -25,8 +26,9 @@ void __forloop_bishop_moves_gen( rank = og_rank - 1, file = og_file - 1, index = rank * 8 + file; while ((rank >= 0 && file >= 0) && !occupied_by(friendly_pieces, index)) { - add_move(moves, from, index); - if (occupied_by(enemy_pieces, index)) { + occupied = occupied_by(enemy_pieces, index); + add_move(moves, from, index, .flags = occupied ? MOVE_CAPTURE : 0); + if (occupied) { break; } index = --rank * 8 + --file; @@ -34,8 +36,9 @@ void __forloop_bishop_moves_gen( rank = og_rank - 1, file = og_file + 1, index = rank * 8 + file; while ((rank >= 0 && file < 8) && !occupied_by(friendly_pieces, index)) { - add_move(moves, from, index); - if (occupied_by(enemy_pieces, index)) { + occupied = occupied_by(enemy_pieces, index); + add_move(moves, from, index, .flags = occupied ? MOVE_CAPTURE : 0); + if (occupied) { break; } index = --rank * 8 + ++file; @@ -43,8 +46,9 @@ void __forloop_bishop_moves_gen( rank = og_rank + 1, file = og_file - 1, index = rank * 8 + file; while ((rank < 8 && file >= 0) && !occupied_by(friendly_pieces, index)) { - add_move(moves, from, index); - if (occupied_by(enemy_pieces, index)) { + occupied = occupied_by(enemy_pieces, index); + add_move(moves, from, index, .flags = occupied ? MOVE_CAPTURE : 0); + if (occupied) { break; } index = ++rank * 8 + --file; diff --git a/src/engine/moves/king.c b/src/engine/moves/king.c index 29bca79..e954ae5 100644 --- a/src/engine/moves/king.c +++ b/src/engine/moves/king.c @@ -7,11 +7,14 @@ void get_king_moves(moves_t* moves, position_t position) { bitboard_t friendly_king; int king_square; bitboard_t friendly_pieces; + bitboard_t enemy_pieces; if (position.turn == WHITE_TURN) { friendly_pieces = whites(position); + enemy_pieces = blacks(position); friendly_king = position.bitboards[WHITE_KING]; } else { friendly_pieces = blacks(position); + enemy_pieces = whites(position); friendly_king = position.bitboards[BLACK_KING]; } king_square = __builtin_ctzll(friendly_king); @@ -32,7 +35,12 @@ void get_king_moves(moves_t* moves, position_t position) { while (movement) { int to = __builtin_ctzll(movement); movement &= movement - 1; - add_move(moves, king_square, to); + add_move( + moves, + king_square, + to, + .flags = ((enemy_pieces >> to) & 1) ? MOVE_CAPTURE : 0, + ); } } diff --git a/src/engine/moves/knight.c b/src/engine/moves/knight.c index 5f5f9ad..20d072f 100644 --- a/src/engine/moves/knight.c +++ b/src/engine/moves/knight.c @@ -79,11 +79,14 @@ void get_knight_moves(moves_t* moves, position_t position) { bitboard_t friendly_knights; bitboard_t friendly_pieces; + bitboard_t enemy_pieces; if (position.turn == WHITE_TURN) { friendly_pieces = whites(position); + enemy_pieces = blacks(position); friendly_knights = position.bitboards[WHITE_KNIGHT]; } else { friendly_pieces = blacks(position); + enemy_pieces = whites(position); friendly_knights = position.bitboards[BLACK_KNIGHT]; } @@ -95,7 +98,13 @@ void get_knight_moves(moves_t* moves, position_t position) { while (ATTACK_MASK) { int to = __builtin_ctzll(ATTACK_MASK); ATTACK_MASK &= ATTACK_MASK - 1; - add_move(moves, from, to); + int capture = 0; + add_move( + moves, + from, + to, + .flags = ((enemy_pieces >> to) & 1) ? MOVE_CAPTURE : 0, + ); } } } diff --git a/src/engine/moves/pawn.c b/src/engine/moves/pawn.c index 3cd28b8..0b8993f 100644 --- a/src/engine/moves/pawn.c +++ b/src/engine/moves/pawn.c @@ -1,14 +1,14 @@ #include "../moves.h" +#define add_promote_moves(other_flags) \ + add_move(moves, from, to, .flags = other_flags | MOVE_PROMOTE_Q); \ + add_move(moves, from, to, .flags = other_flags | MOVE_PROMOTE_R); \ + add_move(moves, from, to, .flags = other_flags | MOVE_PROMOTE_B); \ + add_move(moves, from, to, .flags = other_flags | MOVE_PROMOTE_N) + bitboard_t get_white_pawn_forwardmoves(moves_t* moves, position_t position) { bitboard_t enemy_bitboard = blacks(position); - bitboard_t friendly_pieces = - position.bitboards[WHITE_KING] | - position.bitboards[WHITE_QUEEN] | - position.bitboards[WHITE_ROOK] | - position.bitboards[WHITE_BISHOP] | - position.bitboards[WHITE_KNIGHT] | - position.bitboards[WHITE_PAWN]; + bitboard_t friendly_pieces = whites(position); bitboard_t friendly_pawns = position.bitboards[WHITE_PAWN]; bitboard_t y = friendly_pieces | enemy_bitboard; bitboard_t x = ~((friendly_pawns << 8) & y) & (friendly_pawns << 8); @@ -21,13 +21,7 @@ bitboard_t get_white_pawn_forwardmoves(moves_t* moves, position_t position) { } bitboard_t get_black_pawn_forwardmoves(moves_t* moves, position_t position) { bitboard_t enemy_bitboard = whites(position); - bitboard_t friendly_pieces = - position.bitboards[BLACK_KING] | - position.bitboards[BLACK_QUEEN] | - position.bitboards[BLACK_ROOK] | - position.bitboards[BLACK_BISHOP] | - position.bitboards[BLACK_KNIGHT] | - position.bitboards[BLACK_PAWN]; + bitboard_t friendly_pieces = blacks(position); bitboard_t friendly_pawns = position.bitboards[BLACK_PAWN]; bitboard_t y = friendly_pieces | enemy_bitboard; bitboard_t x = ~((friendly_pawns >> 8) & y) & (friendly_pawns >> 8); @@ -84,7 +78,9 @@ void get_pawn_moves(moves_t* moves, position_t position) { if (pawns == 0) next_from = 64; } item &= (item - 1); - add_move(moves, from, to); + if (to >= 56 || to <= 7) { + add_promote_moves(0); + } else add_move(moves, from, to); } } @@ -108,20 +104,24 @@ void get_pawn_moves(moves_t* moves, position_t position) { if (left != 0) { bitboard_t MASK = file_masks[left - 1] & friendly_pawns & PASSANT_RANK; if (MASK != 0) { - add_move( - moves, - left + rank_shift + from_shift, - position.passantable_file + rank_shift - 1 + int from = left + rank_shift + from_shift; + int to = position.passantable_file + rank_shift - 1; + if (to >= 56 || to <= 7) { + add_promote_moves(MOVE_EN_PASSANT | MOVE_CAPTURE); + } else add_move( + moves, from, to, .flags = MOVE_EN_PASSANT | MOVE_CAPTURE ); } } if (right != 0) { bitboard_t MASK = file_masks[right - 1] & friendly_pawns & PASSANT_RANK; if (MASK != 0) { - add_move( - moves, - right + rank_shift + from_shift, - position.passantable_file + rank_shift - 1 + int from = right + rank_shift + from_shift; + int to = position.passantable_file + rank_shift - 1; + if (to >= 56 || to <= 7) { + add_promote_moves(MOVE_EN_PASSANT | MOVE_CAPTURE); + } else add_move( + moves, from, to, .flags = MOVE_EN_PASSANT | MOVE_CAPTURE ); } } @@ -157,7 +157,9 @@ void get_pawn_moves(moves_t* moves, position_t position) { while (MASK) { int to = __builtin_ctzll(MASK); MASK &= MASK - 1; - add_move(moves, from, to); + if (to >= 56 || to <= 7) { + add_promote_moves(MOVE_CAPTURE); + } else add_move(moves, from, to, .flags = MOVE_CAPTURE); } } } diff --git a/src/engine/moves/rook.c b/src/engine/moves/rook.c index c5867d5..dfd9c32 100644 --- a/src/engine/moves/rook.c +++ b/src/engine/moves/rook.c @@ -15,9 +15,11 @@ void __forloop_rook_moves_gen( int rank = og_rank + 1, file = og_file, index = rank * 8 + file; + bitboard_t occupied; while (rank < 8 && !occupied_by(friendly_pieces, index)) { - add_move(moves, from, index); - if (occupied_by(enemy_pieces, index)) { + occupied = occupied_by(enemy_pieces, index); + add_move(moves, from, index, .flags = occupied ? MOVE_CAPTURE : 0); + if (occupied) { break; } index = ++rank * 8 + file; @@ -25,8 +27,9 @@ void __forloop_rook_moves_gen( rank = og_rank - 1, file = og_file, index = rank * 8 + file; while (rank >= 0 && !occupied_by(friendly_pieces, index)) { - add_move(moves, from, index); - if (occupied_by(enemy_pieces, index)) { + occupied = occupied_by(enemy_pieces, index); + add_move(moves, from, index, .flags = occupied ? MOVE_CAPTURE : 0); + if (occupied) { break; } index = --rank * 8 + file; @@ -34,8 +37,9 @@ void __forloop_rook_moves_gen( rank = og_rank, file = og_file + 1, index = rank * 8 + file; while (file < 8 && !occupied_by(friendly_pieces, index)) { - add_move(moves, from, index); - if (occupied_by(enemy_pieces, index)) { + occupied = occupied_by(enemy_pieces, index); + add_move(moves, from, index, .flags = occupied ? MOVE_CAPTURE : 0); + if (occupied) { break; } index = rank * 8 + ++file; @@ -43,8 +47,9 @@ void __forloop_rook_moves_gen( rank = og_rank, file = og_file - 1, index = rank * 8 + file; while (file >= 0 && !occupied_by(friendly_pieces, index)) { - add_move(moves, from, index); - if (occupied_by(enemy_pieces, index)) { + occupied = occupied_by(enemy_pieces, index); + add_move(moves, from, index, .flags = occupied ? MOVE_CAPTURE : 0); + if (occupied) { break; } index = rank * 8 + --file; diff --git a/src/engine/moves/vec.c b/src/engine/moves/vec.c index 6192706..6a5f3c6 100644 --- a/src/engine/moves/vec.c +++ b/src/engine/moves/vec.c @@ -2,10 +2,6 @@ #include #include -void position_make_move(position_t* position, move_t* move) { - -} - moves_t moves_init() { return moves_init_wcapacity(16); } @@ -32,7 +28,12 @@ int min(int a, int b) { return a; } -void add_move(moves_t* moves, square_t from, square_t to) { +void _add_move( + moves_t* moves, + square_t from, + square_t to, + struct add_move_params params +) { assert(moves->moves != 0); assert(from != to); @@ -43,9 +44,9 @@ void add_move(moves_t* moves, square_t from, square_t to) { moves->capacity * sizeof(*moves->moves) ); } - moves->moves[moves->length] = (move_t){ + moves->moves[moves->length++] = (move_t) { .from = from, - .to = to + .to = to, + .flags = params.flags, }; - moves->length++; } -- cgit v1.2.3