From 3332cdcb0d7c48e0bdeb8b2f1dad32b3bd0e5dc5 Mon Sep 17 00:00:00 2001 From: Michael Whiteley Date: Thu, 28 May 2026 13:39:36 -0600 Subject: [PATCH 1/2] Add debug assert and formatting in validate_en_passant. bench 2756239 --- src/board.rs | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/board.rs b/src/board.rs index 8d28e35e7..6b419d25c 100644 --- a/src/board.rs +++ b/src/board.rs @@ -498,29 +498,28 @@ impl Board { /// We verify is self.state.enpassant is valid, and remove it if it is not. /// This must be called after pinners and checkers have been updated. fn validate_en_passant(&mut self) { - if self.en_passant() == Square::None { - return; - } - - let stm = self.side_to_move(); - let king = self.king_square(stm); - let pushed_pawn = self.en_passant() ^ 8; - let ep_occ = self.occupancies() ^ self.en_passant().to_bb() ^ pushed_pawn.to_bb(); - - let attackers = pawn_attacks(self.en_passant(), !stm) & self.colored_pieces(stm, PieceType::Pawn); - - for attacker in attackers { - let occ = ep_occ ^ attacker.to_bb(); - let slide_attackers = (rook_attacks(king, occ) & self.pieces2(PieceType::Rook, PieceType::Queen)) - | (bishop_attacks(king, occ) & self.pieces2(PieceType::Bishop, PieceType::Queen)); - - if (slide_attackers & self.colors(!stm)).is_empty() { - return; + debug_assert!(!self.all_threats().is_empty()); + + let ep = self.en_passant(); + if ep != Square::None { + let stm = self.side_to_move(); + let king = self.king_square(stm); + let ep_occ = self.occupancies() ^ ep.to_bb() ^ (ep ^ 8).to_bb(); + let ep_takers = pawn_attacks(ep, !stm) & self.colored_pieces(stm, PieceType::Pawn); + + for ep_taker in ep_takers { + let occ = ep_occ ^ ep_taker.to_bb(); + let checkers = (rook_attacks(king, occ) & self.pieces2(PieceType::Rook, PieceType::Queen)) + | (bishop_attacks(king, occ) & self.pieces2(PieceType::Bishop, PieceType::Queen)); + + if (checkers & self.colors(!stm)).is_empty() { + return; //ep capture is allowed + } } - } - self.state.keys.toggle_en_passant(self.en_passant()); - self.state.en_passant = Square::None; + self.state.keys.toggle_en_passant(ep); + self.state.en_passant = Square::None; + } } pub fn get_castling_rook(&self, king_to: Square) -> (Square, Square) { From 657f7d7ae11dcd497bed8a56d5e7ba7f49d758bd Mon Sep 17 00:00:00 2001 From: Arseniy Surkov <93079612+codedeliveryservice@users.noreply.github.com> Date: Sat, 30 May 2026 12:49:09 +0300 Subject: [PATCH 2/2] revert early return Bench: 2756239 --- src/board.rs | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/board.rs b/src/board.rs index 6b419d25c..deb7e82e5 100644 --- a/src/board.rs +++ b/src/board.rs @@ -501,25 +501,28 @@ impl Board { debug_assert!(!self.all_threats().is_empty()); let ep = self.en_passant(); - if ep != Square::None { - let stm = self.side_to_move(); - let king = self.king_square(stm); - let ep_occ = self.occupancies() ^ ep.to_bb() ^ (ep ^ 8).to_bb(); - let ep_takers = pawn_attacks(ep, !stm) & self.colored_pieces(stm, PieceType::Pawn); - - for ep_taker in ep_takers { - let occ = ep_occ ^ ep_taker.to_bb(); - let checkers = (rook_attacks(king, occ) & self.pieces2(PieceType::Rook, PieceType::Queen)) - | (bishop_attacks(king, occ) & self.pieces2(PieceType::Bishop, PieceType::Queen)); - - if (checkers & self.colors(!stm)).is_empty() { - return; //ep capture is allowed - } - } + if ep == Square::None { + return; + } - self.state.keys.toggle_en_passant(ep); - self.state.en_passant = Square::None; + let stm = self.side_to_move(); + let king = self.king_square(stm); + let ep_occ = self.occupancies() ^ ep.to_bb() ^ (ep ^ 8).to_bb(); + let ep_takers = pawn_attacks(ep, !stm) & self.colored_pieces(stm, PieceType::Pawn); + + for ep_taker in ep_takers { + let occ = ep_occ ^ ep_taker.to_bb(); + let checkers = (rook_attacks(king, occ) & self.pieces2(PieceType::Rook, PieceType::Queen)) + | (bishop_attacks(king, occ) & self.pieces2(PieceType::Bishop, PieceType::Queen)); + + if (checkers & self.colors(!stm)).is_empty() { + // En passant capture is allowed + return; + } } + + self.state.keys.toggle_en_passant(ep); + self.state.en_passant = Square::None; } pub fn get_castling_rook(&self, king_to: Square) -> (Square, Square) {