Split out some unchecked and check move build() methods

Unchecked are unsafe. Checked are safe.
This commit is contained in:
Eryn Wells 2024-02-13 11:07:49 -07:00
parent 047eb4fd77
commit b3e55f6dcd

View file

@ -1,10 +1,11 @@
// Eryn Wells <eryn@erynwells.me> // Eryn Wells <eryn@erynwells.me>
use crate::{castle, defs::Kind, Move, PromotionShape}; use crate::{castle, defs::Kind, EnPassant, Move, PromotionShape};
use chessfriend_core::{Color, File, PlacedPiece, Rank, Square}; use chessfriend_core::{Color, File, PlacedPiece, Rank, Square};
use std::result::Result as StdResult; use std::result::Result as StdResult;
pub type Result = std::result::Result<Move, Error>; pub type Result = std::result::Result<Move, Error>;
type EncodedMoveResult = std::result::Result<u16, Error>;
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Error { pub enum Error {
@ -23,11 +24,22 @@ pub trait Style {
None None
} }
fn into_move_bits(&self) -> StdResult<u16, Error> { fn into_move_bits(&self) -> EncodedMoveResult {
let origin_square = self.origin_square().ok_or(Error::MissingOriginSquare)? as u16; let origin_square = self.origin_square().ok_or(Error::MissingOriginSquare)?;
let target_square = self.target_square().ok_or(Error::MissingTargetSquare)? as u16; let target_square = self.target_square().ok_or(Error::MissingTargetSquare)?;
Ok((origin_square & 0b111111) << 4 | (target_square & 0b111111) << 10) Ok(self._build_move_bits(origin_square, target_square))
}
unsafe fn into_move_bits_unchecked(&self) -> u16 {
let origin_square = self.origin_square().unwrap();
let target_square = self.target_square().unwrap();
self._build_move_bits(origin_square, target_square)
}
fn _build_move_bits(&self, origin_square: Square, target_square: Square) -> u16 {
(origin_square as u16 & 0b111111) << 4 | (target_square as u16 & 0b111111) << 10
} }
} }
@ -123,11 +135,17 @@ impl Style for EnPassantCapture {
self.push.to self.push.to
} }
fn into_move_bits(&self) -> StdResult<u16, Error> { fn into_move_bits(&self) -> EncodedMoveResult {
let origin_square = self.origin_square().ok_or(Error::MissingOriginSquare)? as u16; let origin_square = self.origin_square().ok_or(Error::MissingOriginSquare)?;
let target_square = self.target_square().ok_or(Error::MissingTargetSquare)? as u16; let target_square = self.target_square().ok_or(Error::MissingTargetSquare)?;
Ok((origin_square & 0b111111) << 4 | (target_square & 0b111111) << 10) Ok(self._build_move_bits(origin_square, target_square))
}
}
impl EnPassantCapture {
fn _build_move_bits(&self, origin_square: Square, target_square: Square) -> u16 {
(origin_square as u16 & 0b111111) << 4 | (target_square as u16 & 0b111111) << 10
} }
} }
@ -192,11 +210,11 @@ impl Builder<Null> {
Self { style: Null } Self { style: Null }
} }
pub fn push(piece: &PlacedPiece, to: Square) -> Builder<Push> { pub fn push(piece: &PlacedPiece) -> Builder<Push> {
Builder { Builder {
style: Push { style: Push {
from: Some(piece.square()), from: Some(piece.square()),
to: Some(to), to: None,
}, },
} }
} }
@ -224,12 +242,8 @@ impl Builder<Null> {
} }
} }
pub fn capturing_on(piece: &PlacedPiece, to: Square) -> Builder<Capture> {
Self::push(piece, to).capturing_on(to)
}
pub fn capturing_piece(piece: &PlacedPiece, capturing: &PlacedPiece) -> Builder<Capture> { pub fn capturing_piece(piece: &PlacedPiece, capturing: &PlacedPiece) -> Builder<Capture> {
Self::push(piece, capturing.square()).capturing_piece(&capturing) Self::push(piece).capturing_piece(&capturing)
} }
pub fn from(self, square: Square) -> Builder<Push> { pub fn from(self, square: Square) -> Builder<Push> {
@ -252,7 +266,7 @@ impl Builder<Push> {
self self
} }
pub fn to(&mut self, square: Square) -> &mut Self { pub fn to(mut self, square: Square) -> Self {
self.style.to = Some(square); self.style.to = Some(square);
self self
} }
@ -346,7 +360,11 @@ impl Builder<DoublePush> {
} }
impl Builder<EnPassantCapture> { impl Builder<EnPassantCapture> {
pub unsafe fn build_unchecked(&self) -> Result { pub unsafe fn build_unchecked(&self) -> Move {
Move(Kind::EnPassantCapture as u16 | self.style.into_move_bits_unchecked())
}
pub fn build(&self) -> Result {
Ok(Move( Ok(Move(
Kind::EnPassantCapture as u16 | self.style.into_move_bits()?, Kind::EnPassantCapture as u16 | self.style.into_move_bits()?,
)) ))