Replace uses of types in r#move with types from the moves package types
This commit is contained in:
parent
aaad991899
commit
d668091d0d
16 changed files with 273 additions and 280 deletions
|
|
@ -3,5 +3,5 @@
|
|||
mod move_builder;
|
||||
mod position_builder;
|
||||
|
||||
pub use move_builder::Builder as MoveBuilder;
|
||||
pub use move_builder::{Builder as MoveBuilder, MakeMoveError};
|
||||
pub use position_builder::Builder as PositionBuilder;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,19 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use crate::{position::flags::Flags, r#move::Castle, MakeMoveError, Move, Position};
|
||||
use crate::{position::flags::Flags, Position};
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
use chessfriend_core::{Color, Direction, Piece, PlacedPiece, Shape, Square};
|
||||
use chessfriend_moves::{Castle, Move};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum MakeMoveError {
|
||||
PlayerOutOfTurn,
|
||||
NoPiece,
|
||||
NoCapturedPiece,
|
||||
NoLegalMoves,
|
||||
IllegalCastle,
|
||||
IllegalSquare(Square),
|
||||
}
|
||||
|
||||
/// A position builder that builds a new position by making a move.
|
||||
#[derive(Clone)]
|
||||
|
|
@ -51,14 +62,14 @@ where
|
|||
M: MoveToMake,
|
||||
{
|
||||
pub fn make(self, mv: &Move) -> Result<Builder<'p, ValidatedMove>, MakeMoveError> {
|
||||
let from_square = mv.from_square();
|
||||
let origin_square = mv.origin_square();
|
||||
|
||||
let piece = self
|
||||
.position
|
||||
.piece_on_square(from_square)
|
||||
.piece_on_square(origin_square)
|
||||
.ok_or(MakeMoveError::NoPiece)?;
|
||||
|
||||
let to_square = mv.to_square();
|
||||
let target_square = mv.target_square();
|
||||
|
||||
let moves = self
|
||||
.position
|
||||
|
|
@ -72,8 +83,8 @@ where
|
|||
}
|
||||
}
|
||||
None => {
|
||||
if !moves.can_move_to_square(to_square) {
|
||||
return Err(MakeMoveError::IllegalSquare(to_square));
|
||||
if !moves.can_move_to_square(target_square) {
|
||||
return Err(MakeMoveError::IllegalSquare(target_square));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -83,8 +94,8 @@ where
|
|||
let captured_piece = if mv.is_en_passant() {
|
||||
// En passant captures the pawn directly ahead (in the player's direction) of the en passant square.
|
||||
let capture_square = match player {
|
||||
Color::White => to_square.neighbor(Direction::South),
|
||||
Color::Black => to_square.neighbor(Direction::North),
|
||||
Color::White => target_square.neighbor(Direction::South),
|
||||
Color::Black => target_square.neighbor(Direction::North),
|
||||
}
|
||||
.ok_or(MakeMoveError::NoCapturedPiece)?;
|
||||
|
||||
|
|
@ -96,7 +107,7 @@ where
|
|||
} else if mv.is_capture() {
|
||||
Some(
|
||||
self.position
|
||||
.piece_on_square(to_square)
|
||||
.piece_on_square(target_square)
|
||||
.ok_or(MakeMoveError::NoCapturedPiece)?,
|
||||
)
|
||||
} else {
|
||||
|
|
@ -140,8 +151,8 @@ where
|
|||
} else {
|
||||
let en_passant_square: Option<Square> = if mv.is_double_push() {
|
||||
match piece.color() {
|
||||
Color::White => to_square.neighbor(Direction::South),
|
||||
Color::Black => to_square.neighbor(Direction::North),
|
||||
Color::White => target_square.neighbor(Direction::South),
|
||||
Color::Black => target_square.neighbor(Direction::North),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
|
@ -150,8 +161,8 @@ where
|
|||
Ok(Builder {
|
||||
position: self.position,
|
||||
move_to_make: ValidatedMove::RegularMove {
|
||||
from_square,
|
||||
to_square,
|
||||
from_square: origin_square,
|
||||
to_square: target_square,
|
||||
moving_piece: piece,
|
||||
captured_piece,
|
||||
promotion: mv.promotion(),
|
||||
|
|
@ -219,18 +230,19 @@ impl<'p> Builder<'p, ValidatedMove> {
|
|||
} => {
|
||||
let mut pieces = self.position.piece_bitboards().clone();
|
||||
|
||||
let target_squares = castle.target_squares(player);
|
||||
let parameters = castle.parameters(player);
|
||||
|
||||
let king_from: BitBoard = king.square().into();
|
||||
let king_to: BitBoard = target_squares.king.into();
|
||||
*pieces.bitboard_for_piece_mut(king.piece()) ^= king_from | king_to;
|
||||
let king_origin_square: BitBoard = king.square().into();
|
||||
let king_target_square: BitBoard = parameters.king_target_square().into();
|
||||
*pieces.bitboard_for_piece_mut(king.piece()) ^=
|
||||
king_origin_square | king_target_square;
|
||||
|
||||
let rook_from: BitBoard = rook.square().into();
|
||||
let rook_to: BitBoard = target_squares.rook.into();
|
||||
let rook_to: BitBoard = parameters.rook_target_square().into();
|
||||
*pieces.bitboard_for_piece_mut(rook.piece()) ^= rook_from | rook_to;
|
||||
|
||||
*pieces.bitboard_for_color_mut(player) &=
|
||||
!(king_from | rook_from) | (king_to | rook_to);
|
||||
!(king_origin_square | rook_from) | (king_target_square | rook_to);
|
||||
|
||||
Position::new(
|
||||
player.other(),
|
||||
|
|
@ -257,15 +269,24 @@ impl<'p> From<&'p Position> for Builder<'p, NoMove> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{position, r#move::Castle, MoveBuilder, PositionBuilder};
|
||||
use crate::testing::*;
|
||||
use crate::{position, PositionBuilder};
|
||||
use chessfriend_core::piece;
|
||||
use chessfriend_moves::Builder as MoveBuilder;
|
||||
|
||||
#[test]
|
||||
fn move_white_pawn_one_square() -> Result<(), MakeMoveError> {
|
||||
fn move_white_pawn_one_square() -> TestResult {
|
||||
let pos = position![White Pawn on E2];
|
||||
let mv = MoveBuilder::new(piece!(White Pawn), Square::E2, Square::E3).build();
|
||||
let mv = MoveBuilder::new()
|
||||
.from(Square::E2)
|
||||
.to(Square::E3)
|
||||
.build()
|
||||
.map_err(TestError::BuildMove)?;
|
||||
|
||||
let new_position = Builder::<NoMove>::new(&pos).make(&mv)?.build();
|
||||
let new_position = Builder::<NoMove>::new(&pos)
|
||||
.make(&mv)
|
||||
.map_err(|err| TestError::MakeMove(err))?
|
||||
.build();
|
||||
println!("{}", &new_position);
|
||||
|
||||
assert_eq!(
|
||||
|
|
@ -277,9 +298,13 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn move_white_pawn_two_squares() -> Result<(), MakeMoveError> {
|
||||
fn move_white_pawn_two_squares() -> TestResult {
|
||||
let pos = position![White Pawn on E2];
|
||||
let mv = MoveBuilder::new(piece!(White Pawn), Square::E2, Square::E4).build();
|
||||
let mv = MoveBuilder::new()
|
||||
.from(Square::E2)
|
||||
.to(Square::E4)
|
||||
.build()
|
||||
.map_err(TestError::BuildMove)?;
|
||||
|
||||
let new_position = Builder::<NoMove>::new(&pos).make(&mv)?.build();
|
||||
println!("{}", &new_position);
|
||||
|
|
@ -308,9 +333,7 @@ mod tests {
|
|||
];
|
||||
println!("{}", &pos);
|
||||
|
||||
let mv = MoveBuilder::new(piece!(White King), Square::E1, Square::G1)
|
||||
.castle(Castle::KingSide)
|
||||
.build();
|
||||
let mv = MoveBuilder::castling(Castle::KingSide).build();
|
||||
|
||||
let new_position = Builder::<NoMove>::new(&pos).make(&mv)?.build();
|
||||
println!("{}", &new_position);
|
||||
|
|
@ -328,7 +351,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn en_passant_capture() -> Result<(), MakeMoveError> {
|
||||
fn en_passant_capture() -> TestResult {
|
||||
let pos = PositionBuilder::new()
|
||||
.place_piece(piece!(White Pawn on B5))
|
||||
.place_piece(piece!(Black Pawn on A7))
|
||||
|
|
@ -336,7 +359,8 @@ mod tests {
|
|||
.build();
|
||||
println!("{pos}");
|
||||
|
||||
let black_pawn_move = MoveBuilder::new(piece!(Black Pawn), Square::A7, Square::A5).build();
|
||||
let black_pawn_move = MoveBuilder::new().from(Square::A7).to(Square::A5).build()?;
|
||||
|
||||
assert!(black_pawn_move.is_double_push());
|
||||
assert!(!black_pawn_move.is_en_passant());
|
||||
|
||||
|
|
@ -352,9 +376,9 @@ mod tests {
|
|||
Some(piece!(White Pawn on B5))
|
||||
);
|
||||
|
||||
let white_pawn_capture = MoveBuilder::new(piece!(White Pawn), Square::B5, Square::A6)
|
||||
.capturing_en_passant(piece!(Black Pawn on A5))
|
||||
.build();
|
||||
let white_pawn_capture = MoveBuilder::push(&piece!(White Pawn on B5))
|
||||
.capturing_en_passant_on(Square::A5)
|
||||
.build()?;
|
||||
let en_passant_capture = Builder::<NoMove>::new(&en_passant_position)
|
||||
.make(&white_pawn_capture)?
|
||||
.build();
|
||||
|
|
|
|||
|
|
@ -120,13 +120,13 @@ impl Builder {
|
|||
|
||||
for color in Color::ALL {
|
||||
for castle in Castle::ALL {
|
||||
let starting_squares = castle.starting_squares(color);
|
||||
let parameters = castle.parameters(color);
|
||||
let has_rook_on_starting_square = self
|
||||
.pieces
|
||||
.get(&starting_squares.rook)
|
||||
.get(¶meters.rook_origin_square())
|
||||
.is_some_and(|piece| piece.shape() == Shape::Rook);
|
||||
let king_is_on_starting_square =
|
||||
self.kings[color as usize] == Some(starting_squares.king);
|
||||
self.kings[color as usize] == Some(parameters.king_origin_square());
|
||||
|
||||
if !king_is_on_starting_square || !has_rook_on_starting_square {
|
||||
flags.clear_player_has_right_to_castle_flag(color, castle);
|
||||
|
|
|
|||
|
|
@ -45,8 +45,6 @@ impl Default for Flags {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::r#move::Castle;
|
||||
use chessfriend_core::Color;
|
||||
|
||||
#[test]
|
||||
fn castle_flags() {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ mod pieces;
|
|||
mod position;
|
||||
|
||||
pub use {
|
||||
builders::{MoveBuilder, PositionBuilder},
|
||||
builders::{MakeMoveError, MoveBuilder, PositionBuilder},
|
||||
diagram_formatter::DiagramFormatter,
|
||||
pieces::Pieces,
|
||||
position::Position,
|
||||
|
|
|
|||
|
|
@ -372,9 +372,10 @@ impl fmt::Display for Position {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{position, test_position, Castle, Position, PositionBuilder};
|
||||
use super::*;
|
||||
use crate::{position, test_position, Position, PositionBuilder};
|
||||
use chessfriend_bitboard::bitboard;
|
||||
use chessfriend_core::{piece, Color, Square};
|
||||
use chessfriend_core::piece;
|
||||
|
||||
#[test]
|
||||
fn piece_on_square() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue