From bc0422a53ef106a60ff7a93d463a494e3be1b8cd Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Thu, 18 Dec 2025 00:04:41 +0100 Subject: [PATCH] wip: update MoveGen --- src/moves.rs | 12 +++++------- src/position.rs | 39 ++++++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/moves.rs b/src/moves.rs index 335b734..0567d5c 100644 --- a/src/moves.rs +++ b/src/moves.rs @@ -223,17 +223,15 @@ pub struct Moves<'l> { impl<'l> MoveGen for Moves<'l> { #[inline] - fn is_check(&mut self) -> ControlFlow { - self.is_check = true; - ControlFlow::Continue(()) - } - #[inline] - fn en_passant_is_legal(&mut self) -> ControlFlow { - self.en_passant_is_legal = true; + fn checkers(&mut self, b: Bitboard) -> ControlFlow { + self.is_check = !b.is_empty(); ControlFlow::Continue(()) } #[inline] fn extend(&mut self, s: MoveSet) -> ControlFlow { + if let MoveSet::EnPassant { .. } = s { + self.en_passant_is_legal = true; + } s.for_each(|raw| unsafe { self.array.push_unchecked(raw) }); ControlFlow::Continue(()) } diff --git a/src/position.rs b/src/position.rs index f6a3f64..9967257 100644 --- a/src/position.rs +++ b/src/position.rs @@ -130,8 +130,10 @@ impl Position { /// Returns `true` if the king is in check. #[must_use] pub fn is_check(&self) -> bool { - struct MoveGenImpl; - impl MoveGen<()> for MoveGenImpl { + struct MoveGenImpl { + checkers: Bitboard, + } + impl MoveGen for MoveGenImpl { #[inline] fn roles(&self, _role: Role) -> bool { false @@ -145,11 +147,16 @@ impl Position { Bitboard::new() } #[inline] - fn is_check(&mut self) -> ControlFlow<()> { - ControlFlow::Break(()) + fn checkers(&mut self, b: Bitboard) -> ControlFlow { + self.checkers = b; + ControlFlow::Continue(()) } } - self.generate_moves(&mut MoveGenImpl).is_break() + let mut acc = MoveGenImpl { + checkers: Bitboard::new(), + }; + let ControlFlow::Continue(()) = self.generate_moves(&mut acc); + !acc.checkers.is_empty() } /// Returns `true` if there is no legal move on the position. @@ -184,8 +191,11 @@ impl Position { self.to } #[inline] - fn en_passant_is_legal(&mut self) -> ControlFlow<()> { - ControlFlow::Break(()) + fn extend(&mut self, s: MoveSet) -> ControlFlow<()> { + match s { + MoveSet::EnPassant { .. } => ControlFlow::Break(()), + _ => ControlFlow::Continue(()), + } } } let mut moves = MoveGenImpl { @@ -761,11 +771,7 @@ pub(crate) trait MoveGen { } #[inline] - fn is_check(&mut self) -> ControlFlow { - ControlFlow::Continue(()) - } - #[inline] - fn en_passant_is_legal(&mut self) -> ControlFlow { + fn checkers(&mut self, _b: Bitboard) -> ControlFlow { ControlFlow::Continue(()) } #[inline] @@ -829,6 +835,8 @@ impl Position { | x & theirs.bishop() | y & theirs.rook(); + moves.checkers(checkers)?; + if moves.roles(Role::King) && global_mask_from.contains(king_square) { let attacked = { let blockers = blockers ^ ours.king(); @@ -887,7 +895,6 @@ impl Position { } if checkers.len() > 1 { - moves.is_check()?; return ControlFlow::Continue(()); } @@ -971,7 +978,6 @@ impl Position { & candidates & (!pinned | lookup::segment(king_square, to)) { - moves.en_passant_is_legal()?; moves.extend(MoveSet::EnPassant { from, to })?; } } @@ -1006,7 +1012,6 @@ impl Position { } if checker.is_some() { - moves.is_check()?; return ControlFlow::Continue(()); } @@ -1233,8 +1238,8 @@ impl MateMoveGenImpl { } impl MoveGen for MateMoveGenImpl { #[inline] - fn is_check(&mut self) -> ControlFlow { - self.is_check = true; + fn checkers(&mut self, b: Bitboard) -> ControlFlow { + self.is_check = !b.is_empty(); ControlFlow::Continue(()) } #[inline]