From c61a59a4dd4a846499e6faf50ecdd87786f5c2df Mon Sep 17 00:00:00 2001 From: Aargh Rai Date: Wed, 25 Feb 2026 20:41:16 +0530 Subject: GOOGLE EN PASSANT --- assets/board.js | 45 ++++++++++++------------ src/bitboard.c | 2 ++ src/bitboard.h | 1 + src/main.c | 18 +++++++++- src/search/pawn_moves.c | 93 +++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 129 insertions(+), 30 deletions(-) diff --git a/assets/board.js b/assets/board.js index 6b8486a..e5a9a2d 100644 --- a/assets/board.js +++ b/assets/board.js @@ -41,14 +41,15 @@ const BLACK_BISHOP = 10; const BLACK_KNIGHT = 11; const BLACK_PAWN = 12; -function trackBitboard(j, i, selected, output) { +let counting_bitboard = 0n; +function trackBitboard(i, selected, output) { const mask = 1n << BigInt(i); if (selected) { - bitboards[j] |= mask; + counting_bitboard |= mask; } else { - bitboards[j] &= ~mask; + counting_bitboard &= ~mask; } - output.textContent = bitboards[j].toString(); + output.textContent = counting_bitboard.toString(); } function checkForPiece(square, bitIndex, set = true) { @@ -101,29 +102,29 @@ window.onload = () => { square.id = 'square-' + bitIndex.toString(); checkForPiece(square, bitIndex); square.onclick = (e) => { - if (!e.ctrlKey) { - const piece = checkForPiece(square, bitIndex, false); - if ( - (hoveringPiece < 0 && piece == null) || - (hoveringPiece >= 0 && piece != null) - ) return; - if (hoveringPiece < 0) { - setHoverpiece(piece); - square.style.backgroundImage = `none`; - bitboards[piece] &= ~(1n << BigInt(bitIndex)); + if (e.ctrlKey) { + const selected = square.classList.contains("selected"); + selectedAction(bitIndex, !selected, output); + if (selected) { + square.classList.remove("selected"); } else { - square.style.backgroundImage = `url(${assets[hoveringPiece]})`; - bitboards[hoveringPiece] |= (1n << BigInt(bitIndex)); - setHoverpiece(-1); + square.classList.add("selected"); } return; } - const selected = square.classList.contains("selected"); - selectedAction(0, bitIndex, !selected, output); - if (selected) { - square.classList.remove("selected"); + const piece = checkForPiece(square, bitIndex, false); + if ( + (hoveringPiece < 0 && piece == null) || + (hoveringPiece >= 0 && piece != null) + ) return; + if (hoveringPiece < 0) { + setHoverpiece(piece); + square.style.backgroundImage = `none`; + bitboards[piece] &= ~(1n << BigInt(bitIndex)); } else { - square.classList.add("selected"); + square.style.backgroundImage = `url(${assets[hoveringPiece]})`; + bitboards[hoveringPiece] |= (1n << BigInt(bitIndex)); + setHoverpiece(-1); } }; board.appendChild(square); diff --git a/src/bitboard.c b/src/bitboard.c index ce994c5..8b9a83c 100644 --- a/src/bitboard.c +++ b/src/bitboard.c @@ -25,6 +25,7 @@ position_t position_starting() { (1 << BLACK_SHORT_CASTLE) | (1 << BLACK_LONG_CASTLE), .turn = WHITE_TURN, + .passantable_column = 0, }; } @@ -38,6 +39,7 @@ void assert_valid_position(position_t position) { ) ); assert(position.turn == WHITE_TURN || position.turn == BLACK_TURN); + assert(position.passantable_column <= 8); } bitboard_t whites(position_t position) { diff --git a/src/bitboard.h b/src/bitboard.h index a816ea6..39f5d80 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -54,6 +54,7 @@ typedef struct { bitboard_t bitboards[PIECE_TYPE_COUNT]; u8 castling; u8 turn; + u8 passantable_column; } position_t; position_t position_starting(); diff --git a/src/main.c b/src/main.c index 6c05aa2..fdff93d 100644 --- a/src/main.c +++ b/src/main.c @@ -5,7 +5,23 @@ int main() { moves_t moves = moves_init(); position_t position = position_starting(); + +position.bitboards[WHITE_KING] = 16ULL; +position.bitboards[WHITE_QUEEN] = 8ULL; +position.bitboards[WHITE_ROOK] = 129ULL; +position.bitboards[WHITE_BISHOP] = 36ULL; +position.bitboards[WHITE_KNIGHT] = 66ULL; +position.bitboards[WHITE_PAWN] = 85899406080ULL; +position.bitboards[BLACK_KING] = 1152921504606846976ULL; +position.bitboards[BLACK_QUEEN] = 576460752303423488ULL; +position.bitboards[BLACK_ROOK] = 9295429630892703744ULL; +position.bitboards[BLACK_BISHOP] = 2594073385365405696ULL; +position.bitboards[BLACK_KNIGHT] = 4755801206503243776ULL; +position.bitboards[BLACK_PAWN] = 69524353607270400ULL; + + position.passantable_column = 4; + position.turn = WHITE_TURN; + get_pawn_moves(&moves, position); - printf("Hello World\n"); return 0; } diff --git a/src/search/pawn_moves.c b/src/search/pawn_moves.c index e169c07..f015e7d 100644 --- a/src/search/pawn_moves.c +++ b/src/search/pawn_moves.c @@ -1,14 +1,17 @@ #include "../search.h" +#include #include +#include -void get_white_pawn_moves(moves_t* moves, position_t position) { +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_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); @@ -17,16 +20,17 @@ void get_white_pawn_moves(moves_t* moves, position_t position) { first_move_x |= (first_move_x << 8) & (~y); x |= first_move_x; - print_bitboard(x); + return x; } -void get_black_pawn_moves(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_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); @@ -34,14 +38,89 @@ void get_black_pawn_moves(moves_t* moves, position_t position) { 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; if (position.turn == WHITE_TURN) { - get_white_pawn_moves(moves, position); + forward_moves = get_white_pawn_forwardmoves(moves, position); + friendly_pawns = position.bitboards[WHITE_PAWN]; } else { - get_black_pawn_moves(moves, position); + forward_moves = get_black_pawn_forwardmoves(moves, position); + friendly_pawns = position.bitboards[BLACK_PAWN]; + } + + bitboard_t column_masks[8] = { + BITMASK_COLM_1, + BITMASK_COLM_2, + BITMASK_COLM_3, + BITMASK_COLM_4, + BITMASK_COLM_5, + BITMASK_COLM_6, + BITMASK_COLM_7, + BITMASK_COLM_8, + }; + + for (int i = 0; i < 8; i++) { + bitboard_t item = column_masks[i] & forward_moves; + bitboard_t pawns = column_masks[i] & friendly_pawns; + + int from = __builtin_ctzll(pawns); + pawns &= (pawns - 1); + int next_from = __builtin_ctzll(pawns); + while (item) { + int to = __builtin_ctzll(item); + if (to > next_from) { + from = next_from; + pawns &= (pawns - 1); + next_from = __builtin_ctzll(pawns); + } + item &= (item - 1); + add_move(moves, from, to); + } + } + + if (position.passantable_column != 0) { + bitboard_t PASSANT_RANK; + int rank_shift; + int from_shift; + if (position.turn == WHITE_TURN) { + PASSANT_RANK = BITMASK_RANK_E; + rank_shift = 40; + from_shift = -9; + } else { + PASSANT_RANK = BITMASK_RANK_D; + from_shift = 7; + rank_shift = 16; + } + + int left = 0, right = 0; + if (position.passantable_column > 1) left = position.passantable_column - 1; + if (position.passantable_column < 8) right = position.passantable_column + 1; + if (left != 0) { + bitboard_t MASK = column_masks[left - 1] & friendly_pawns & PASSANT_RANK; + if (MASK != 0) { + add_move( + moves, + left + rank_shift + from_shift, + position.passantable_column + rank_shift - 1 + ); + } + } + if (right != 0) { + bitboard_t MASK = column_masks[right - 1] & friendly_pawns & PASSANT_RANK; + if (MASK != 0) { + add_move( + moves, + right + rank_shift + from_shift, + position.passantable_column + rank_shift - 1 + ); + } + } } } -- cgit v1.2.3