From 3cd53c7d708746143c8a0c75beff8c58c87eda1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 09:51:07 +0100 Subject: [PATCH 01/11] added file and module structure for board representation --- engine/src/bitboard.rs | 3 ++- engine/src/bitboard/board.rs | 0 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 engine/src/bitboard/board.rs diff --git a/engine/src/bitboard.rs b/engine/src/bitboard.rs index 67d128d..890ddc2 100644 --- a/engine/src/bitboard.rs +++ b/engine/src/bitboard.rs @@ -1,2 +1,3 @@ mod attackmaps; -mod utils; \ No newline at end of file +mod utils; +pub mod board; \ No newline at end of file diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs new file mode 100644 index 0000000..e69de29 -- 2.49.1 From 66dd2877b24f2ed8336119f9a1989bb64c7315f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 09:56:17 +0100 Subject: [PATCH 02/11] defined board representation shape in board.rs --- engine/src/bitboard/board.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index e69de29..b742d5c 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -0,0 +1,10 @@ +pub struct Board { + bitboards: [u64; 12], // 0-5 -> white pieces (P, N, B, R, Q, K), 6-11 -> black pieces (p, n, b, r, q, k) + piece_board: [u8; 64], // same as board indexes, 12 -> empty square + occupancy: [u64; 3], // 0 -> white, 1 -> black, 2 -> combined + castling_rights: u8, // 0b0000_KQkq + pinned_squares: [u8; 64], // 0 -> E-W, 1 -> NE-SW, 2 -> N-S, 3 -> SE-NW, 4 -> no pin + pin_mask: u64, // 1 -> pin, 0 -> no pin + en_passant_square: u64, // 1 -> ep square, 0 -> no ep square + side_to_move: u8, // 0 -> white to play, 1 -> black to play +} \ No newline at end of file -- 2.49.1 From 38b38845d67d891b99676d41f671eac2a3a7ce03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 09:58:38 +0100 Subject: [PATCH 03/11] added constructor for clear board to board.rs --- engine/src/bitboard/board.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index b742d5c..d630c32 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -6,5 +6,23 @@ pub struct Board { pinned_squares: [u8; 64], // 0 -> E-W, 1 -> NE-SW, 2 -> N-S, 3 -> SE-NW, 4 -> no pin pin_mask: u64, // 1 -> pin, 0 -> no pin en_passant_square: u64, // 1 -> ep square, 0 -> no ep square - side_to_move: u8, // 0 -> white to play, 1 -> black to play + side_to_move: u8 // 0 -> white to play, 1 -> black to play +} + +impl Board { + + pub fn new_clear() -> Self { + let mut bit_board: Self = Self { + bitboards: [0x0000_0000_0000_0000; 12], + piece_board: [12; 64], + occupancy: [0x0000_0000_0000_0000; 3], + castling_rights: 0b0000_0000, + pinned_squares: [4; 64], + pin_mask: 0u64, + en_passant_square: 0x0000_0000_0000_0000, + side_to_move: 0 + }; + + return bit_board; + } } \ No newline at end of file -- 2.49.1 From 7f4c53ddb74a8c0808f33a047e459caae665cf36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 10:03:24 +0100 Subject: [PATCH 04/11] added partial constructor for initial board state to board.rs --- engine/src/bitboard/board.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index d630c32..85abea4 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -25,4 +25,29 @@ impl Board { return bit_board; } + pub fn new() -> Self { + let mut bit_board: Board = Self { + bitboards: [0x0000_0000_0000_FF00, + 0x0000_0000_0000_0042, + 0x0000_0000_0000_0024, + 0x0000_0000_0000_0081, + 0x0000_0000_0000_0008, + 0x0000_0000_0000_0010, + 0x00FF_0000_0000_0000, + 0x4200_0000_0000_0000, + 0x2400_0000_0000_0000, + 0x8100_0000_0000_0000, + 0x0800_0000_0000_0000, + 0x1000_0000_0000_0000], + piece_board: [12; 64], + occupancy: [0; 3], + castling_rights: 0b0000_1111, + pinned_squares: [4; 64], + pin_mask: 0u64, + en_passant_square: 0x0000_0000_0000_0000, + side_to_move: 0 + }; + return bit_board; + } + } \ No newline at end of file -- 2.49.1 From c88fbe68e310a023d60f5fa3d854faf993dfecd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 10:06:12 +0100 Subject: [PATCH 05/11] added and used necessary methods the initial state constructor --- engine/src/bitboard/board.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index 85abea4..3d3695d 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -50,4 +50,26 @@ impl Board { return bit_board; } + + + fn calc_occupancy(&mut self) { + self.occupancy = [0u64; 3]; + for b in 0..6 { + self.occupancy[0] |= self.bitboards[b]; + } + for b in 6..12 { + self.occupancy[1] |= self.bitboards[b]; + } + self.occupancy[2] = self.occupancy[0] | self.occupancy[1]; + } + fn calc_piece_board(&mut self) { + for sq in 0..64 { + for b in 0..12 { + if (self.bitboards[b as usize] & 1 << sq) != 0 { + self.piece_board[sq] = b; + } + } + } + } + } \ No newline at end of file -- 2.49.1 From 11f26809df1eef76067c7ed1a61aadc99feb5dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 10:07:23 +0100 Subject: [PATCH 06/11] used calc_occupancy and calc_piece_board methods in the initial state constructor --- engine/src/bitboard/board.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index 3d3695d..06d5e7d 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -47,6 +47,9 @@ impl Board { en_passant_square: 0x0000_0000_0000_0000, side_to_move: 0 }; + bit_board.calc_occupancy(); + bit_board.calc_piece_board(); + return bit_board; } -- 2.49.1 From f36a196b2f39afa9a91db2d18655a7b6517c3d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 10:11:34 +0100 Subject: [PATCH 07/11] added getters for fields --- engine/src/bitboard/board.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index 06d5e7d..1a7794c 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -53,6 +53,38 @@ impl Board { return bit_board; } + #[inline(always)] + pub fn bitboards(&self, index: usize) -> u64 { + return self.bitboards[index]; + } + #[inline(always)] + pub fn piece_board(&self, sq: u8) -> u8 { + return self.piece_board[sq as usize]; + } + #[inline(always)] + pub fn occupancy(&self, side: usize) -> u64 { + return self.occupancy[side]; + } + #[inline(always)] + pub fn castling_rights(&self) -> u8 { + return self.castling_rights; + } + #[inline(always)] + pub fn pinned_squares(&self, sq: usize) -> u8 { + return self.pinned_squares[sq]; + } + #[inline(always)] + pub fn pin_mask(&self) -> u64 { + return self.pin_mask; + } + #[inline(always)] + pub fn en_passant_square(&self) -> u64 { + return self.en_passant_square; + } + #[inline(always)] + pub fn side_to_move(&self) -> u8 { + return self.side_to_move; + } fn calc_occupancy(&mut self) { -- 2.49.1 From 5854dbc20b20dc1e95a6c05aea5e9bbe240e3f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 10:12:52 +0100 Subject: [PATCH 08/11] set each field to pub(in super) for later use --- engine/src/bitboard/board.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index 1a7794c..71980df 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -1,12 +1,12 @@ pub struct Board { - bitboards: [u64; 12], // 0-5 -> white pieces (P, N, B, R, Q, K), 6-11 -> black pieces (p, n, b, r, q, k) - piece_board: [u8; 64], // same as board indexes, 12 -> empty square - occupancy: [u64; 3], // 0 -> white, 1 -> black, 2 -> combined - castling_rights: u8, // 0b0000_KQkq - pinned_squares: [u8; 64], // 0 -> E-W, 1 -> NE-SW, 2 -> N-S, 3 -> SE-NW, 4 -> no pin - pin_mask: u64, // 1 -> pin, 0 -> no pin - en_passant_square: u64, // 1 -> ep square, 0 -> no ep square - side_to_move: u8 // 0 -> white to play, 1 -> black to play + pub(in super) bitboards: [u64; 12], // 0-5 -> white pieces (P, N, B, R, Q, K), 6-11 -> black pieces (p, n, b, r, q, k) + pub(in super) piece_board: [u8; 64], // same as board indexes, 12 -> empty square + pub(in super) occupancy: [u64; 3], // 0 -> white, 1 -> black, 2 -> combined + pub(in super) castling_rights: u8, // 0b0000_KQkq + pub(in super) pinned_squares: [u8; 64], // 0 -> E-W, 1 -> NE-SW, 2 -> N-S, 3 -> SE-NW, 4 -> no pin + pub(in super) pin_mask: u64, // 1 -> pin, 0 -> no pin + pub(in super) en_passant_square: u64, // 1 -> ep square, 0 -> no ep square + pub(in super) side_to_move: u8 // 0 -> white to play, 1 -> black to play } impl Board { -- 2.49.1 From 274ffcf5ec9d936810847e046b8c666c2b65023d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 10:14:37 +0100 Subject: [PATCH 09/11] added method to get the current square of a king --- engine/src/bitboard/board.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index 71980df..7eb73da 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -86,6 +86,10 @@ impl Board { return self.side_to_move; } + #[inline(always)] + pub fn current_king_square(&self) -> u32 { + return if self.side_to_move == 0 { self.bitboards[5].trailing_zeros() } else { self.bitboards[11].trailing_zeros() }; + } fn calc_occupancy(&mut self) { self.occupancy = [0u64; 3]; -- 2.49.1 From 1104c8e6c57c79369d1af0f0dcfb130fdb11efdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 10:21:00 +0100 Subject: [PATCH 10/11] added helper method for fen parsing to utils.rs --- engine/src/bitboard/utils.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/engine/src/bitboard/utils.rs b/engine/src/bitboard/utils.rs index a30e503..25d7ba8 100644 --- a/engine/src/bitboard/utils.rs +++ b/engine/src/bitboard/utils.rs @@ -27,6 +27,27 @@ pub fn notation_from_square_number(sq: u8) -> String { return notation; } +pub fn try_get_square_number_from_notation(notation: &str) -> Result { + + let file = match notation.chars().nth(0).unwrap() { + 'a' => 0, + 'b' => 1, + 'c' => 2, + 'd' => 3, + 'e' => 4, + 'f' => 5, + 'g' => 6, + 'h' => 7, + _ => { return Result::Err(()); } + }; + if let Some(rank) = notation.chars().nth(1) { + return Result::Ok(file + 8 * (rank.to_digit(10).unwrap() as u8) - 8); + } + else { + return Result::Err(()); + } +} + // <----- TESTS -----> -- 2.49.1 From 5425ccc5cd729e545b9af00103a204c6338ea5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Sat, 15 Nov 2025 10:26:31 +0100 Subject: [PATCH 11/11] added partial constructor for starting from a fen position --- engine/src/bitboard/board.rs | 68 ++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index 7eb73da..7ceb4d6 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -1,3 +1,5 @@ +use super::utils::try_get_square_number_from_notation; + pub struct Board { pub(in super) bitboards: [u64; 12], // 0-5 -> white pieces (P, N, B, R, Q, K), 6-11 -> black pieces (p, n, b, r, q, k) pub(in super) piece_board: [u8; 64], // same as board indexes, 12 -> empty square @@ -52,6 +54,72 @@ impl Board { return bit_board; } + pub fn build(fen: &str) -> Self { + let mut board: Board = Board::new_clear(); + + let mut col: i32 = 0; + let mut row: i32 = 7; + let pieces: [char; 12] = ['p', 'n', 'b', 'r', 'q', 'k', 'P', 'N', 'B', 'R', 'Q', 'K']; + let mut coming_up: &str = fen; + + for (i, c) in coming_up.chars().enumerate() { + if pieces.contains(&c) { + // board.place_piece(row*8 + col, c); + col += 1; + } + else if ('1'..='8').contains(&c) { + col += c.to_string().parse::().unwrap(); + } + else if c == '/' { + row -= 1; + col = 0; + } + else { + coming_up = &coming_up[i+1..]; + break; + } + } + board.calc_occupancy(); + + match coming_up.chars().next().unwrap() { + 'w' => board.side_to_move = 0, + 'b' => board.side_to_move = 1, + _ => panic!("invalid fen notation / to be handled later") + } + coming_up = &coming_up[2..]; + + for (i, c) in coming_up.chars().enumerate() { + match c { + 'K' => board.castling_rights |= 1 << 3, + 'Q' => board.castling_rights |= 1 << 2, + 'k' => board.castling_rights |= 1 << 1, + 'q' => board.castling_rights |= 1, + '-' => { + coming_up = &coming_up[i+2..]; + break; + } + _ => { + coming_up = &coming_up[i+1..]; + break; + } + } + } + match coming_up.chars().next().unwrap() { + '-' => { + coming_up = &coming_up[1..]; + } + _ => { + let notation = coming_up.split(' ').next().unwrap(); + if let Ok(epsq_index) = try_get_square_number_from_notation(notation) { + board.en_passant_square = 1 << epsq_index; + } + } + } + // board.calc_pinned_squares(); + board.calc_piece_board(); + + return board; + } #[inline(always)] pub fn bitboards(&self, index: usize) -> u64 { -- 2.49.1