From a6a00fc8192a91f0ac0e9baac6468570958c1d5b Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Wed, 22 Oct 2025 22:59:53 +0200 Subject: [PATCH] misc --- src/board.rs | 26 ++++---- src/position.rs | 155 ++++++++++++++++++++++++------------------------ src/setup.rs | 10 ++-- 3 files changed, 97 insertions(+), 94 deletions(-) diff --git a/src/board.rs b/src/board.rs index db22a3d..d84ba43 100644 --- a/src/board.rs +++ b/src/board.rs @@ -194,7 +194,7 @@ impl Rank { #[inline] pub fn mirror(self) -> Self { - unsafe { Self::transmute(7_u8.unchecked_sub(self as u8)) } + unsafe { Self::transmute(!(self as u8)) } } #[inline] @@ -263,7 +263,7 @@ impl Square { #[inline] pub fn new(file: File, rank: Rank) -> Self { - unsafe { Self::transmute(((rank as u8) << 3) + file as u8) } + unsafe { Self::transmute(((rank as u8) << 3) | file as u8) } } #[inline] @@ -278,7 +278,8 @@ impl Square { #[inline] pub fn mirror(self) -> Self { - Self::new(self.file(), self.rank().mirror()) + let sq = self as u8; + unsafe { Self::transmute(sq & 0b000111 | (!sq & 0b111000)) } } #[inline] @@ -389,18 +390,19 @@ impl std::str::FromStr for Square { } } +#[rustfmt::skip] +#[allow(unused)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(u8)] -#[rustfmt::skip] pub(crate) enum OptionSquare { - _A1, _B1, _C1, _D1, _E1, _F1, _G1, _H1, - _A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2, - _A3, _B3, _C3, _D3, _E3, _F3, _G3, _H3, - _A4, _B4, _C4, _D4, _E4, _F4, _G4, _H4, - _A5, _B5, _C5, _D5, _E5, _F5, _G5, _H5, - _A6, _B6, _C6, _D6, _E6, _F6, _G6, _H6, - _A7, _B7, _C7, _D7, _E7, _F7, _G7, _H7, - _A8, _B8, _C8, _D8, _E8, _F8, _G8, _H8, + A1, B1, C1, D1, E1, F1, G1, H1, + A2, B2, C2, D2, E2, F2, G2, H2, + A3, B3, C3, D3, E3, F3, G3, H3, + A4, B4, C4, D4, E4, F4, G4, H4, + A5, B5, C5, D5, E5, F5, G5, H5, + A6, B6, C6, D6, E6, F6, G6, H6, + A7, B7, C7, D7, E7, F7, G7, H7, + A8, B8, C8, D8, E8, F8, G8, H8, None, } diff --git a/src/position.rs b/src/position.rs index 8e227fb..d060e97 100644 --- a/src/position.rs +++ b/src/position.rs @@ -62,14 +62,6 @@ pub struct Position { const MAX_LEGAL_MOVES: usize = 218; -impl std::fmt::Debug for Position { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - f.debug_tuple("Position") - .field(&self.as_setup().to_string()) - .finish() - } -} - impl Position { /// Returns the initial position of a chess game. /// @@ -484,6 +476,14 @@ impl Position { } } +impl std::fmt::Debug for Position { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + f.debug_tuple("Position") + .field(&self.as_setup().to_string()) + .finish() + } +} + /// A legal move. #[derive(Clone, Copy)] pub struct Move<'l> { @@ -657,7 +657,7 @@ impl<'l> Move<'l> { }, suffix: { let pos = self.make(); - let mut visitor = MateCollector::new(); + let mut visitor = MateVisitorImpl::new(); pos.generate_moves(&mut visitor); visitor.is_check.then(|| match visitor.is_mate { true => SanSuffix::Checkmate, @@ -976,11 +976,6 @@ impl Position { | d.knight(king_square) & theirs.knight() | x & theirs.bishop() | y & theirs.rook(); - let blockers_x_ray = blockers & !(x | y); - let pinned = (d.bishop(king_square, blockers_x_ray) & theirs.bishop() - | d.rook(king_square, blockers_x_ray) & theirs.rook()) - .map(|sq| d.segment(king_square, sq)) - .reduce_or(); if visitor.roles(Role::King) && global_mask_from.contains(king_square) { let attacked = { @@ -1058,6 +1053,12 @@ impl Position { return; } + let blockers_x_ray = blockers & !(x | y); + let pinned = (d.bishop(king_square, blockers_x_ray) & theirs.bishop() + | d.rook(king_square, blockers_x_ray) & theirs.rook()) + .map(|sq| d.segment(king_square, sq)) + .reduce_or(); + let checker = checkers.first(); let block_check = checker .map(|checker| d.segment(king_square, checker)) @@ -1091,7 +1092,7 @@ impl Position { to, role: Role::Pawn, })); - visitor.moves(WithPromotion::new((targets & promotion).map(|to| { + visitor.moves(MoveAndPromote::new((targets & promotion).map(|to| { RawMove { kind: MoveType::PawnAdvancePromotion, from: unsafe { to.trans_unchecked(!forward) }, @@ -1113,7 +1114,7 @@ impl Position { to, role: Role::Pawn, })); - visitor.moves(WithPromotion::new((targets & promotion).map(|to| { + visitor.moves(MoveAndPromote::new((targets & promotion).map(|to| { RawMove { kind: MoveType::PawnAttackPromotion, from: unsafe { to.trans_unchecked(!kside) }, @@ -1135,7 +1136,7 @@ impl Position { to, role: Role::Pawn, })); - visitor.moves(WithPromotion::new((targets & promotion).map(|to| { + visitor.moves(MoveAndPromote::new((targets & promotion).map(|to| { RawMove { kind: MoveType::PawnAttackPromotion, from: unsafe { to.trans_unchecked(!qside) }, @@ -1295,63 +1296,6 @@ impl Position { } } -struct WithPromotion + ExactSizeIterator + FusedIterator> { - inner: I, - cur: std::mem::MaybeUninit, - role: Role, -} -impl WithPromotion -where - I: Iterator + ExactSizeIterator + FusedIterator, -{ - #[inline] - fn new(inner: I) -> Self { - Self { - inner, - cur: std::mem::MaybeUninit::uninit(), - role: Role::King, - } - } -} -impl Iterator for WithPromotion -where - I: Iterator + ExactSizeIterator + FusedIterator, -{ - type Item = RawMove; - #[inline] - fn next(&mut self) -> Option { - if self.role == Role::King { - self.cur.write(self.inner.next()?); - self.role = Role::Knight; - } - let raw = unsafe { self.cur.assume_init() }; - let res = RawMove { - role: self.role, - ..raw - }; - self.role = unsafe { Role::transmute((self.role as u8).unchecked_add(1)) }; - Some(res) - } - #[inline] - fn size_hint(&self) -> (usize, Option) { - let len = self.len(); - (len, Some(len)) - } -} -impl FusedIterator for WithPromotion where - I: Iterator + ExactSizeIterator + FusedIterator -{ -} -impl ExactSizeIterator for WithPromotion -where - I: Iterator + ExactSizeIterator + FusedIterator, -{ - #[inline] - fn len(&self) -> usize { - unsafe { self.inner.len().unchecked_mul(4) } - } -} - #[inline] fn aux_play_normal(setup: &mut Setup, role: Role, from: Square, target: Square) { let from = from.bitboard(); @@ -1458,11 +1402,11 @@ fn aux_play_castle(setup: &mut Setup, side: CastlingSide) { setup.castling_rights.unset(setup.turn, CastlingSide::Long); } -struct MateCollector { +struct MateVisitorImpl { is_check: bool, is_mate: bool, } -impl MateCollector { +impl MateVisitorImpl { #[inline] fn new() -> Self { Self { @@ -1471,7 +1415,7 @@ impl MateCollector { } } } -impl Visitor for MateCollector { +impl Visitor for MateVisitorImpl { #[inline] fn is_check(&mut self) { self.is_check = true; @@ -1486,3 +1430,60 @@ impl Visitor for MateCollector { self.is_mate &= iter.len() == 0; } } + +struct MoveAndPromote + ExactSizeIterator + FusedIterator> { + inner: I, + cur: std::mem::MaybeUninit, + role: Role, +} +impl MoveAndPromote +where + I: Iterator + ExactSizeIterator + FusedIterator, +{ + #[inline] + fn new(inner: I) -> Self { + Self { + inner, + cur: std::mem::MaybeUninit::uninit(), + role: Role::King, + } + } +} +impl Iterator for MoveAndPromote +where + I: Iterator + ExactSizeIterator + FusedIterator, +{ + type Item = RawMove; + #[inline] + fn next(&mut self) -> Option { + if self.role == Role::King { + self.cur.write(self.inner.next()?); + self.role = Role::Knight; + } + let raw = unsafe { self.cur.assume_init() }; + let res = RawMove { + role: self.role, + ..raw + }; + self.role = unsafe { Role::transmute((self.role as u8).unchecked_add(1)) }; + Some(res) + } + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } +} +impl FusedIterator for MoveAndPromote where + I: Iterator + ExactSizeIterator + FusedIterator +{ +} +impl ExactSizeIterator for MoveAndPromote +where + I: Iterator + ExactSizeIterator + FusedIterator, +{ + #[inline] + fn len(&self) -> usize { + unsafe { self.inner.len().unchecked_mul(4) } + } +} diff --git a/src/setup.rs b/src/setup.rs index 83fe4f1..b5cc44a 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -405,12 +405,12 @@ impl Setup { }; ByRole::new(|kind| { mask & match kind { - Role::King => k, - Role::Queen => q, - Role::Bishop => b, - Role::Knight => n, - Role::Rook => r, Role::Pawn => p, + Role::Knight => n, + Role::Bishop => b, + Role::Rook => r, + Role::Queen => q, + Role::King => k, } }) })