Return a chessfriend_moves::EnPassant from a new Position::en_passant()
Replace Position's en_passant_target_square() and en_passant_capture_square() with a single en_passant() method that returns a new EnPassant struct that has the target and capture squares for the en passant move.
This commit is contained in:
parent
cc23ee2d90
commit
e6a9b7f8c4
8 changed files with 66 additions and 27 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -87,6 +87,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chessfriend_bitboard",
|
"chessfriend_bitboard",
|
||||||
"chessfriend_core",
|
"chessfriend_core",
|
||||||
|
"chessfriend_moves",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
49
moves/src/en_passant.rs
Normal file
49
moves/src/en_passant.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Eryn Wells <eryn@erynwells.me>
|
||||||
|
|
||||||
|
use chessfriend_core::{Rank, Square};
|
||||||
|
|
||||||
|
/// En passant information.
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct EnPassant {
|
||||||
|
target: Square,
|
||||||
|
capture: Square,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EnPassant {
|
||||||
|
fn _capture_square(target: Square) -> Option<Square> {
|
||||||
|
let (file, rank) = target.file_rank();
|
||||||
|
match rank {
|
||||||
|
Rank::THREE => Some(Square::from_file_rank(file, Rank::FOUR)),
|
||||||
|
Rank::SIX => Some(Square::from_file_rank(file, Rank::FIVE)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return en passant information for a particular target square. The target
|
||||||
|
/// square is the square a pawn capturing en passant will move to.
|
||||||
|
///
|
||||||
|
/// Return `None` if the square is not eligible for en passant.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use chessfriend_core::Square;
|
||||||
|
/// use chessfriend_moves::EnPassant;
|
||||||
|
/// assert!(EnPassant::from_target_square(Square::E3).is_some());
|
||||||
|
/// assert!(EnPassant::from_target_square(Square::B4).is_none());
|
||||||
|
/// ```
|
||||||
|
pub fn from_target_square(target: Square) -> Option<Self> {
|
||||||
|
match Self::_capture_square(target) {
|
||||||
|
Some(capture) => Some(Self { target, capture }),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn target_square(&self) -> Square {
|
||||||
|
self.target
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn capture_square(&self) -> Square {
|
||||||
|
self.capture
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,9 +3,11 @@
|
||||||
mod builder;
|
mod builder;
|
||||||
mod castle;
|
mod castle;
|
||||||
mod defs;
|
mod defs;
|
||||||
|
mod en_passant;
|
||||||
mod moves;
|
mod moves;
|
||||||
|
|
||||||
pub use builder::{Builder, Error as BuilderError};
|
pub use builder::{Builder, Error as BuilderError};
|
||||||
pub use castle::Castle;
|
pub use castle::Castle;
|
||||||
pub use defs::PromotionShape;
|
pub use defs::PromotionShape;
|
||||||
|
pub use en_passant::EnPassant;
|
||||||
pub use moves::Move;
|
pub use moves::Move;
|
||||||
|
|
|
@ -8,3 +8,4 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chessfriend_core = { path = "../core" }
|
chessfriend_core = { path = "../core" }
|
||||||
chessfriend_bitboard = { path = "../bitboard" }
|
chessfriend_bitboard = { path = "../bitboard" }
|
||||||
|
chessfriend_moves = { path = "../moves" }
|
||||||
|
|
|
@ -95,11 +95,8 @@ impl ToFen for Position {
|
||||||
write!(
|
write!(
|
||||||
fen_string,
|
fen_string,
|
||||||
" {}",
|
" {}",
|
||||||
if let Some(en_passant_square) = self.en_passant_target_square() {
|
self.en_passant()
|
||||||
en_passant_square.to_string()
|
.map_or("-".to_string(), |ep| ep.target_square().to_string())
|
||||||
} else {
|
|
||||||
"-".to_string()
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
.map_err(|err| ToFenError::FmtError(err))?;
|
.map_err(|err| ToFenError::FmtError(err))?;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
// Eryn Wells <eryn@erynwells.me>
|
// Eryn Wells <eryn@erynwells.me>
|
||||||
|
|
||||||
use crate::{
|
use crate::{position::flags::Flags, r#move::Castle, MakeMoveError, Move, Position};
|
||||||
position::flags::Flags,
|
|
||||||
r#move::{AlgebraicMoveFormatter, Castle},
|
|
||||||
MakeMoveError, Move, Position,
|
|
||||||
};
|
|
||||||
use chessfriend_bitboard::BitBoard;
|
use chessfriend_bitboard::BitBoard;
|
||||||
use chessfriend_core::{Color, Direction, Piece, PlacedPiece, Shape, Square};
|
use chessfriend_core::{Color, Direction, Piece, PlacedPiece, Shape, Square};
|
||||||
|
|
||||||
|
@ -292,7 +288,10 @@ mod tests {
|
||||||
new_position.piece_on_square(Square::E4),
|
new_position.piece_on_square(Square::E4),
|
||||||
Some(piece!(White Pawn on E4))
|
Some(piece!(White Pawn on E4))
|
||||||
);
|
);
|
||||||
assert_eq!(new_position.en_passant_target_square(), Some(Square::E3));
|
assert_eq!(
|
||||||
|
new_position.en_passant().map(|ep| ep.target_square()),
|
||||||
|
Some(Square::E3)
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ impl Builder {
|
||||||
flags: position.flags(),
|
flags: position.flags(),
|
||||||
pieces,
|
pieces,
|
||||||
kings: [Some(white_king), Some(black_king)],
|
kings: [Some(white_king), Some(black_king)],
|
||||||
en_passant_square: position.en_passant_target_square(),
|
en_passant_square: position.en_passant().map(|ep| ep.target_square()),
|
||||||
ply_counter: position.ply_counter(),
|
ply_counter: position.ply_counter(),
|
||||||
move_number: position.move_number(),
|
move_number: position.move_number(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use chessfriend_bitboard::BitBoard;
|
use chessfriend_bitboard::BitBoard;
|
||||||
use chessfriend_core::{Color, Piece, PlacedPiece, Rank, Shape, Square};
|
use chessfriend_core::{Color, Piece, PlacedPiece, Rank, Shape, Square};
|
||||||
|
use chessfriend_moves::EnPassant;
|
||||||
use std::{cell::OnceCell, fmt};
|
use std::{cell::OnceCell, fmt};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq)]
|
#[derive(Clone, Debug, Eq)]
|
||||||
|
@ -182,23 +183,12 @@ impl Position {
|
||||||
Pieces::new(&self, color)
|
Pieces::new(&self, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If en passant is available in this position, the square a pawn will move
|
pub fn has_en_passant_square(&self) -> bool {
|
||||||
/// to if it captures en passant.
|
self.en_passant_square.is_some()
|
||||||
pub fn en_passant_target_square(&self) -> Option<Square> {
|
|
||||||
self.en_passant_square
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If en passant is available in this position, the square on which the
|
pub fn en_passant(&self) -> Option<EnPassant> {
|
||||||
/// captured pawn is sitting.
|
EnPassant::from_target_square(self.en_passant_square?)
|
||||||
pub fn en_passant_capture_square(&self) -> Option<Square> {
|
|
||||||
let target_square = self.en_passant_square?;
|
|
||||||
|
|
||||||
let file = target_square.file();
|
|
||||||
Some(match target_square.rank() {
|
|
||||||
Rank::THREE => Square::from_file_rank(file, Rank::FOUR),
|
|
||||||
Rank::SIX => Square::from_file_rank(file, Rank::SEVEN),
|
|
||||||
_ => unreachable!(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _sight_of_player(&self, player: Color, pieces: &PieceBitBoards) -> BitBoard {
|
fn _sight_of_player(&self, player: Color, pieces: &PieceBitBoards) -> BitBoard {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue