1
0
Fork 0

get rid of OptionSquare

This commit is contained in:
Paul-Nicolas Madelaine 2025-11-29 14:12:20 +01:00
parent 4c137d3c95
commit ebab07f5ae
3 changed files with 21 additions and 67 deletions

View file

@ -434,52 +434,6 @@ impl core::str::FromStr for Square {
} }
} }
#[rustfmt::skip]
#[allow(unused)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
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,
None,
}
impl OptionSquare {
#[inline]
pub(crate) fn new(square: Option<Square>) -> OptionSquare {
match square {
Some(square) => Self::from_square(square),
None => Self::None,
}
}
#[inline]
pub(crate) fn try_into_square(self) -> Option<Square> {
unsafe {
match self {
Self::None => None,
_ => Some(Square::new_unchecked(self as u8)),
}
}
}
#[inline]
pub(crate) fn from_square(square: Square) -> Self {
unsafe { core::mem::transmute(square) }
}
#[inline]
pub(crate) fn bitboard(&self) -> Bitboard {
Bitboard(1 << (*self as u8))
}
}
/// A type of piece. /// A type of piece.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)] #[repr(u8)]

View file

@ -94,7 +94,7 @@ impl Position {
], ],
turn: Color::White, turn: Color::White,
castling_rights: CastlingRights::full(), castling_rights: CastlingRights::full(),
en_passant: OptionSquare::None, en_passant: None,
}) })
} }
@ -164,7 +164,7 @@ impl Position {
/// Returns `true` if taking en passant is legal on the position. /// Returns `true` if taking en passant is legal on the position.
#[must_use] #[must_use]
pub fn en_passant_is_legal(&self) -> bool { pub fn en_passant_is_legal(&self) -> bool {
if self.as_setup().en_passant == OptionSquare::None { if self.as_setup().en_passant == None {
return false; return false;
} }
struct MoveGenImpl { struct MoveGenImpl {
@ -192,7 +192,11 @@ impl Position {
} }
} }
let mut moves = MoveGenImpl { let mut moves = MoveGenImpl {
to: self.as_setup().en_passant.bitboard(), to: self
.as_setup()
.en_passant
.map(|square| square.bitboard())
.unwrap_or(Bitboard::new()),
}; };
self.generate_moves(&mut moves).is_break() self.generate_moves(&mut moves).is_break()
} }
@ -204,7 +208,7 @@ impl Position {
/// passant before calling this function. /// passant before calling this function.
#[inline] #[inline]
pub fn remove_en_passant_target_square(&mut self) { pub fn remove_en_passant_target_square(&mut self) {
self.0.en_passant = OptionSquare::None; self.0.en_passant = None
} }
/// Removes the castling rights for the given color and side, if any. /// Removes the castling rights for the given color and side, if any.
@ -255,7 +259,7 @@ impl Position {
checkers.is_empty().then(|| { checkers.is_empty().then(|| {
Self(Setup { Self(Setup {
turn: !turn, turn: !turn,
en_passant: OptionSquare::None, en_passant: None,
..self.0.clone() ..self.0.clone()
}) })
}) })
@ -801,7 +805,7 @@ impl Position {
), ),
)?; )?;
// en passant // en passant
if let Some(to) = en_passant.try_into_square() { if let Some(to) = en_passant {
if global_mask_to.contains(to) { if global_mask_to.contains(to) {
let capture_square = unsafe { let capture_square = unsafe {
// SAFETY: the position is legal // SAFETY: the position is legal
@ -907,7 +911,7 @@ impl Position {
pub(crate) unsafe fn play_unchecked(&mut self, m: RawMove) { pub(crate) unsafe fn play_unchecked(&mut self, m: RawMove) {
let Self(setup) = self; let Self(setup) = self;
setup.en_passant = OptionSquare::None; setup.en_passant = None;
let RawMove { let RawMove {
kind, kind,
@ -927,13 +931,13 @@ impl Position {
MoveType::PawnAttackPromotion => aux_play_normal(setup, role, from, to), MoveType::PawnAttackPromotion => aux_play_normal(setup, role, from, to),
MoveType::PawnDoubleAdvance => { MoveType::PawnDoubleAdvance => {
aux_play_pawn_advance(setup, Role::Pawn, from, to); aux_play_pawn_advance(setup, Role::Pawn, from, to);
setup.en_passant = OptionSquare::new(Some(Square::from_coords( setup.en_passant = Some(Square::from_coords(
from.file(), from.file(),
match setup.turn { match setup.turn {
Color::White => Rank::Third, Color::White => Rank::Third,
Color::Black => Rank::Sixth, Color::Black => Rank::Sixth,
}, },
))); ));
} }
MoveType::EnPassant => { MoveType::EnPassant => {
let direction = !setup.turn.forward(); let direction = !setup.turn.forward();

View file

@ -32,7 +32,7 @@ pub struct Setup {
/// bitboards = [pawns | bishops | queens, knights | bishops | kings, rooks | queens | kings, black] /// bitboards = [pawns | bishops | queens, knights | bishops | kings, rooks | queens | kings, black]
pub(crate) bitboards: [Bitboard; 4], pub(crate) bitboards: [Bitboard; 4],
pub(crate) turn: Color, pub(crate) turn: Color,
pub(crate) en_passant: OptionSquare, pub(crate) en_passant: Option<Square>,
pub(crate) castling_rights: CastlingRights, pub(crate) castling_rights: CastlingRights,
} }
@ -43,7 +43,7 @@ impl Setup {
Self { Self {
bitboards: [Bitboard(0); 4], bitboards: [Bitboard(0); 4],
turn: Color::White, turn: Color::White,
en_passant: OptionSquare::None, en_passant: None,
castling_rights: CastlingRights::new(), castling_rights: CastlingRights::new(),
} }
} }
@ -208,7 +208,7 @@ impl Setup {
w.write_char(' ')?; w.write_char(' ')?;
match self.en_passant.try_into_square() { match self.en_passant {
Some(sq) => { Some(sq) => {
w.write_char(sq.file().to_char())?; w.write_char(sq.file().to_char())?;
w.write_char(sq.rank().to_char())?; w.write_char(sq.rank().to_char())?;
@ -245,7 +245,7 @@ impl Setup {
/// Returns the optional en passant target square. /// Returns the optional en passant target square.
#[inline] #[inline]
pub fn en_passant_target_square(&self) -> Option<Square> { pub fn en_passant_target_square(&self) -> Option<Square> {
self.en_passant.try_into_square() self.en_passant
} }
/// Sets the occupancy of a square. /// Sets the occupancy of a square.
@ -307,7 +307,7 @@ impl Setup {
/// Sets the en passant target square. /// Sets the en passant target square.
#[inline] #[inline]
pub fn set_en_passant_target_square(&mut self, square: Option<Square>) { pub fn set_en_passant_target_square(&mut self, square: Option<Square>) {
self.en_passant = OptionSquare::new(square); self.en_passant = square;
} }
/// Returns the quad-bitboard representation of the board. /// Returns the quad-bitboard representation of the board.
@ -341,11 +341,7 @@ impl Setup {
(black ^ (p_b_q | n_b_k | r_q_k)).mirror(), (black ^ (p_b_q | n_b_k | r_q_k)).mirror(),
], ],
turn: !self.turn, turn: !self.turn,
en_passant: self en_passant: self.en_passant.map(|square| square.mirror()),
.en_passant
.try_into_square()
.map(|square| OptionSquare::from_square(square.mirror()))
.unwrap_or(OptionSquare::None),
castling_rights: self.castling_rights.mirror(), castling_rights: self.castling_rights.mirror(),
} }
} }
@ -460,7 +456,7 @@ impl Setup {
reasons.add(IllegalPositionReason::InvalidCastlingRights); reasons.add(IllegalPositionReason::InvalidCastlingRights);
} }
if self.en_passant.try_into_square().is_some_and(|en_passant| { if self.en_passant.is_some_and(|en_passant| {
let (target_rank, pawn_rank) = match self.turn { let (target_rank, pawn_rank) = match self.turn {
Color::White => (Rank::Sixth, Rank::Fifth), Color::White => (Rank::Sixth, Rank::Fifth),
Color::Black => (Rank::Third, Rank::Fourth), Color::Black => (Rank::Third, Rank::Fourth),
@ -473,7 +469,7 @@ impl Setup {
reasons.add(IllegalPositionReason::InvalidEnPassant); reasons.add(IllegalPositionReason::InvalidEnPassant);
} }
if self.en_passant.try_into_square().is_some_and(|en_passant| { if self.en_passant.is_some_and(|en_passant| {
let blockers = blockers let blockers = blockers
& !en_passant.bitboard().trans(match self.turn { & !en_passant.bitboard().trans(match self.turn {
Color::White => Direction::South, Color::White => Direction::South,