summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/board.js45
-rw-r--r--src/bitboard.c2
-rw-r--r--src/bitboard.h1
-rw-r--r--src/main.c18
-rw-r--r--src/search/pawn_moves.c93
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 <stdio.h>
#include <assert.h>
+#include <inttypes.h>
-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
+ );
+ }
+ }
}
}