From ee61528891d4043d0c95de3c9b78b30af1899c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:16:48 +0100 Subject: [PATCH 01/36] added file and module structure for bitboard::movegen.rs --- engine/src/bitboard.rs | 1 + engine/src/bitboard/movegen.rs | 0 2 files changed, 1 insertion(+) create mode 100644 engine/src/bitboard/movegen.rs diff --git a/engine/src/bitboard.rs b/engine/src/bitboard.rs index 1486484..177e4a5 100644 --- a/engine/src/bitboard.rs +++ b/engine/src/bitboard.rs @@ -5,5 +5,6 @@ mod checkinfo; mod attacks; mod bitmove; mod movebuffer; +mod movegen; pub mod board; \ No newline at end of file diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs new file mode 100644 index 0000000..e69de29 From d172afc50c5841cdea165277371a6d24c30ff919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:32:12 +0100 Subject: [PATCH 02/36] re-added missing code for check tests from past branch --- engine/src/bitboard/board.rs | 19 +++++++- engine/src/bitboard/legality.rs | 79 +++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index 11a85ce..483f1c4 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -64,7 +64,7 @@ impl Board { for (i, c) in coming_up.chars().enumerate() { if pieces.contains(&c) { - // board.place_piece(row*8 + col, c); + board.place_piece(row*8 + col, c); col += 1; } else if ('1'..='8').contains(&c) { @@ -179,4 +179,21 @@ impl Board { } } + pub fn place_piece(&mut self, sq: i32, piece: char) { + match piece { + 'p' => {self.bitboards[6] |= 1 << sq} + 'n' => {self.bitboards[7] |= 1 << sq} + 'b' => {self.bitboards[8] |= 1 << sq} + 'r' => {self.bitboards[9] |= 1 << sq} + 'q' => {self.bitboards[10] |= 1 << sq} + 'k' => {self.bitboards[11] |= 1 << sq} + 'P' => {self.bitboards[0] |= 1 << sq} + 'N' => {self.bitboards[1] |= 1 << sq} + 'B' => {self.bitboards[2] |= 1 << sq} + 'R' => {self.bitboards[3] |= 1 << sq} + 'Q' => {self.bitboards[4] |= 1 << sq} + 'K' => {self.bitboards[5] |= 1 << sq} + _ => () + } + } } \ No newline at end of file diff --git a/engine/src/bitboard/legality.rs b/engine/src/bitboard/legality.rs index 7d12e57..f42fdc1 100644 --- a/engine/src/bitboard/legality.rs +++ b/engine/src/bitboard/legality.rs @@ -1,8 +1,56 @@ use super::board::Board; use super::attackmaps::RAY_TABLE; +use super::checkinfo::CheckInfo; +use super::attacks::get_raycast_from_square_in_direction; impl Board { + pub fn check_test(&self) -> CheckInfo { + let mut check_info: CheckInfo = CheckInfo::new(); + let offset: usize = 6 * self.side_to_move as usize; + let king: u64 = self.bitboards[5 + offset]; + let king_sq = king.trailing_zeros() as usize; + let occupancy = self.occupancy[2]; + + // queen-rook checks (+) + let attacker_mask = self.bitboards[10 - offset] | self.bitboards[9 - offset]; + + for dir in [0, 2, 4, 6] { + let threat_mask: u64 = get_raycast_from_square_in_direction(occupancy, king_sq, dir); + if threat_mask & attacker_mask != 0 { + check_info.add_checker(threat_mask); + } + } + + // queen-bishop checks (x) + let attacker_mask = self.bitboards[10 - offset] | self.bitboards[8 - offset]; + + for dir in [1, 3, 5, 7] { + let threat_mask = get_raycast_from_square_in_direction(occupancy, king_sq, dir); + if threat_mask & attacker_mask != 0 { + check_info.add_checker(threat_mask); + } + } + + // knight checks (L) + let attacker_mask = self.bitboards[7 - offset]; + let threat_mask = self.get_pseudo_knight_moves(king_sq as u32); + let checker = threat_mask & attacker_mask; + if checker != 0 { + check_info.add_checker(checker); + } + + // pawn checks (v) + let attacker_mask = self.bitboards[6 - offset]; + let threat_mask = self.get_pseudo_pawn_captures(king_sq as u32); + let checker = threat_mask & attacker_mask; + if checker != 0 { + check_info.add_checker(checker); + } + + return check_info; + } + pub(in super) fn calc_pinned_squares(&mut self) { self.pinned_squares = [4; 64]; self.pin_mask = 0u64; @@ -45,4 +93,35 @@ impl Board { } } +} + +// <----- TESTS -----> + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn check_test_test() { + + let fens = [ + "rnb1k1nr/pppppppp/4q3/8/1b6/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", // no check + "rnb1k1nr/pppppppp/4q3/8/1b1P4/8/PPP1PPPP/RNBQKBNR w KQkq d3 0 1", // single check + "rnb1k1nr/ppp1p2p/3pq1p1/8/1b1P1P2/8/PPP2PPP/RNBQKBNR w KQkq - 0 1" // double check + ]; + let expected_results = [ + CheckInfo { check_count: 0, move_mask: 0xFFFF_FFFF_FFFF_FFFF }, + CheckInfo { check_count: 1, move_mask: 0x0000_0000_0204_0800 }, + CheckInfo { check_count: 2, move_mask: 0x0000_0000_0000_0000 } + ]; + + for test_nr in 0..3 { + let fen = fens[test_nr]; + let board = Board::build(fen); + let check_test_actual = board.check_test(); + assert_eq!(check_test_actual.check_count, expected_results[test_nr].check_count); + assert_eq!(check_test_actual.move_mask, expected_results[test_nr].move_mask); + } + + } } \ No newline at end of file From 48272d6d70ebbb44c5e6dad8ea4536f7fec011a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:35:46 +0100 Subject: [PATCH 03/36] added skeleton for main move generation method to bitboard::movegen --- engine/src/bitboard/movegen.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index e69de29..345821e 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -0,0 +1,19 @@ +use super::board::Board; +use super::movebuffer::MoveBuffer; + +impl Board { + + pub fn collect_moves(&mut self, buffer: &mut MoveBuffer, temp_buffer: &mut MoveBuffer) -> bool { + buffer.clear(); + self.calc_pinned_squares(); + let check_info = self.check_test(); + + match check_info.check_count { + // 0 => self.collect_all_moves(), + // 1 => self.collect_moves_single_check(), + // 2 => self.collect_king_evasion(), + _ => panic!("More than 2 checking pieces found as the same time!") + } + return check_info.check_count > 0; + } +} \ No newline at end of file From 3f7cc2df4dfa2db1325353f01fda9ffbbb2cd73f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:39:00 +0100 Subject: [PATCH 04/36] added file and module structure for bitboard::movegen::pawns --- engine/src/bitboard/movegen.rs | 2 ++ engine/src/bitboard/movegen/pawns.rs | 0 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/pawns.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 345821e..aa5ff96 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -1,3 +1,5 @@ +mod pawns; + use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs new file mode 100644 index 0000000..e69de29 From a2f261778bdce392e94fa62fe70944c6c86a9a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:47:44 +0100 Subject: [PATCH 05/36] implemented move generation method for pawn quiet moves --- engine/src/bitboard/legality.rs | 7 +++++ engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/pawns.rs | 38 ++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/engine/src/bitboard/legality.rs b/engine/src/bitboard/legality.rs index f42fdc1..f81973e 100644 --- a/engine/src/bitboard/legality.rs +++ b/engine/src/bitboard/legality.rs @@ -93,6 +93,13 @@ impl Board { } } + #[inline] + pub(in super) fn get_pin_masked_moves(&self, moves: u64, sq: u32) -> u64 { + let sq: usize = sq as usize; + if self.pinned_squares[sq] == 4 { return moves; } + let dir: u8 = self.pinned_squares[sq]; + return moves & (RAY_TABLE[sq][dir as usize] | RAY_TABLE[sq][4 + dir as usize]); + } } // <----- TESTS -----> diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index aa5ff96..4dbb76e 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -2,6 +2,7 @@ mod pawns; use super::board::Board; use super::movebuffer::MoveBuffer; +use super::bitmove::BitMove; impl Board { diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index e69de29..30d2000 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -0,0 +1,38 @@ +use super::*; + +impl Board { + + fn add_pawn_quiets(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset: u8 = self.side_to_move * 6; + let mut pawns: u64 = self.bitboards[offset as usize]; + while pawns != 0 { + let next_sq = pawns.trailing_zeros(); + pawns &= !(1 << next_sq); + + let mut quiets: u64 = self.get_pseudo_pawn_moves(next_sq) & move_mask; + quiets = self.get_pin_masked_moves(quiets, next_sq); + while quiets != 0 { + let to_sq = quiets.trailing_zeros(); + + if (self.side_to_move == 0 && quiets.trailing_zeros() / 8 == 7) + || (self.side_to_move == 1 && quiets.trailing_zeros() / 8 == 0) { + for piece_type in [3, 2, 1, 0] { + buffer.add(BitMove::quiet( + next_sq as u8, + to_sq as u8, + Some(piece_type) + )); + } + } + else { + buffer.add(BitMove::quiet( + next_sq as u8, + to_sq as u8, + None + )); + } + quiets &= !(1 << to_sq); + } + } + } +} \ No newline at end of file From a4c63f19e54bc6d381f4dd8eaedebd0f65132245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:52:28 +0100 Subject: [PATCH 06/36] implemented move generation method for pawn capture moves --- engine/src/bitboard/movegen/pawns.rs | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index 30d2000..3cb7037 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -35,4 +35,40 @@ impl Board { } } } + fn add_pawn_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut pawns: u64 = self.bitboards[offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while pawns != 0 { + let next_sq: u32 = pawns.trailing_zeros(); + pawns &= !(1 << next_sq); + + let mut attacks: u64 = self.get_pseudo_pawn_captures(next_sq) & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + attacks &= opponents; + + while attacks != 0 { + let to_sq = attacks.trailing_zeros(); + + if (self.side_to_move == 0 && attacks.trailing_zeros() / 8 == 7) + || (self.side_to_move == 1 && attacks.trailing_zeros() / 8 == 0) { + for piece_type in [3, 2, 1, 0] { + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + Some(piece_type) + )); + } + } + else { + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + attacks &= !(1 << to_sq); + } + } + } } \ No newline at end of file From d66787f51d169dbdc83c6c19690fdd8242e265f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:54:01 +0100 Subject: [PATCH 07/36] implemented method to collect both quiet and capture moves for pawns --- engine/src/bitboard/movegen/pawns.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index 3cb7037..f31b3f7 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -71,4 +71,8 @@ impl Board { } } } + fn add_pawn_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + self.add_pawn_captures(capture_buffer, move_mask); + self.add_pawn_quiets(quiet_buffer, move_mask); + } } \ No newline at end of file From 372d86b4511b941864e586707cfa5d1121ca10ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:58:56 +0100 Subject: [PATCH 08/36] changed signature utility functions utils::pop_lsb and utils::pop_msb to reduce unnecessary type conversions --- engine/src/bitboard/movegen/pawns.rs | 8 ++++---- engine/src/bitboard/utils.rs | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index f31b3f7..1f0c6e3 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -1,3 +1,5 @@ +use crate::bitboard::utils::pop_lsb; + use super::*; impl Board { @@ -6,8 +8,7 @@ impl Board { let offset: u8 = self.side_to_move * 6; let mut pawns: u64 = self.bitboards[offset as usize]; while pawns != 0 { - let next_sq = pawns.trailing_zeros(); - pawns &= !(1 << next_sq); + let next_sq = pop_lsb(&mut pawns); let mut quiets: u64 = self.get_pseudo_pawn_moves(next_sq) & move_mask; quiets = self.get_pin_masked_moves(quiets, next_sq); @@ -40,8 +41,7 @@ impl Board { let mut pawns: u64 = self.bitboards[offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; while pawns != 0 { - let next_sq: u32 = pawns.trailing_zeros(); - pawns &= !(1 << next_sq); + let next_sq = pop_lsb(&mut pawns); let mut attacks: u64 = self.get_pseudo_pawn_captures(next_sq) & move_mask; attacks = self.get_pin_masked_moves(attacks, next_sq); diff --git a/engine/src/bitboard/utils.rs b/engine/src/bitboard/utils.rs index f7f83fe..81cc68f 100644 --- a/engine/src/bitboard/utils.rs +++ b/engine/src/bitboard/utils.rs @@ -1,13 +1,13 @@ #[inline(always)] -pub fn pop_lsb(value: &mut u64) -> usize { - let idx = value.trailing_zeros() as usize; +pub fn pop_lsb(value: &mut u64) -> u32 { + let idx = value.trailing_zeros(); *value &= !(1 << idx); return idx; } #[inline(always)] -pub fn pop_msb(value: &mut u64) -> usize { - let idx = 63 - value.leading_zeros() as usize; +pub fn pop_msb(value: &mut u64) -> u32 { + let idx = 63 - value.leading_zeros(); *value &= !(1 << idx); return idx; } @@ -72,7 +72,7 @@ mod tests { 0xBEAC_DBE0_903A_AC00, 0x01E8_C895_A6F0_0000 ]; - let expected_values: [usize; 6] = [63, 0, 4, 2, 10, 20]; + let expected_values: [u32; 6] = [63, 0, 4, 2, 10, 20]; // tests for index in 0..6 { @@ -92,7 +92,7 @@ mod tests { 0x0000_C1C3_201C_0DB1, 0x0000_0203_0DE4_E944 ]; - let expected_values: [usize; 6] = [63, 0, 61, 57, 47, 41]; + let expected_values: [u32; 6] = [63, 0, 61, 57, 47, 41]; // tests for index in 0..6 { From 2e82a52f2754a6bf180c010308c9fcd2718164f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:03:27 +0100 Subject: [PATCH 09/36] added file and module structure for bitboard::movegen::knights --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/knights.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/knights.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 4dbb76e..b83278a 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -1,4 +1,5 @@ mod pawns; +mod knights; use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/knights.rs b/engine/src/bitboard/movegen/knights.rs new file mode 100644 index 0000000..9148c04 --- /dev/null +++ b/engine/src/bitboard/movegen/knights.rs @@ -0,0 +1 @@ +use super::*; \ No newline at end of file From 40e2c50209247a1c50b202bc304d26f9f43eb851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:05:58 +0100 Subject: [PATCH 10/36] implemeneted general move generation method for knight moves --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/knights.rs | 37 +++++++++++++++++++++++++- engine/src/bitboard/movegen/pawns.rs | 2 -- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index b83278a..0fb7857 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -4,6 +4,7 @@ mod knights; use super::board::Board; use super::movebuffer::MoveBuffer; use super::bitmove::BitMove; +use super::utils::*; impl Board { diff --git a/engine/src/bitboard/movegen/knights.rs b/engine/src/bitboard/movegen/knights.rs index 9148c04..43b6b24 100644 --- a/engine/src/bitboard/movegen/knights.rs +++ b/engine/src/bitboard/movegen/knights.rs @@ -1 +1,36 @@ -use super::*; \ No newline at end of file +use super::*; + +impl Board { + + fn add_knight_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + let piece_index = 1 + self.side_to_move * 6; + let mut knights = self.bitboards[piece_index as usize]; + let empty = !self.occupancy[2]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while knights != 0 { + let from_sq = pop_lsb(&mut knights); + let raw_move_map = self.get_pseudo_knight_moves(from_sq) & move_mask; + let move_map = self.get_pin_masked_moves(raw_move_map, from_sq); + + let mut quiet_map = move_map & empty; + let mut capture_map = move_map & opponents; + + while quiet_map != 0 { + let to_sq = pop_lsb(&mut quiet_map); + quiet_buffer.add(BitMove::quiet( + from_sq as u8, + to_sq as u8, + None + )); + } + while capture_map != 0 { + let to_sq = pop_lsb(&mut capture_map); + capture_buffer.add(BitMove::capture( + from_sq as u8, + to_sq as u8, + None + )); + } + } + } +} \ No newline at end of file diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index 1f0c6e3..6e9e1dc 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -1,5 +1,3 @@ -use crate::bitboard::utils::pop_lsb; - use super::*; impl Board { From 2d646f0ad0421ebd11dcecd7be92c57c4b7abc83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:07:18 +0100 Subject: [PATCH 11/36] implemented move generation method for knight capture moves --- engine/src/bitboard/movegen/knights.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen/knights.rs b/engine/src/bitboard/movegen/knights.rs index 43b6b24..db4a105 100644 --- a/engine/src/bitboard/movegen/knights.rs +++ b/engine/src/bitboard/movegen/knights.rs @@ -33,4 +33,23 @@ impl Board { } } } + fn add_knight_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut knights: u64 = self.bitboards[1 + offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while knights != 0 { + let next_sq: u32 = pop_lsb(&mut knights); + let mut attacks: u64 = self.get_pseudo_knight_moves(next_sq) & opponents & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + + while attacks != 0 { + let to_sq = pop_lsb(&mut attacks); + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + } + } } \ No newline at end of file From 06cb2b88c2d61d9b2ee0b25be0db00e82917cbd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:08:45 +0100 Subject: [PATCH 12/36] added file and module structure for bitboard::movegen::bishops --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/bishops.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/bishops.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 0fb7857..1aba161 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -1,5 +1,6 @@ mod pawns; mod knights; +mod bishops; use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/bishops.rs b/engine/src/bitboard/movegen/bishops.rs new file mode 100644 index 0000000..9148c04 --- /dev/null +++ b/engine/src/bitboard/movegen/bishops.rs @@ -0,0 +1 @@ +use super::*; \ No newline at end of file From 8165749845ec36fe74d2967995d51504af713f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:11:39 +0100 Subject: [PATCH 13/36] implemented general move generation method for bishops --- engine/src/bitboard/movegen/bishops.rs | 37 +++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/movegen/bishops.rs b/engine/src/bitboard/movegen/bishops.rs index 9148c04..c05a964 100644 --- a/engine/src/bitboard/movegen/bishops.rs +++ b/engine/src/bitboard/movegen/bishops.rs @@ -1 +1,36 @@ -use super::*; \ No newline at end of file +use super::*; + +impl Board { + + fn add_bishop_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + let piece_index = 2 + self.side_to_move * 6; + let mut bishops = self.bitboards[piece_index as usize]; + let empty = !self.occupancy[2]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while bishops != 0 { + let from_sq = pop_lsb(&mut bishops); + let raw_move_map = self.get_pseudo_bishop_moves(from_sq) & move_mask; + let move_map = self.get_pin_masked_moves(raw_move_map, from_sq); + + let mut quiet_map = move_map & empty; + let mut capture_map = move_map & opponents; + + while quiet_map != 0 { + let to_sq = pop_lsb(&mut quiet_map); + quiet_buffer.add(BitMove::quiet( + from_sq as u8, + to_sq as u8, + None + )); + } + while capture_map != 0 { + let to_sq = pop_lsb(&mut capture_map); + capture_buffer.add(BitMove::capture( + from_sq as u8, + to_sq as u8, + None + )); + } + } + } +} \ No newline at end of file From 35cb1eeb738ccab727bc48c8178724e12b117512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:13:05 +0100 Subject: [PATCH 14/36] implemented move generation method for bishop capture moves --- engine/src/bitboard/movegen/bishops.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen/bishops.rs b/engine/src/bitboard/movegen/bishops.rs index c05a964..00f681b 100644 --- a/engine/src/bitboard/movegen/bishops.rs +++ b/engine/src/bitboard/movegen/bishops.rs @@ -33,4 +33,23 @@ impl Board { } } } + fn add_bishop_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut bishops: u64 = self.bitboards[2 + offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while bishops != 0 { + let next_sq: u32 = pop_lsb(&mut bishops); + let mut attacks: u64 = self.get_pseudo_bishop_moves(next_sq) & opponents & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + + while attacks != 0 { + let to_sq = pop_lsb(&mut attacks); + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + } + } } \ No newline at end of file From 9fb3d15beda85d5bffadf5fd4736d74c296247e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:14:31 +0100 Subject: [PATCH 15/36] added file and module structure for bitboard::movegen::rooks --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/rooks.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/rooks.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 1aba161..0664d7c 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -1,6 +1,7 @@ mod pawns; mod knights; mod bishops; +mod rooks; use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/rooks.rs b/engine/src/bitboard/movegen/rooks.rs new file mode 100644 index 0000000..9148c04 --- /dev/null +++ b/engine/src/bitboard/movegen/rooks.rs @@ -0,0 +1 @@ +use super::*; \ No newline at end of file From e896aba4ec4aa50707495ca258b877a20ac86cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:18:25 +0100 Subject: [PATCH 16/36] implemented general move generation method for rooks --- engine/src/bitboard/movegen/rooks.rs | 37 +++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/movegen/rooks.rs b/engine/src/bitboard/movegen/rooks.rs index 9148c04..f81f129 100644 --- a/engine/src/bitboard/movegen/rooks.rs +++ b/engine/src/bitboard/movegen/rooks.rs @@ -1 +1,36 @@ -use super::*; \ No newline at end of file +use super::*; + +impl Board { + + fn add_rook_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + let piece_index = 3 + self.side_to_move * 6; + let mut rooks = self.bitboards[piece_index as usize]; + let empty = !self.occupancy[2]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while rooks != 0 { + let from_sq = pop_lsb(&mut rooks); + let raw_move_map = self.get_pseudo_rook_moves(from_sq) & move_mask; + let move_map = self.get_pin_masked_moves(raw_move_map, from_sq); + + let mut quiet_map = move_map & empty; + let mut capture_map = move_map & opponents; + + while quiet_map != 0 { + let to_sq = pop_lsb(&mut quiet_map); + quiet_buffer.add(BitMove::quiet( + from_sq as u8, + to_sq as u8, + None + )); + } + while capture_map != 0 { + let to_sq = pop_lsb(&mut capture_map); + capture_buffer.add(BitMove::capture( + from_sq as u8, + to_sq as u8, + None + )); + } + } + } +} \ No newline at end of file From 0dd9a3d0473aedb83e093b9be9e5f89961d9a9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:23:14 +0100 Subject: [PATCH 17/36] implemented move generation method for rook capture moves --- engine/src/bitboard/movegen/rooks.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen/rooks.rs b/engine/src/bitboard/movegen/rooks.rs index f81f129..b908911 100644 --- a/engine/src/bitboard/movegen/rooks.rs +++ b/engine/src/bitboard/movegen/rooks.rs @@ -33,4 +33,23 @@ impl Board { } } } + fn add_rook_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut rooks: u64 = self.bitboards[3 + offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while rooks != 0 { + let next_sq: u32 = pop_lsb(&mut rooks); + let mut attacks: u64 = self.get_pseudo_rook_moves(next_sq) & opponents & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + + while attacks != 0 { + let to_sq = pop_lsb(&mut attacks); + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + } + } } \ No newline at end of file From a51d5e26525e9dc32b4a83b8f10eb9f8e2f88e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:24:40 +0100 Subject: [PATCH 18/36] added file and module structure for bitboard::movegen::queens --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/queens.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/queens.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 0664d7c..effeacc 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -2,6 +2,7 @@ mod pawns; mod knights; mod bishops; mod rooks; +mod queens; use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/queens.rs b/engine/src/bitboard/movegen/queens.rs new file mode 100644 index 0000000..9148c04 --- /dev/null +++ b/engine/src/bitboard/movegen/queens.rs @@ -0,0 +1 @@ +use super::*; \ No newline at end of file From 9fa298ed5185e73e4662917360232735e2832cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:26:16 +0100 Subject: [PATCH 19/36] implemented general move generation method for queens --- engine/src/bitboard/movegen/queens.rs | 37 ++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/movegen/queens.rs b/engine/src/bitboard/movegen/queens.rs index 9148c04..95951a8 100644 --- a/engine/src/bitboard/movegen/queens.rs +++ b/engine/src/bitboard/movegen/queens.rs @@ -1 +1,36 @@ -use super::*; \ No newline at end of file +use super::*; + +impl Board { + + fn add_queen_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + let piece_index = 4 + self.side_to_move * 6; + let mut queens = self.bitboards[piece_index as usize]; + let empty = !self.occupancy[2]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while queens != 0 { + let from_sq = pop_lsb(&mut queens); + let raw_move_map = self.get_pseudo_queen_moves(from_sq) & move_mask; + let move_map = self.get_pin_masked_moves(raw_move_map, from_sq); + + let mut quiet_map = move_map & empty; + let mut capture_map = move_map & opponents; + + while quiet_map != 0 { + let to_sq = pop_lsb(&mut quiet_map); + quiet_buffer.add(BitMove::quiet( + from_sq as u8, + to_sq as u8, + None + )); + } + while capture_map != 0 { + let to_sq = pop_lsb(&mut capture_map); + capture_buffer.add(BitMove::capture( + from_sq as u8, + to_sq as u8, + None + )); + } + } + } +} \ No newline at end of file From c2abc08206180b2259ed159ab34cbc408e7151b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:27:31 +0100 Subject: [PATCH 20/36] implemented move generation method for queen capture moves --- engine/src/bitboard/movegen/queens.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen/queens.rs b/engine/src/bitboard/movegen/queens.rs index 95951a8..6fdf4bd 100644 --- a/engine/src/bitboard/movegen/queens.rs +++ b/engine/src/bitboard/movegen/queens.rs @@ -33,4 +33,23 @@ impl Board { } } } + fn add_queen_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut queens: u64 = self.bitboards[4 + offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while queens != 0 { + let next_sq: u32 = pop_lsb(&mut queens); + let mut attacks: u64 = self.get_pseudo_queen_moves(next_sq) & opponents & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + + while attacks != 0 { + let to_sq = pop_lsb(&mut attacks); + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + } + } } \ No newline at end of file From e9f76634883e91ef64ea0a7ad3c544ec9ac10b26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:28:46 +0100 Subject: [PATCH 21/36] added file and module structure for bitboard::movegen::kings --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/kings.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/kings.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index effeacc..8f5a34a 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -3,6 +3,7 @@ mod knights; mod bishops; mod rooks; mod queens; +mod kings; use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs new file mode 100644 index 0000000..9148c04 --- /dev/null +++ b/engine/src/bitboard/movegen/kings.rs @@ -0,0 +1 @@ +use super::*; \ No newline at end of file From 21d26902f068b87c6537e88fafda7bba34285e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:33:58 +0100 Subject: [PATCH 22/36] implemented general move generation methdod for kings --- engine/src/bitboard/movegen/kings.rs | 36 +++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs index 9148c04..101ca04 100644 --- a/engine/src/bitboard/movegen/kings.rs +++ b/engine/src/bitboard/movegen/kings.rs @@ -1 +1,35 @@ -use super::*; \ No newline at end of file +use super::*; + +impl Board { + + fn add_king_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + let piece_index = 5 + self.side_to_move * 6; + let mut kings = self.bitboards[piece_index as usize]; + let empty = !self.occupancy[2]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while kings != 0 { + let from_sq = pop_lsb(&mut kings); + let move_map = self.get_pseudo_king_moves(from_sq) & move_mask; + + let mut quiet_map = move_map & empty; + let mut capture_map = move_map & opponents; + + while quiet_map != 0 { + let to_sq = pop_lsb(&mut quiet_map); + quiet_buffer.add(BitMove::quiet( + from_sq as u8, + to_sq as u8, + None + )); + } + while capture_map != 0 { + let to_sq = pop_lsb(&mut capture_map); + capture_buffer.add(BitMove::capture( + from_sq as u8, + to_sq as u8, + None + )); + } + } + } +} \ No newline at end of file From 5b3e84dab0d14efe7ed7f3f98eaf75c48dedb2e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:35:46 +0100 Subject: [PATCH 23/36] implemented move generation method or king capture moves --- engine/src/bitboard/movegen/kings.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs index 101ca04..883d082 100644 --- a/engine/src/bitboard/movegen/kings.rs +++ b/engine/src/bitboard/movegen/kings.rs @@ -32,4 +32,23 @@ impl Board { } } } + fn add_king_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut kings: u64 = self.bitboards[5 + offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while kings != 0 { + let next_sq: u32 = pop_lsb(&mut kings); + let mut attacks: u64 = self.get_pseudo_king_moves(next_sq) & opponents & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + + while attacks != 0 { + let to_sq = pop_lsb(&mut attacks); + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + } + } } \ No newline at end of file From 08ba7ee436ae1bcc212b21fa29264e70847495c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:41:20 +0100 Subject: [PATCH 24/36] implemented move generation method for castling moves --- engine/src/bitboard/attacks.rs | 25 ++++++++++++++++++++ engine/src/bitboard/movegen/kings.rs | 34 ++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/engine/src/bitboard/attacks.rs b/engine/src/bitboard/attacks.rs index a348d96..27c54e0 100644 --- a/engine/src/bitboard/attacks.rs +++ b/engine/src/bitboard/attacks.rs @@ -71,6 +71,31 @@ impl Board { pub fn get_pseudo_queen_moves(&self, sq: u32) -> u64 { return self.get_pseudo_bishop_moves(sq) | self.get_pseudo_rook_moves(sq); } + + #[inline] + pub fn is_square_attacked(&self, king_sq: u32) -> bool { + let offset: usize = 6 * self.side_to_move as usize; + + // rook-queen checks (+) + let mut threat_mask: u64 = self.get_pseudo_rook_moves(king_sq); + let mut attacker_mask: u64 = self.bitboards[10 - offset] | self.bitboards[9 - offset]; + if threat_mask & attacker_mask != 0 { return true; } + + // bishop-queen checks (x) + threat_mask = self.get_pseudo_bishop_moves(king_sq); + attacker_mask = self.bitboards[10 - offset] | self.bitboards[8 - offset]; + if threat_mask & attacker_mask != 0 { return true; } + + // knight checks (L) + threat_mask = KNIGHT_ATTACK_MAP[king_sq as usize]; + attacker_mask = self.bitboards[7 - offset]; + if threat_mask & attacker_mask != 0 { return true; } + + // pawn checks (v) + threat_mask = PAWN_ATTACK_MAP[king_sq as usize][self.side_to_move as usize]; + attacker_mask = self.bitboards[6 - offset]; + return threat_mask & attacker_mask != 0; + } } #[inline(always)] diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs index 883d082..18315e4 100644 --- a/engine/src/bitboard/movegen/kings.rs +++ b/engine/src/bitboard/movegen/kings.rs @@ -51,4 +51,38 @@ impl Board { } } } + fn add_king_castles(&self, buffer: &mut MoveBuffer, move_mask: u64) { + if self.castling_rights & (0b11 << (2 - 2 * self.side_to_move)) == 0 { + return; + } + + let offset = 5 + 6 * self.side_to_move as u8; + let castle_offset = 2 - 2 * self.side_to_move as u8; + let castling_rights = self.castling_rights & 3 << castle_offset; + let occupied = self.occupancy[2]; + let king_sq = self.bitboards[offset as usize].trailing_zeros(); + + let queenside_mask = 0b111 << (king_sq - 3); + let kingside_mask = 0b11 << (king_sq + 1); + + if (castling_rights & 1 << castle_offset) != 0 + && queenside_mask & occupied == 0 + && !move_mask & 0b11 << (king_sq - 2) == 0 + && !self.is_square_attacked(king_sq - 2) { + buffer.add(BitMove::castle( + king_sq as u8, + (king_sq - 2) as u8 + )); + } + if (castling_rights & 2 << castle_offset) != 0 + && kingside_mask & occupied == 0 + && !move_mask & 0b11 << (king_sq + 1) == 0 + && !self.is_square_attacked(king_sq + 2) { + buffer.add(BitMove::castle( + king_sq as u8, + (king_sq + 2) as u8 + )); + } + + } } \ No newline at end of file From 33ca535547244128714321dec217e372ea0ad350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:21:28 +0100 Subject: [PATCH 25/36] added LUT ROOK_MOVE_MASK in bitboard::attackmaps for king safety checks --- engine/src/bitboard/attackmaps.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/engine/src/bitboard/attackmaps.rs b/engine/src/bitboard/attackmaps.rs index f7fe35f..51b150c 100644 --- a/engine/src/bitboard/attackmaps.rs +++ b/engine/src/bitboard/attackmaps.rs @@ -94,6 +94,17 @@ pub static RAY_TABLE: Lazy<[[u64; 8]; 64]> = Lazy::new(|| { return table; }); +pub static ROOK_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { + let mut table = [0u64; 64]; + + for sq in 0..64 { + for dir in [0, 2, 4, 6] { + table[sq] |= RAY_TABLE[sq][dir]; + } + } + table +}); + // <----- TESTS -----> From 71ea2a05d0185c15fa6f0ed3c48a9920967cac0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:22:08 +0100 Subject: [PATCH 26/36] added LUT BISHOP_MOVE_MASK in bitboard::attackmaps for king safety checks --- engine/src/bitboard/attackmaps.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/engine/src/bitboard/attackmaps.rs b/engine/src/bitboard/attackmaps.rs index 51b150c..f581113 100644 --- a/engine/src/bitboard/attackmaps.rs +++ b/engine/src/bitboard/attackmaps.rs @@ -105,6 +105,17 @@ pub static ROOK_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { table }); +pub static BISHOP_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { + let mut table = [0u64; 64]; + + for sq in 0..64 { + for dir in [1, 3, 5, 7] { + table[sq] |= RAY_TABLE[sq][dir]; + } + } + table +}); + // <----- TESTS -----> From d8eae9177b79153f01dbec6d66224dd82d7462aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:23:40 +0100 Subject: [PATCH 27/36] added LUT KING_SAFETY_ROOK_MASK in bitboard::attackmaps for king safety checks --- engine/src/bitboard/attackmaps.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/engine/src/bitboard/attackmaps.rs b/engine/src/bitboard/attackmaps.rs index f581113..016719d 100644 --- a/engine/src/bitboard/attackmaps.rs +++ b/engine/src/bitboard/attackmaps.rs @@ -94,6 +94,7 @@ pub static RAY_TABLE: Lazy<[[u64; 8]; 64]> = Lazy::new(|| { return table; }); +// ROOK_MOVE_MASK[] pub static ROOK_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { let mut table = [0u64; 64]; @@ -105,6 +106,7 @@ pub static ROOK_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { table }); +// BISHOP_MOVE_MASK[] pub static BISHOP_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { let mut table = [0u64; 64]; @@ -116,6 +118,22 @@ pub static BISHOP_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { table }); +pub static KING_SAFETY_ROOK_MASK: Lazy<[u64; 64]> = Lazy::new(|| { + let mut table = [0u64; 64]; + + for sq in 0..64 { + let mut mask = KING_ATTACK_MAP[sq]; + + while mask != 0 { + let next_sq = mask.trailing_zeros(); + table[sq] |= ROOK_MOVE_MASK[next_sq as usize]; + mask &= !(1 << next_sq); + } + } + + table +}); + // <----- TESTS -----> From 8c0fa09f1ea755f33eded79cfe4f919895627490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:25:14 +0100 Subject: [PATCH 28/36] added LUT KING_SAFETY_BISHOP_MASK in bitboard::attackmaps for king safety checks --- engine/src/bitboard/attackmaps.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/engine/src/bitboard/attackmaps.rs b/engine/src/bitboard/attackmaps.rs index 016719d..b99a4db 100644 --- a/engine/src/bitboard/attackmaps.rs +++ b/engine/src/bitboard/attackmaps.rs @@ -118,6 +118,7 @@ pub static BISHOP_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { table }); +// KING_SAFETY_ROOK_MASK[] pub static KING_SAFETY_ROOK_MASK: Lazy<[u64; 64]> = Lazy::new(|| { let mut table = [0u64; 64]; @@ -134,6 +135,23 @@ pub static KING_SAFETY_ROOK_MASK: Lazy<[u64; 64]> = Lazy::new(|| { table }); +// KING_SAFETY_BISHOP_MASK[] +pub static KING_SAFETY_BISHOP_MASK: Lazy<[u64; 64]> = Lazy::new(|| { + let mut table = [0u64; 64]; + + for sq in 0..64 { + let mut mask = KING_ATTACK_MAP[sq]; + + while mask != 0 { + let next_sq = mask.trailing_zeros(); + table[sq] |= BISHOP_MOVE_MASK[next_sq as usize]; + mask &= !(1 << next_sq); + } + } + + table +}); + // <----- TESTS -----> From 1bbe33f3aa50ebd50f45a521645a19d294e2c00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:28:16 +0100 Subject: [PATCH 29/36] added method get_pseudo_bishop_moves_ignore_king in bitboard::attacks for king safety checks --- engine/src/bitboard/attacks.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/engine/src/bitboard/attacks.rs b/engine/src/bitboard/attacks.rs index 27c54e0..cd547d4 100644 --- a/engine/src/bitboard/attacks.rs +++ b/engine/src/bitboard/attacks.rs @@ -72,6 +72,21 @@ impl Board { return self.get_pseudo_bishop_moves(sq) | self.get_pseudo_rook_moves(sq); } + #[inline] + pub fn get_pseudo_bishop_moves_ignore_king(&self, sq: u32) -> u64 { + let mut moves = 0u64; + let sq = sq as usize; + let king = self.bitboards[5 + 6*self.side_to_move as usize]; + let occupancy = self.occupancy[2] & !king; + moves |= get_raycast_from_square_in_direction(occupancy, sq, 1); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 3); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 5); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 7); + + return moves; + } + + #[inline] pub fn is_square_attacked(&self, king_sq: u32) -> bool { let offset: usize = 6 * self.side_to_move as usize; From 47a22dbbaa3d5d21005718702fcd0d6d0331d78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:29:27 +0100 Subject: [PATCH 30/36] added method get_pseudo_rook_moves_ignore_king in bitboard::attacks for king safety checks --- engine/src/bitboard/attacks.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/engine/src/bitboard/attacks.rs b/engine/src/bitboard/attacks.rs index cd547d4..2e1e655 100644 --- a/engine/src/bitboard/attacks.rs +++ b/engine/src/bitboard/attacks.rs @@ -85,7 +85,19 @@ impl Board { return moves; } + #[inline] + pub fn get_pseudo_rook_moves_ignore_king(&self, sq: u32) -> u64 { + let mut moves: u64 = 0u64; + let sq = sq as usize; + let king = self.bitboards[5 + 6*self.side_to_move as usize]; + let occupancy = self.occupancy[2] & !king; + moves |= get_raycast_from_square_in_direction(occupancy, sq, 0); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 2); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 4); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 6); + return moves; + } #[inline] pub fn is_square_attacked(&self, king_sq: u32) -> bool { From dba7aca2cfada34d44a8cf9f7fce6390df347dc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:35:44 +0100 Subject: [PATCH 31/36] added method get_safe_king_squares to bitboard::attacks for king safety checks --- engine/src/bitboard/attacks.rs | 55 ++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/engine/src/bitboard/attacks.rs b/engine/src/bitboard/attacks.rs index 2e1e655..63b0c32 100644 --- a/engine/src/bitboard/attacks.rs +++ b/engine/src/bitboard/attacks.rs @@ -5,6 +5,8 @@ impl Board { const RANK_2: u64 = 0x0000_0000_0000_FF00; const RANK_7: u64 = 0x00FF_0000_0000_0000; + const A_FILE: u64 = 0x0101_0101_0101_0101; + const H_FILE: u64 = 0x8080_8080_8080_8080; pub fn get_pseudo_pawn_moves(&self, sq: u32) -> u64 { let pawn: u64 = 1 << sq; @@ -123,6 +125,59 @@ impl Board { attacker_mask = self.bitboards[6 - offset]; return threat_mask & attacker_mask != 0; } + pub fn get_safe_king_squares(&self) -> u64 { + let offset: usize = 6 * (1 - self.side_to_move as usize); + let king_sq = self.bitboards[11 - offset].trailing_zeros() as usize; + let bishop_mask = KING_SAFETY_BISHOP_MASK[king_sq]; + let rook_mask = KING_SAFETY_ROOK_MASK[king_sq]; + let mut attack_map: u64 = 0u64; + + let mut board: u64 = self.bitboards[offset]; + if self.side_to_move() == 0 { + attack_map |= (board >> 9 & !Self::H_FILE) | (board >> 7 & !Self::A_FILE); + } + else { + attack_map |= (board << 9 & !Self::A_FILE) | (board << 7 & !Self::H_FILE); + } + + board = self.bitboards[offset + 1]; + while board != 0 { + let piece_sq: u32 = board.trailing_zeros(); + board &= !(1 << piece_sq); + + attack_map |= self.get_pseudo_knight_moves(piece_sq); + } + + board = self.bitboards[offset + 2] & bishop_mask; + while board != 0 { + let piece_sq: u32 = board.trailing_zeros(); + board &= !(1 << piece_sq); + + attack_map |= self.get_pseudo_bishop_moves_ignore_king(piece_sq); + } + + board = self.bitboards[offset + 3] & rook_mask; + while board != 0 { + let piece_sq: u32 = board.trailing_zeros(); + board &= !(1 << piece_sq); + + attack_map |= self.get_pseudo_rook_moves_ignore_king(piece_sq); + } + + board = self.bitboards[offset + 4] & (bishop_mask | rook_mask); + while board != 0 { + let piece_sq: u32 = board.trailing_zeros(); + board &= !(1 << piece_sq); + + attack_map |= self.get_pseudo_rook_moves_ignore_king(piece_sq) | self.get_pseudo_bishop_moves_ignore_king(piece_sq); + } + + board = self.bitboards[offset + 5]; + let piece_sq: u32 = board.trailing_zeros(); + attack_map |= self.get_pseudo_king_moves(piece_sq); + + return !attack_map; + } } #[inline(always)] From 9b43c9ce9a9db5756a5d4b432d43d8bf6b36c1c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:39:47 +0100 Subject: [PATCH 32/36] implemented method collect_all_moves in bitboard::movegen used in move generation --- engine/src/bitboard/movegen.rs | 19 ++++++++++++++++++- engine/src/bitboard/movegen/bishops.rs | 4 ++-- engine/src/bitboard/movegen/kings.rs | 6 +++--- engine/src/bitboard/movegen/knights.rs | 4 ++-- engine/src/bitboard/movegen/pawns.rs | 6 +++--- engine/src/bitboard/movegen/queens.rs | 4 ++-- engine/src/bitboard/movegen/rooks.rs | 4 ++-- 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 8f5a34a..76bc395 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -12,17 +12,34 @@ use super::utils::*; impl Board { + const NO_FILTER: u64 = 0xFFFF_FFFF_FFFF_FFFF; + pub fn collect_moves(&mut self, buffer: &mut MoveBuffer, temp_buffer: &mut MoveBuffer) -> bool { buffer.clear(); self.calc_pinned_squares(); let check_info = self.check_test(); match check_info.check_count { - // 0 => self.collect_all_moves(), + 0 => self.collect_all_moves(buffer, temp_buffer), // 1 => self.collect_moves_single_check(), // 2 => self.collect_king_evasion(), _ => panic!("More than 2 checking pieces found as the same time!") } return check_info.check_count > 0; } + + pub(in super) fn collect_all_moves(&self, buffer: &mut MoveBuffer, temp_buffer: &mut MoveBuffer) { + let safe_squares = self.get_safe_king_squares(); + + self.add_pawn_moves(buffer, temp_buffer, Self::NO_FILTER); + self.add_knight_moves(buffer, temp_buffer, Self::NO_FILTER); + self.add_bishop_moves(buffer, temp_buffer, Self::NO_FILTER); + self.add_rook_moves(buffer, temp_buffer, Self::NO_FILTER); + self.add_queen_moves(buffer, temp_buffer, Self::NO_FILTER); + self.add_king_moves(buffer, temp_buffer, safe_squares); + self.add_king_castles(buffer, safe_squares); + + buffer.append(temp_buffer); + temp_buffer.clear(); + } } \ No newline at end of file diff --git a/engine/src/bitboard/movegen/bishops.rs b/engine/src/bitboard/movegen/bishops.rs index 00f681b..3d41916 100644 --- a/engine/src/bitboard/movegen/bishops.rs +++ b/engine/src/bitboard/movegen/bishops.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_bishop_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_bishop_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { let piece_index = 2 + self.side_to_move * 6; let mut bishops = self.bitboards[piece_index as usize]; let empty = !self.occupancy[2]; @@ -33,7 +33,7 @@ impl Board { } } } - fn add_bishop_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_bishop_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut bishops: u64 = self.bitboards[2 + offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs index 18315e4..60e7daf 100644 --- a/engine/src/bitboard/movegen/kings.rs +++ b/engine/src/bitboard/movegen/kings.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_king_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_king_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { let piece_index = 5 + self.side_to_move * 6; let mut kings = self.bitboards[piece_index as usize]; let empty = !self.occupancy[2]; @@ -32,7 +32,7 @@ impl Board { } } } - fn add_king_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_king_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut kings: u64 = self.bitboards[5 + offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; @@ -51,7 +51,7 @@ impl Board { } } } - fn add_king_castles(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_king_castles(&self, buffer: &mut MoveBuffer, move_mask: u64) { if self.castling_rights & (0b11 << (2 - 2 * self.side_to_move)) == 0 { return; } diff --git a/engine/src/bitboard/movegen/knights.rs b/engine/src/bitboard/movegen/knights.rs index db4a105..4c0efce 100644 --- a/engine/src/bitboard/movegen/knights.rs +++ b/engine/src/bitboard/movegen/knights.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_knight_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_knight_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { let piece_index = 1 + self.side_to_move * 6; let mut knights = self.bitboards[piece_index as usize]; let empty = !self.occupancy[2]; @@ -33,7 +33,7 @@ impl Board { } } } - fn add_knight_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_knight_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut knights: u64 = self.bitboards[1 + offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index 6e9e1dc..9fc7571 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_pawn_quiets(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_pawn_quiets(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset: u8 = self.side_to_move * 6; let mut pawns: u64 = self.bitboards[offset as usize]; while pawns != 0 { @@ -34,7 +34,7 @@ impl Board { } } } - fn add_pawn_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_pawn_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut pawns: u64 = self.bitboards[offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; @@ -69,7 +69,7 @@ impl Board { } } } - fn add_pawn_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_pawn_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { self.add_pawn_captures(capture_buffer, move_mask); self.add_pawn_quiets(quiet_buffer, move_mask); } diff --git a/engine/src/bitboard/movegen/queens.rs b/engine/src/bitboard/movegen/queens.rs index 6fdf4bd..960f49a 100644 --- a/engine/src/bitboard/movegen/queens.rs +++ b/engine/src/bitboard/movegen/queens.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_queen_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_queen_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { let piece_index = 4 + self.side_to_move * 6; let mut queens = self.bitboards[piece_index as usize]; let empty = !self.occupancy[2]; @@ -33,7 +33,7 @@ impl Board { } } } - fn add_queen_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_queen_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut queens: u64 = self.bitboards[4 + offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; diff --git a/engine/src/bitboard/movegen/rooks.rs b/engine/src/bitboard/movegen/rooks.rs index b908911..749e2d8 100644 --- a/engine/src/bitboard/movegen/rooks.rs +++ b/engine/src/bitboard/movegen/rooks.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_rook_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_rook_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { let piece_index = 3 + self.side_to_move * 6; let mut rooks = self.bitboards[piece_index as usize]; let empty = !self.occupancy[2]; @@ -33,7 +33,7 @@ impl Board { } } } - fn add_rook_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_rook_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut rooks: u64 = self.bitboards[3 + offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; From fad1a6d51b4644b6a58d7ca02b2ec9adbb5ddf60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:42:44 +0100 Subject: [PATCH 33/36] implemented method collect_moves_single_check in bitboard::movegen used in move generation --- engine/src/bitboard/movegen.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 76bc395..5e5ca3c 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -8,6 +8,7 @@ mod kings; use super::board::Board; use super::movebuffer::MoveBuffer; use super::bitmove::BitMove; +use super::checkinfo::CheckInfo; use super::utils::*; impl Board { @@ -39,6 +40,19 @@ impl Board { self.add_king_moves(buffer, temp_buffer, safe_squares); self.add_king_castles(buffer, safe_squares); + buffer.append(temp_buffer); + temp_buffer.clear(); + } + pub(in super) fn collect_moves_single_check(&self, buffer: &mut MoveBuffer, temp_buffer: &mut MoveBuffer, check_info: &CheckInfo) { + let safe_squares = self.get_safe_king_squares(); + + self.add_pawn_moves(buffer, temp_buffer, check_info.move_mask); + self.add_knight_moves(buffer, temp_buffer, check_info.move_mask); + self.add_bishop_moves(buffer, temp_buffer, check_info.move_mask); + self.add_rook_moves(buffer, temp_buffer, check_info.move_mask); + self.add_queen_moves(buffer, temp_buffer, check_info.move_mask); + self.add_king_moves(buffer, temp_buffer, safe_squares); + buffer.append(temp_buffer); temp_buffer.clear(); } From f3d316d3e3b43794e48c9a0259c2d258206f0276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:43:35 +0100 Subject: [PATCH 34/36] implemented method collect_king_evasion in bitboard::movegen used in move generation --- engine/src/bitboard/movegen.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 5e5ca3c..2e5e6a7 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -56,4 +56,12 @@ impl Board { buffer.append(temp_buffer); temp_buffer.clear(); } + pub(in super) fn collect_king_evasion(&self, buffer: &mut MoveBuffer, temp_buffer: &mut MoveBuffer) { + let safe_squares = self.get_safe_king_squares(); + + self.add_king_moves(buffer, temp_buffer, safe_squares); + + buffer.append(&temp_buffer); + temp_buffer.clear(); + } } \ No newline at end of file From 84121fbeba83228511f828d01ca7af188efae527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:45:26 +0100 Subject: [PATCH 35/36] allowed use of move generation methods in case of check --- engine/src/bitboard/movegen.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 2e5e6a7..b702f4a 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -22,8 +22,8 @@ impl Board { match check_info.check_count { 0 => self.collect_all_moves(buffer, temp_buffer), - // 1 => self.collect_moves_single_check(), - // 2 => self.collect_king_evasion(), + 1 => self.collect_moves_single_check(buffer, temp_buffer, &check_info), + 2 => self.collect_king_evasion(buffer, temp_buffer), _ => panic!("More than 2 checking pieces found as the same time!") } return check_info.check_count > 0; From 775083fde7ef482efcae5b5703088e517aaf1f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 21:11:41 +0100 Subject: [PATCH 36/36] fixed wrong promotion_piece indexes being saved in bitboard::movegen::pawns --- engine/src/bitboard/movegen/pawns.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index 9fc7571..444b387 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -15,7 +15,7 @@ impl Board { if (self.side_to_move == 0 && quiets.trailing_zeros() / 8 == 7) || (self.side_to_move == 1 && quiets.trailing_zeros() / 8 == 0) { - for piece_type in [3, 2, 1, 0] { + for piece_type in [4, 3, 2, 1] { buffer.add(BitMove::quiet( next_sq as u8, to_sq as u8, @@ -50,7 +50,7 @@ impl Board { if (self.side_to_move == 0 && attacks.trailing_zeros() / 8 == 7) || (self.side_to_move == 1 && attacks.trailing_zeros() / 8 == 0) { - for piece_type in [3, 2, 1, 0] { + for piece_type in [4, 3, 2, 1] { buffer.add(BitMove::capture( next_sq as u8, to_sq as u8,