From 2c2a70b69869f149c0407a62f1bf4c39899027a7 Mon Sep 17 00:00:00 2001 From: Aargh Rai Date: Wed, 27 May 2026 18:02:44 +0530 Subject: restructing --- src/engine/moves/bishop.c | 77 ++++++++++++++++++++++ src/engine/moves/king.c | 53 +++++++++++++++ src/engine/moves/knight.c | 101 ++++++++++++++++++++++++++++ src/engine/moves/pawn.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++ src/engine/moves/queen.c | 31 +++++++++ src/engine/moves/rook.c | 77 ++++++++++++++++++++++ src/engine/moves/vec.c | 51 ++++++++++++++ 7 files changed, 554 insertions(+) create mode 100644 src/engine/moves/bishop.c create mode 100644 src/engine/moves/king.c create mode 100644 src/engine/moves/knight.c create mode 100644 src/engine/moves/pawn.c create mode 100644 src/engine/moves/queen.c create mode 100644 src/engine/moves/rook.c create mode 100644 src/engine/moves/vec.c (limited to 'src/engine/moves') diff --git a/src/engine/moves/bishop.c b/src/engine/moves/bishop.c new file mode 100644 index 0000000..52b90b3 --- /dev/null +++ b/src/engine/moves/bishop.c @@ -0,0 +1,77 @@ +#include "../moves.h" + +void __forloop_bishop_moves_gen( + moves_t* moves, + bitboard_t friendly_type, + bitboard_t friendly_pieces, + bitboard_t enemy_pieces +) { + while (friendly_type) { + int from = __builtin_ctzll(friendly_type); + friendly_type &= friendly_type - 1; + + int og_rank = from / 8; // range: [0, 7] + int og_file = from % 8; // range: [0, 7] + int rank = og_rank + 1, file = og_file + 1, index = rank * 8 + file; + + + while ((rank < 8 && file < 8) && !occupied_by(friendly_pieces, index)) { + add_move(moves, from, index); + if (occupied_by(enemy_pieces, index)) { + break; + } + index = ++rank * 8 + ++file; + } + + 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)) { + break; + } + index = --rank * 8 + --file; + } + + 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)) { + break; + } + index = --rank * 8 + ++file; + } + + 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)) { + break; + } + index = ++rank * 8 + --file; + } + } +} + +void get_bishop_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t friendly_bishops; + bitboard_t friendly_pieces; + bitboard_t enemy_pieces; + if (position.turn == WHITE_TURN) { + friendly_pieces = whites(position); + enemy_pieces = blacks(position); + friendly_bishops = position.bitboards[WHITE_BISHOP]; + } else { + friendly_pieces = blacks(position); + enemy_pieces = whites(position); + friendly_bishops = position.bitboards[BLACK_BISHOP]; + } + + __forloop_bishop_moves_gen( + moves, + friendly_bishops, + friendly_pieces, + enemy_pieces + ); +} diff --git a/src/engine/moves/king.c b/src/engine/moves/king.c new file mode 100644 index 0000000..0637109 --- /dev/null +++ b/src/engine/moves/king.c @@ -0,0 +1,53 @@ +#include "../moves.h" + +void get_king_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t friendly_king; + int king_square; + bitboard_t friendly_pieces; + if (position.turn == WHITE_TURN) { + friendly_pieces = whites(position); + friendly_king = position.bitboards[WHITE_KING]; + } else { + friendly_pieces = blacks(position); + friendly_king = position.bitboards[BLACK_KING]; + } + king_square = __builtin_ctzll(friendly_king); + + bitboard_t movement; + if (king_square >= 10) { + movement = 920078ULL << (king_square - 10); + } else { + movement = 920078ULL >> -(king_square - 10); + } + if (friendly_king & BITMASK_FILE_A) { + movement &= BITMASK_FILE_A | BITMASK_FILE_B; + } else if (friendly_king & BITMASK_FILE_H) { + movement &= BITMASK_FILE_G | BITMASK_FILE_H; + } + + movement &= ~friendly_pieces; + print_bitboard(movement); + while (movement) { + int to = __builtin_ctzll(movement); + movement &= movement - 1; + add_move(moves, king_square, to); + } +} + +#ifdef TEST_MOD +#include +#include "../bitboard.c" +#include "./moves.c" + +bool test_empty_board() { + int i = 0; + while (i++ < 1000000000); + return true; +} + +bool test_friendly_pieces() { + return false; +} +#endif diff --git a/src/engine/moves/knight.c b/src/engine/moves/knight.c new file mode 100644 index 0000000..c48b48e --- /dev/null +++ b/src/engine/moves/knight.c @@ -0,0 +1,101 @@ +#include "../moves.h" + +bitboard_t knight_moves[64] = { + 132096ULL, + 329728ULL, + 659712ULL, + 659712ULL >> 1, + 659712ULL >> 2, + 659712ULL >> 3, + 10489856ULL, + 4202496ULL, + + 33816580ULL, + 84410376ULL, + 168886289ULL, + 168886289ULL >> 1, + 168886289ULL >> 2, + 168886289ULL >> 3, + 2685403152ULL, + 1075839008ULL, + + 8657044482ULL, + 21609056261ULL, + 43234889994ULL, + 43234889994ULL >> 1, + 43234889994ULL >> 2, + 43234889994ULL >> 3, + 687463207072ULL, + 275414786112ULL, + + 8657044482ULL >> 8, + 21609056261ULL >> 8, + 43234889994ULL >> 8, + 43234889994ULL >> (8 + 1), + 43234889994ULL >> (8 + 2), + 43234889994ULL >> (8 + 3), + 687463207072ULL >> 8, + 275414786112ULL >> 8, + + 8657044482ULL >> 16, + 21609056261ULL >> 16, + 43234889994ULL >> 16, + 43234889994ULL >> (16 + 1), + 43234889994ULL >> (16 + 2), + 43234889994ULL >> (16 + 3), + 687463207072ULL >> 16, + 275414786112ULL >> 16, + + 8657044482ULL >> 24, + 21609056261ULL >> 24, + 43234889994ULL >> 24, + 43234889994ULL >> (24 + 1), + 43234889994ULL >> (24 + 2), + 43234889994ULL >> (24 + 3), + 687463207072ULL >> 24, + 275414786112ULL >> 24, + + 288234782788157440ULL, + 576469569871282176ULL, + 1224997833292120064ULL, + 1224997833292120064ULL >> 1, + 1224997833292120064ULL >> 2, + 1224997833292120064ULL >> 3, + 1152939783987658752ULL, + 2305878468463689728ULL, + + 1128098930098176ULL, + 2257297371824128ULL, + 4796069720358912ULL, + 4796069720358912ULL >> 1, + 4796069720358912ULL >> 2, + 4796069720358912ULL >> 3, + 4679521487814656ULL, + 9077567998918656ULL, +}; + +void get_knight_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t friendly_knights; + bitboard_t friendly_pieces; + if (position.turn == WHITE_TURN) { + friendly_pieces = whites(position); + friendly_knights = position.bitboards[WHITE_KNIGHT]; + } else { + friendly_pieces = blacks(position); + friendly_knights = position.bitboards[BLACK_KNIGHT]; + } + + while (friendly_knights) { + int from = __builtin_ctzll(friendly_knights); + friendly_knights &= friendly_knights - 1; + bitboard_t ATTACK_MASK = knight_moves[from]; + ATTACK_MASK &= ~friendly_pieces; + while (ATTACK_MASK) { + int to = __builtin_ctzll(ATTACK_MASK); + ATTACK_MASK &= ATTACK_MASK - 1; + add_move(moves, from, to); + } + } +} diff --git a/src/engine/moves/pawn.c b/src/engine/moves/pawn.c new file mode 100644 index 0000000..3cd28b8 --- /dev/null +++ b/src/engine/moves/pawn.c @@ -0,0 +1,164 @@ +#include "../moves.h" + +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_pawns = position.bitboards[WHITE_PAWN]; + bitboard_t y = friendly_pieces | enemy_bitboard; + bitboard_t x = ~((friendly_pawns << 8) & y) & (friendly_pawns << 8); + bitboard_t first_move_x = x & BITMASK_RANK_3; + + first_move_x |= (first_move_x << 8) & (~y); + x |= first_move_x; + + return x; +} +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_pawns = position.bitboards[BLACK_PAWN]; + bitboard_t y = friendly_pieces | enemy_bitboard; + bitboard_t x = ~((friendly_pawns >> 8) & y) & (friendly_pawns >> 8); + bitboard_t first_move_x = x & BITMASK_RANK_6; + + first_move_x |= (first_move_x >> 8) & (~y); + x |= first_move_x; + + return x; +} + +void get_pawn_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t forward_moves; + bitboard_t friendly_pawns; + bitboard_t enemy_bitboard; + if (position.turn == WHITE_TURN) { + forward_moves = get_white_pawn_forwardmoves(moves, position); + friendly_pawns = position.bitboards[WHITE_PAWN]; + enemy_bitboard = blacks(position); + } else { + forward_moves = get_black_pawn_forwardmoves(moves, position); + friendly_pawns = position.bitboards[BLACK_PAWN]; + enemy_bitboard = whites(position); + } + + bitboard_t file_masks[8] = { + BITMASK_FILE_A, + BITMASK_FILE_B, + BITMASK_FILE_C, + BITMASK_FILE_D, + BITMASK_FILE_E, + BITMASK_FILE_F, + BITMASK_FILE_G, + BITMASK_FILE_H, + }; + + for (int i = 0; i < 8; i++) { + bitboard_t item = file_masks[i] & forward_moves; + bitboard_t pawns = file_masks[i] & friendly_pawns; + + int from = __builtin_ctzll(pawns); + pawns &= (pawns - 1); + int next_from = __builtin_ctzll(pawns); + if (pawns == 0) next_from = 64; // to work around UB + + while (item) { + int to = __builtin_ctzll(item); + if (to > next_from) { + from = next_from; + pawns &= (pawns - 1); + next_from = __builtin_ctzll(pawns); + if (pawns == 0) next_from = 64; + } + item &= (item - 1); + add_move(moves, from, to); + } + } + + if (position.passantable_file != 0) { + bitboard_t PASSANT_RANK; + int rank_shift; + int from_shift; + if (position.turn == WHITE_TURN) { + PASSANT_RANK = BITMASK_RANK_5; + rank_shift = 40; + from_shift = -9; + } else { + PASSANT_RANK = BITMASK_RANK_4; + from_shift = 7; + rank_shift = 16; + } + + int left = 0, right = 0; + if (position.passantable_file > 1) left = position.passantable_file - 1; + if (position.passantable_file < 8) right = position.passantable_file + 1; + 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 + ); + } + } + 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 + ); + } + } + } + + + bitboard_t ATTACK_MASK; + int shift; + if (position.turn == WHITE_TURN) { + shift = 0; + } else { + shift = -16; + } + for (int i = 0; i < 8; i++) { + if (i == 0) ATTACK_MASK = 512; + else if (i == 7) ATTACK_MASK = 128; + else { + ATTACK_MASK = 640; + } + bitboard_t pawns = file_masks[i] & friendly_pawns; + while (pawns) { + int from = __builtin_ctzll(pawns); + pawns &= pawns - 1; + + bitboard_t MASK; + if (from + shift > 0) { + MASK = ATTACK_MASK << (from + shift); + } else { + MASK = ATTACK_MASK >> -(from + shift); + } + + MASK &= enemy_bitboard; + while (MASK) { + int to = __builtin_ctzll(MASK); + MASK &= MASK - 1; + add_move(moves, from, to); + } + } + } +} diff --git a/src/engine/moves/queen.c b/src/engine/moves/queen.c new file mode 100644 index 0000000..9e6e5c4 --- /dev/null +++ b/src/engine/moves/queen.c @@ -0,0 +1,31 @@ +#include "../moves.h" + +void get_queen_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t friendly_queens; + bitboard_t friendly_pieces; + bitboard_t enemy_pieces; + if (position.turn == WHITE_TURN) { + friendly_pieces = whites(position); + enemy_pieces = blacks(position); + friendly_queens = position.bitboards[WHITE_QUEEN]; + } else { + friendly_pieces = blacks(position); + enemy_pieces = whites(position); + friendly_queens = position.bitboards[BLACK_QUEEN]; + } + + __forloop_rook_moves_gen( + moves, + friendly_queens, + friendly_pieces, + enemy_pieces + ); + __forloop_bishop_moves_gen( + moves, + friendly_queens, + friendly_pieces, + enemy_pieces + ); +} diff --git a/src/engine/moves/rook.c b/src/engine/moves/rook.c new file mode 100644 index 0000000..c5867d5 --- /dev/null +++ b/src/engine/moves/rook.c @@ -0,0 +1,77 @@ +#include "../moves.h" + +void __forloop_rook_moves_gen( + moves_t* moves, + bitboard_t friendly_type, + bitboard_t friendly_pieces, + bitboard_t enemy_pieces +) { + while (friendly_type) { + int from = __builtin_ctzll(friendly_type); + friendly_type &= friendly_type - 1; + + int og_rank = from / 8; // range: [0, 7] + int og_file = from % 8; // range: [0, 7] + int rank = og_rank + 1, file = og_file, index = rank * 8 + file; + + + while (rank < 8 && !occupied_by(friendly_pieces, index)) { + add_move(moves, from, index); + if (occupied_by(enemy_pieces, index)) { + break; + } + index = ++rank * 8 + file; + } + + 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)) { + break; + } + index = --rank * 8 + file; + } + + 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)) { + break; + } + index = rank * 8 + ++file; + } + + 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)) { + break; + } + index = rank * 8 + --file; + } + } +} + +void get_rook_moves(moves_t* moves, position_t position) { + assert_valid_position(position); + + bitboard_t friendly_rooks; + bitboard_t friendly_pieces; + bitboard_t enemy_pieces; + if (position.turn == WHITE_TURN) { + friendly_pieces = whites(position); + enemy_pieces = blacks(position); + friendly_rooks = position.bitboards[WHITE_ROOK]; + } else { + friendly_pieces = blacks(position); + enemy_pieces = whites(position); + friendly_rooks = position.bitboards[BLACK_ROOK]; + } + + __forloop_rook_moves_gen( + moves, + friendly_rooks, + friendly_pieces, + enemy_pieces + ); +} diff --git a/src/engine/moves/vec.c b/src/engine/moves/vec.c new file mode 100644 index 0000000..6192706 --- /dev/null +++ b/src/engine/moves/vec.c @@ -0,0 +1,51 @@ +#include "../moves.h" +#include +#include + +void position_make_move(position_t* position, move_t* move) { + +} + +moves_t moves_init() { + return moves_init_wcapacity(16); +} + +moves_t moves_init_wcapacity(u32 capacity) { + move_t* moves = malloc(capacity * sizeof(*moves)); + return (moves_t) { + .moves = moves, + .capacity = capacity, + .length = 0, + }; +} + +moves_t moves_empty() { + return (moves_t) { + .moves = 0, + .capacity = 0, + .length = 0, + }; +} + +int min(int a, int b) { + if (a > b) return b; + return a; +} + +void add_move(moves_t* moves, square_t from, square_t to) { + assert(moves->moves != 0); + assert(from != to); + + if (moves->length + 1 >= moves->capacity) { + moves->capacity += min(32, moves->capacity); + moves->moves = realloc( + moves->moves, + moves->capacity * sizeof(*moves->moves) + ); + } + moves->moves[moves->length] = (move_t){ + .from = from, + .to = to + }; + moves->length++; +} -- cgit v1.2.3