From 651544fdd942c4d73b4b6f3ea340395fd7177e21 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 8 Jun 2025 17:16:23 -0700 Subject: [PATCH] [explorer, moves, position] Remove unused MoveBuilder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This thing isn't used by any of the "modern" code I've written. It was difficult to write, but kinda neat architecturally. It made a lot of invalid configurations of moves into build-time errors. Anyway… Remove several of the tests that relied on it, but that hadn't been updated to use the newer code either. --- explorer/src/main.rs | 20 +- moves/src/builder.rs | 428 ---------------------------------------- moves/src/lib.rs | 2 - moves/src/testing.rs | 9 - moves/tests/flags.rs | 108 ---------- moves/tests/pushes.rs | 17 -- position/src/testing.rs | 9 +- 7 files changed, 4 insertions(+), 589 deletions(-) delete mode 100644 moves/src/builder.rs delete mode 100644 moves/tests/flags.rs delete mode 100644 moves/tests/pushes.rs diff --git a/explorer/src/main.rs b/explorer/src/main.rs index ea8ce26..2e7a545 100644 --- a/explorer/src/main.rs +++ b/explorer/src/main.rs @@ -6,7 +6,7 @@ use chessfriend_board::ZobristState; use chessfriend_board::{fen::FromFenStr, Board}; use chessfriend_core::random::RandomNumberGenerator; use chessfriend_core::{Color, Piece, Shape, Square}; -use chessfriend_moves::{Builder as MoveBuilder, GeneratedMove, ValidateMove}; +use chessfriend_moves::GeneratedMove; use chessfriend_position::{fen::ToFenStr, PlacePieceStrategy, Position}; use clap::{Arg, Command}; use rustyline::error::ReadlineError; @@ -128,22 +128,8 @@ fn respond(line: &str, state: &mut State) -> anyhow::Result { println!("{}", state.position.to_fen_str()?); result.should_print_position = false; } - Some(("make", matches)) => { - let from_square = Square::from_algebraic_str( - matches - .get_one::("from") - .ok_or(CommandHandlingError::MissingArgument("from"))?, - )?; - - let to_square = Square::from_algebraic_str( - matches - .get_one::("to") - .ok_or(CommandHandlingError::MissingArgument("to"))?, - )?; - - let ply = MoveBuilder::new().from(from_square).to(to_square).build()?; - - state.position.make_move(ply, ValidateMove::Yes)?; + Some(("make", _matches)) => { + unimplemented!() } Some(("place", matches)) => { let color = matches diff --git a/moves/src/builder.rs b/moves/src/builder.rs deleted file mode 100644 index 53bc894..0000000 --- a/moves/src/builder.rs +++ /dev/null @@ -1,428 +0,0 @@ -// Eryn Wells - -use crate::{defs::Kind, Move, PromotionShape}; -use chessfriend_board::{en_passant::EnPassant, CastleParameters}; -use chessfriend_core::{Color, File, PlacedPiece, Rank, Square, Wing}; -use std::result::Result as StdResult; -use thiserror::Error; - -pub type Result = std::result::Result; -type EncodedMoveResult = std::result::Result; - -#[derive(Clone, Copy, Debug, Error, Eq, PartialEq)] -pub enum Error { - #[error("no origin square")] - MissingOriginSquare, - #[error("no target square")] - MissingTargetSquare, - #[error("no capture square")] - MissingCaptureSquare, - #[error("invalid en passant square")] - InvalidEnPassantSquare, -} - -const MASK: u16 = 0b111_111; - -fn build_move_bits(origin_square: Square, target_square: Square) -> u16 { - (origin_square as u16 & MASK) << 4 | (target_square as u16 & MASK) << 10 -} - -pub trait Style { - fn origin_square(&self) -> Option { - None - } - - fn target_square(&self) -> Option { - None - } - - fn move_bits(&self) -> EncodedMoveResult { - let origin_square = self.origin_square().ok_or(Error::MissingOriginSquare)?; - let target_square = self.target_square().ok_or(Error::MissingTargetSquare)?; - - Ok(build_move_bits(origin_square, target_square)) - } - - unsafe fn move_bits_unchecked(&self) -> u16 { - let origin_square = self.origin_square().unwrap(); - let target_square = self.target_square().unwrap(); - - build_move_bits(origin_square, target_square) - } -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct Builder { - style: S, -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct Null; - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct Push { - from: Option, - to: Option, -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct DoublePush { - from: Square, - to: Square, -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct Capture { - push: Push, - capture: Option, -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct EnPassantCapture { - push: Push, - capture: Option, -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct Promotion { - style: S, - promotion: PromotionShape, -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct Castle { - color: Color, - wing: Wing, -} - -impl Style for Null {} - -impl Style for Push { - fn origin_square(&self) -> Option { - self.from - } - - fn target_square(&self) -> Option { - self.to - } -} - -impl Style for Capture { - fn origin_square(&self) -> Option { - self.push.from - } - - fn target_square(&self) -> Option { - self.push.to - } -} - -impl Style for Castle { - fn origin_square(&self) -> Option { - let parameters = CastleParameters::get(self.color, self.wing); - Some(parameters.origin.king) - } - - fn target_square(&self) -> Option { - let parameters = CastleParameters::get(self.color, self.wing); - Some(parameters.target.king) - } -} - -impl Style for DoublePush { - fn origin_square(&self) -> Option { - Some(self.from) - } - - fn target_square(&self) -> Option { - Some(self.to) - } - - fn move_bits(&self) -> StdResult { - Ok( - Kind::DoublePush as u16 - | (self.from as u16 & MASK) << 4 - | (self.to as u16 & MASK) << 10, - ) - } -} - -impl Style for EnPassantCapture { - fn origin_square(&self) -> Option { - self.push.from - } - - fn target_square(&self) -> Option { - self.push.to - } - - fn move_bits(&self) -> EncodedMoveResult { - let origin_square = self.origin_square().ok_or(Error::MissingOriginSquare)?; - let target_square = self.target_square().ok_or(Error::MissingTargetSquare)?; - - Ok(build_move_bits(origin_square, target_square)) - } -} - -impl Style for Promotion { - fn origin_square(&self) -> Option { - self.style.from - } - - fn target_square(&self) -> Option { - self.style.to - } -} - -impl Style for Promotion { - fn origin_square(&self) -> Option { - self.style.push.from - } - - fn target_square(&self) -> Option { - self.style.push.to - } -} - -impl Promotion { - fn move_bits(&self) -> StdResult { - let origin_square = self - .style - .origin_square() - .ok_or(Error::MissingOriginSquare)? as u16; - let target_square = self - .style - .target_square() - .ok_or(Error::MissingTargetSquare)? as u16; - - Ok(Kind::Promotion as u16 - | self.promotion as u16 - | (origin_square & MASK << 4) - | (target_square & MASK << 10)) - } -} - -impl Promotion { - fn move_bits(&self) -> StdResult { - let origin_square = self - .style - .origin_square() - .ok_or(Error::MissingOriginSquare)? as u16; - let target_square = self - .style - .target_square() - .ok_or(Error::MissingTargetSquare)? as u16; - - Ok(Kind::CapturePromotion as u16 - | self.promotion as u16 - | (origin_square & MASK) << 4 - | (target_square & MASK) << 10) - } -} - -impl Builder { - #[must_use] - pub fn new() -> Self { - Self::default() - } - - #[must_use] - pub fn push(piece: &PlacedPiece) -> Builder { - Builder { - style: Push { - from: Some(piece.square), - to: None, - }, - } - } - - #[must_use] - pub fn double_push(file: File, color: Color) -> Builder { - let (from, to) = match color { - Color::White => ( - Square::from_file_rank(file, Rank::TWO), - Square::from_file_rank(file, Rank::FOUR), - ), - Color::Black => ( - Square::from_file_rank(file, Rank::SEVEN), - Square::from_file_rank(file, Rank::FIVE), - ), - }; - - Builder { - style: DoublePush { from, to }, - } - } - - #[must_use] - pub fn castling(color: Color, wing: Wing) -> Builder { - Builder { - style: Castle { color, wing }, - } - } - - #[must_use] - pub fn capturing_piece(piece: &PlacedPiece, capturing: &PlacedPiece) -> Builder { - Self::push(piece).capturing_piece(capturing) - } - - #[must_use] - pub fn from(&self, square: Square) -> Builder { - Builder { - style: Push { - from: Some(square), - to: None, - }, - } - } - - #[must_use] - pub fn build(&self) -> Move { - Move(0) - } -} - -impl Default for Builder { - fn default() -> Self { - Self { style: Null } - } -} - -impl Builder { - pub fn from(&mut self, square: Square) -> &mut Self { - self.style.from = Some(square); - self - } - - pub fn to(&mut self, square: Square) -> &mut Self { - self.style.to = Some(square); - self - } - - #[must_use] - pub fn capturing_on(&self, square: Square) -> Builder { - let mut style = self.style.clone(); - style.to = Some(square); - - Builder { - style: Capture { - push: style, - capture: Some(square), - }, - } - } - - #[must_use] - pub fn capturing_en_passant_on(&self, target_square: Square) -> Builder { - match EnPassant::from_target_square(target_square) { - Some(en_passant) => { - let mut style = self.style.clone(); - style.to = Some(en_passant.target_square()); - - Builder { - style: EnPassantCapture { - push: style, - capture: Some(en_passant), - }, - } - } - None => todo!(), - } - } - - #[must_use] - pub fn capturing_piece(&self, piece: &PlacedPiece) -> Builder { - Builder { - style: Capture { - push: self.style.clone(), - capture: Some(piece.square), - }, - } - } - - #[must_use] - pub fn promoting_to(&self, shape: PromotionShape) -> Builder> { - Builder { - style: Promotion { - style: self.style.clone(), - promotion: shape, - }, - } - } - - pub fn build(&self) -> Result { - Ok(Move(Kind::Quiet as u16 | self.style.move_bits()?)) - } -} - -impl Builder { - fn bits(&self) -> u16 { - let bits = match self.style.wing { - Wing::KingSide => Kind::KingSideCastle, - Wing::QueenSide => Kind::QueenSideCastle, - }; - - bits as u16 - } - - pub fn build(&self) -> Result { - Ok(Move(self.bits() | self.style.move_bits()?)) - } -} - -impl Builder { - #[must_use] - pub fn promoting_to(self, shape: PromotionShape) -> Builder> { - Builder { - style: Promotion { - style: self.style, - promotion: shape, - }, - } - } - - pub fn build(&self) -> Result { - Ok(Move(Kind::Capture as u16 | self.style.move_bits()?)) - } -} - -impl Builder { - pub fn build(&self) -> Result { - Ok(Move(Kind::DoublePush as u16 | self.style.move_bits()?)) - } -} - -impl Builder { - /// Builds an en passant move. - /// - /// ## Safety - /// - /// This method builds without doing error checking. - #[must_use] - pub unsafe fn build_unchecked(&self) -> Move { - Move(Kind::EnPassantCapture as u16 | self.style.move_bits_unchecked()) - } - - /// Build an en passant move. - /// - /// ## Errors - /// - /// Returns an error if the target or origin squares are invalid. - pub fn build(&self) -> Result { - Ok(Move( - Kind::EnPassantCapture as u16 | self.style.move_bits()?, - )) - } -} - -impl Builder> { - pub fn build(&self) -> Result { - Ok(Move(self.style.move_bits()?)) - } -} - -impl Builder> { - pub fn build(&self) -> Result { - Ok(Move(self.style.move_bits()?)) - } -} diff --git a/moves/src/lib.rs b/moves/src/lib.rs index 4ed188c..1a46667 100644 --- a/moves/src/lib.rs +++ b/moves/src/lib.rs @@ -3,7 +3,6 @@ pub mod generators; pub mod testing; -mod builder; mod defs; mod macros; mod make_move; @@ -11,7 +10,6 @@ mod moves; mod record; mod unmake_move; -pub use builder::{Builder, Error as BuildMoveError, Result as BuildMoveResult}; pub use defs::{Kind, PromotionShape}; pub use generators::GeneratedMove; pub use make_move::{MakeMove, MakeMoveError, MakeMoveResult, ValidateMove}; diff --git a/moves/src/testing.rs b/moves/src/testing.rs index b298d5d..c4ef5a5 100644 --- a/moves/src/testing.rs +++ b/moves/src/testing.rs @@ -1,17 +1,8 @@ // Eryn Wells -use crate::BuildMoveError; - pub type TestResult = Result<(), TestError>; #[derive(Debug, Eq, PartialEq)] pub enum TestError { - BuildMove(BuildMoveError), NoLegalMoves, } - -impl From for TestError { - fn from(value: BuildMoveError) -> Self { - TestError::BuildMove(value) - } -} diff --git a/moves/tests/flags.rs b/moves/tests/flags.rs deleted file mode 100644 index f4d7530..0000000 --- a/moves/tests/flags.rs +++ /dev/null @@ -1,108 +0,0 @@ -// Eryn Wells - -use chessfriend_core::{piece, Color, File, Shape, Square, Wing}; -use chessfriend_moves::{testing::*, Builder, PromotionShape}; - -macro_rules! assert_flag { - ($move:expr, $left:expr, $right:expr, $desc:expr) => { - assert_eq!($left, $right, "{:?} -> {}", $move, stringify!($desc)) - }; -} - -macro_rules! assert_flags { - ($move:expr, $quiet:expr, $double_push:expr, $en_passant:expr, $capture:expr, $castle:expr, $promotion:expr) => { - assert_flag!($move, $move.is_quiet(), $quiet, "is_quiet"); - assert_flag!( - $move, - $move.is_double_push(), - $double_push, - "is_double_push" - ); - assert_flag!($move, $move.is_en_passant(), $en_passant, "is_en_passant"); - assert_flag!($move, $move.is_capture(), $capture, "is_capture"); - assert_flag!($move, $move.is_castle(), $castle, "is_castle"); - assert_flag!($move, $move.is_promotion(), $promotion, "is_promotion"); - }; -} - -#[test] -fn move_flags_quiet() -> TestResult { - let mv = Builder::push(&piece!(White Pawn on A4)) - .to(Square::A5) - .build()?; - assert_flags!(mv, true, false, false, false, false, false); - - Ok(()) -} - -#[test] -fn move_flags_double_push() -> TestResult { - let mv = Builder::double_push(File::C, Color::White).build()?; - assert_flags!(mv, false, true, false, false, false, false); - - Ok(()) -} - -#[test] -fn move_flags_capture() -> TestResult { - let mv = Builder::new() - .from(Square::A4) - .capturing_on(Square::B5) - .build()?; - - assert_flags!(mv, false, false, false, true, false, false); - - Ok(()) -} - -#[test] -fn move_flags_en_passant_capture() -> TestResult { - let ply = Builder::new() - .from(Square::A4) - .capturing_en_passant_on(Square::B3) - .build()?; - - assert!(ply.is_en_passant()); - assert_eq!(ply.origin_square(), Square::A4); - assert_eq!(ply.target_square(), Square::B3); - assert_eq!(ply.capture_square(), Some(Square::B4)); - - Ok(()) -} - -#[test] -fn move_flags_promotion() -> TestResult { - let ply = Builder::push(&piece!(White Pawn on H7)) - .to(Square::H8) - .promoting_to(PromotionShape::Queen) - .build()?; - - assert!(ply.is_promotion()); - assert_eq!(ply.promotion_shape(), Some(Shape::Queen)); - - Ok(()) -} - -#[test] -fn move_flags_capture_promotion() -> TestResult { - let ply = Builder::push(&piece!(White Pawn on H7)) - .to(Square::H8) - .capturing_piece(&piece!(Black Knight on G8)) - .promoting_to(PromotionShape::Queen) - .build()?; - - assert!(ply.is_capture()); - assert!(ply.is_promotion()); - assert_eq!(ply.promotion_shape(), Some(Shape::Queen)); - - Ok(()) -} - -#[test] -fn move_flags_castle() -> TestResult { - let mv = Builder::castling(Color::White, Wing::KingSide).build()?; - - assert_flags!(mv, false, false, false, false, true, false); - - Ok(()) -} diff --git a/moves/tests/pushes.rs b/moves/tests/pushes.rs deleted file mode 100644 index 7406eb0..0000000 --- a/moves/tests/pushes.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Eryn Wells - -use chessfriend_core::{piece, Square}; -use chessfriend_moves::{testing::*, Builder}; - -#[test] -fn pawn_push() -> TestResult { - let mv = Builder::push(&piece!(White Pawn on A3)) - .to(Square::A4) - .build()?; - - assert!(mv.is_quiet()); - assert_eq!(mv.origin_square(), Square::A3); - assert_eq!(mv.target_square(), Square::A4); - - Ok(()) -} diff --git a/position/src/testing.rs b/position/src/testing.rs index c546a79..c5f4491 100644 --- a/position/src/testing.rs +++ b/position/src/testing.rs @@ -1,6 +1,6 @@ // Eryn Wells -use chessfriend_moves::{BuildMoveError, MakeMoveError}; +use chessfriend_moves::MakeMoveError; #[macro_export] macro_rules! assert_eq_bitboards { @@ -19,17 +19,10 @@ pub type TestResult = Result<(), TestError>; #[derive(Debug, Eq, PartialEq)] pub enum TestError { - BuildMove(BuildMoveError), MakeMove(MakeMoveError), NoLegalMoves, } -impl From for TestError { - fn from(value: BuildMoveError) -> Self { - TestError::BuildMove(value) - } -} - impl From for TestError { fn from(value: MakeMoveError) -> Self { TestError::MakeMove(value)