[explorer, moves, position] Implement bespoke make_move and unmake_move methods on Position
Instead of inheriting the MakeMove and UnmakeMove traits by being a BoardProvider, implement bespoke versions of these two methods. This gives Position a chance to do some of its own work (tracking captures, move records, etc) when making a move. Pass the move record by reference to the unmake_move() method. Saves a copy. Export the Result types for MakeMove and UnmakeMove.
This commit is contained in:
parent
724a98c2e2
commit
8f42a4c94e
5 changed files with 66 additions and 45 deletions
|
@ -13,7 +13,7 @@ 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, ValidateMove};
|
||||
pub use make_move::{MakeMove, MakeMoveError, MakeMoveResult, ValidateMove};
|
||||
pub use moves::Move;
|
||||
pub use record::MoveRecord;
|
||||
pub use unmake_move::{UnmakeMove, UnmakeMoveError};
|
||||
pub use unmake_move::{UnmakeMove, UnmakeMoveError, UnmakeMoveResult};
|
||||
|
|
|
@ -8,7 +8,7 @@ use chessfriend_board::{
|
|||
use chessfriend_core::{Color, Piece, Rank, Square, Wing};
|
||||
use thiserror::Error;
|
||||
|
||||
type MakeMoveResult = Result<MoveRecord, MakeMoveError>;
|
||||
pub type MakeMoveResult = Result<MoveRecord, MakeMoveError>;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||
pub enum ValidateMove {
|
||||
|
|
|
@ -5,7 +5,7 @@ use chessfriend_board::{Board, BoardProvider, PlacePieceError, PlacePieceStrateg
|
|||
use chessfriend_core::{Piece, Square};
|
||||
use thiserror::Error;
|
||||
|
||||
type UnmakeMoveResult = Result<(), UnmakeMoveError>;
|
||||
pub type UnmakeMoveResult = Result<(), UnmakeMoveError>;
|
||||
|
||||
#[derive(Debug, Error, Eq, PartialEq)]
|
||||
pub enum UnmakeMoveError {
|
||||
|
@ -42,7 +42,7 @@ pub trait UnmakeMove {
|
|||
/// Returns one of [`UnmakeMoveError`] indicating why the move cannot be
|
||||
/// unmade.
|
||||
///
|
||||
fn unmake_move(&mut self, record: MoveRecord) -> UnmakeMoveResult;
|
||||
fn unmake_move(&mut self, record: &MoveRecord) -> UnmakeMoveResult;
|
||||
}
|
||||
|
||||
trait UnmakeMoveInternal {
|
||||
|
@ -53,17 +53,17 @@ trait UnmakeMoveInternal {
|
|||
}
|
||||
|
||||
impl<T: BoardProvider> UnmakeMove for T {
|
||||
fn unmake_move(&mut self, record: MoveRecord) -> UnmakeMoveResult {
|
||||
fn unmake_move(&mut self, record: &MoveRecord) -> UnmakeMoveResult {
|
||||
let ply = record.ply;
|
||||
|
||||
if ply.is_quiet() || ply.is_double_push() {
|
||||
self.unmake_quiet_move(&record)?;
|
||||
self.unmake_quiet_move(record)?;
|
||||
} else if ply.is_capture() || ply.is_en_passant() {
|
||||
self.unmake_capture_move(&record)?;
|
||||
self.unmake_capture_move(record)?;
|
||||
} else if ply.is_promotion() {
|
||||
self.unmake_promotion_move(&record)?;
|
||||
self.unmake_promotion_move(record)?;
|
||||
} else if ply.is_castle() {
|
||||
self.unmake_castle_move(&record)?;
|
||||
self.unmake_castle_move(record)?;
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ mod tests {
|
|||
);
|
||||
|
||||
// Unmake the move
|
||||
initial_board.unmake_move(record)?;
|
||||
initial_board.unmake_move(&record)?;
|
||||
|
||||
// Verify we're back to the initial state
|
||||
assert_eq!(
|
||||
|
@ -240,8 +240,7 @@ mod tests {
|
|||
assert_eq!(board.get_piece(Square::C3), Some(piece!(White Pawn)));
|
||||
assert_eq!(board.active_color, Color::Black);
|
||||
|
||||
// Unmake the move
|
||||
board.unmake_move(record)?;
|
||||
board.unmake_move(&record)?;
|
||||
|
||||
// Verify original state restored
|
||||
assert_eq!(board.get_piece(Square::C2), Some(piece!(White Pawn)));
|
||||
|
@ -264,8 +263,7 @@ mod tests {
|
|||
assert_eq!(board.en_passant_target, Some(Square::E3));
|
||||
assert_eq!(board.active_color, Color::Black);
|
||||
|
||||
// Unmake the move
|
||||
board.unmake_move(record)?;
|
||||
board.unmake_move(&record)?;
|
||||
|
||||
// Verify original state restored
|
||||
assert_eq!(board.get_piece(Square::E2), Some(piece!(White Pawn)));
|
||||
|
@ -292,8 +290,7 @@ mod tests {
|
|||
assert_eq!(record.captured_piece, Some(piece!(Black Rook)));
|
||||
assert_eq!(board.active_color, Color::Black);
|
||||
|
||||
// Unmake the move
|
||||
board.unmake_move(record)?;
|
||||
board.unmake_move(&record)?;
|
||||
|
||||
// Verify original state restored
|
||||
assert_eq!(board.get_piece(Square::C2), Some(piece!(White Bishop)));
|
||||
|
@ -328,8 +325,7 @@ mod tests {
|
|||
);
|
||||
assert_eq!(record.captured_piece, Some(piece!(White Pawn)));
|
||||
|
||||
// Unmake the en passant capture
|
||||
board.unmake_move(record)?;
|
||||
board.unmake_move(&record)?;
|
||||
|
||||
// Verify state before en passant is restored
|
||||
assert_eq!(board.get_piece(Square::F4), Some(piece!(Black Pawn)));
|
||||
|
@ -358,8 +354,7 @@ mod tests {
|
|||
assert_eq!(board.get_piece(Square::F8), Some(piece!(White Queen)));
|
||||
assert_eq!(board.active_color, Color::Black);
|
||||
|
||||
// Unmake the promotion
|
||||
board.unmake_move(record)?;
|
||||
board.unmake_move(&record)?;
|
||||
|
||||
// Verify original pawn is restored
|
||||
assert_eq!(board.get_piece(Square::F7), Some(piece!(White Pawn)));
|
||||
|
@ -384,8 +379,7 @@ mod tests {
|
|||
assert_eq!(board.get_piece(Square::G8), Some(piece!(White Queen)));
|
||||
assert_eq!(record.captured_piece, Some(piece!(Black Rook)));
|
||||
|
||||
// Unmake the promotion capture
|
||||
board.unmake_move(record)?;
|
||||
board.unmake_move(&record)?;
|
||||
|
||||
// Verify original state restored
|
||||
assert_eq!(board.get_piece(Square::F7), Some(piece!(White Pawn)));
|
||||
|
@ -416,8 +410,7 @@ mod tests {
|
|||
.castling_rights
|
||||
.color_has_right(Color::White, Wing::KingSide));
|
||||
|
||||
// Unmake the castle
|
||||
board.unmake_move(record)?;
|
||||
board.unmake_move(&record)?;
|
||||
|
||||
// Verify original state restored
|
||||
assert_eq!(board.get_piece(Square::E1), Some(piece!(White King)));
|
||||
|
@ -451,8 +444,7 @@ mod tests {
|
|||
.castling_rights
|
||||
.color_has_right(Color::White, Wing::QueenSide));
|
||||
|
||||
// Unmake the castle
|
||||
board.unmake_move(record)?;
|
||||
board.unmake_move(&record)?;
|
||||
|
||||
// Verify original state restored
|
||||
assert_eq!(board.get_piece(Square::E1), Some(piece!(White King)));
|
||||
|
@ -484,8 +476,7 @@ mod tests {
|
|||
assert_eq!(board.get_piece(Square::G8), Some(piece!(Black King)));
|
||||
assert_eq!(board.get_piece(Square::F8), Some(piece!(Black Rook)));
|
||||
|
||||
// Unmake the castle
|
||||
board.unmake_move(record)?;
|
||||
board.unmake_move(&record)?;
|
||||
|
||||
// Verify original state restored
|
||||
assert_eq!(board.get_piece(Square::E8), Some(piece!(Black King)));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue