[position, moves] Implement some castling tests
Add white castling for both wings. Found some bugs in how king sight is computed while writing these. In order for the king to perform the castle, the Movement bitboard needs to return the two squares the king can castle to. That means anytime movement is calculated for the king, the (relatively expensive) castling evaluation needs to happen. Write two new helper static functions to create a Move for castling and promotion moves. Since structs cannot have any functions with the same name, the two methods that return properties related to those moves (Move::castle and Move::promotion) need to be renamed. They're now called Move::castle_wing and Move::promotion_shape.
This commit is contained in:
parent
7c9c5484ba
commit
feaa81bbd8
5 changed files with 99 additions and 27 deletions
|
@ -13,45 +13,52 @@ use std::fmt;
|
|||
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
||||
pub struct Move(pub(crate) u16);
|
||||
|
||||
fn origin_bits(square: Square) -> u16 {
|
||||
(square as u16) << 4
|
||||
}
|
||||
|
||||
fn target_bits(square: Square) -> u16 {
|
||||
(square as u16) << 10
|
||||
}
|
||||
|
||||
impl Move {
|
||||
#[must_use]
|
||||
pub fn quiet(origin: Square, target: Square) -> Self {
|
||||
let origin_bits = (origin as u16) << 4;
|
||||
let target_bits = (target as u16) << 10;
|
||||
Move(origin_bits | target_bits)
|
||||
Move(origin_bits(origin) | target_bits(target))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn double_push(origin: Square, target: Square) -> Self {
|
||||
let origin_bits = (origin as u16) << 4;
|
||||
let target_bits = (target as u16) << 10;
|
||||
let flag_bits = Kind::DoublePush as u16;
|
||||
Move(origin_bits | target_bits | flag_bits)
|
||||
Move(origin_bits(origin) | target_bits(target) | flag_bits)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn capture(origin: Square, target: Square) -> Self {
|
||||
let origin_bits = (origin as u16) << 4;
|
||||
let target_bits = (target as u16) << 10;
|
||||
let flag_bits = Kind::Capture as u16;
|
||||
Move(origin_bits | target_bits | flag_bits)
|
||||
Move(origin_bits(origin) | target_bits(target) | flag_bits)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn en_passant_capture(origin: Square, target: Square) -> Self {
|
||||
let origin_bits = (origin as u16) << 4;
|
||||
let target_bits = (target as u16) << 10;
|
||||
let flag_bits = Kind::EnPassantCapture as u16;
|
||||
Move(origin_bits | target_bits | flag_bits)
|
||||
Move(origin_bits(origin) | target_bits(target) | flag_bits)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn promotion(origin: Square, target: Square, shape: PromotionShape) -> Self {
|
||||
let origin_bits = (origin as u16) << 4;
|
||||
let target_bits = (target as u16) << 10;
|
||||
let flag_bits = Kind::Promotion as u16;
|
||||
let shape_bits = shape as u16;
|
||||
Move(origin_bits | target_bits | flag_bits | shape_bits)
|
||||
Move(origin_bits(origin) | target_bits(target) | flag_bits | shape_bits)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn castle(origin: Square, target: Square, wing: Wing) -> Self {
|
||||
let flag_bits = match wing {
|
||||
Wing::KingSide => Kind::KingSideCastle,
|
||||
Wing::QueenSide => Kind::QueenSideCastle,
|
||||
} as u16;
|
||||
Move(origin_bits(origin) | target_bits(target) | flag_bits)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +109,7 @@ impl Move {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn castle(&self) -> Option<Wing> {
|
||||
pub fn castle_wing(&self) -> Option<Wing> {
|
||||
match self.flags() {
|
||||
0b0010 => Some(Wing::KingSide),
|
||||
0b0011 => Some(Wing::QueenSide),
|
||||
|
@ -168,7 +175,7 @@ const QUEENSIDE_CASTLE_STR: &str = "0-0-0";
|
|||
|
||||
impl fmt::Display for Move {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if let Some(castle) = self.castle() {
|
||||
if let Some(castle) = self.castle_wing() {
|
||||
return match castle {
|
||||
Wing::KingSide => write!(f, "{KINGSIDE_CASTLE_STR}"),
|
||||
Wing::QueenSide => write!(f, "{QUEENSIDE_CASTLE_STR}"),
|
||||
|
|
|
@ -78,7 +78,7 @@ fn move_flags_promotion() -> TestResult {
|
|||
.build()?;
|
||||
|
||||
assert!(ply.is_promotion());
|
||||
assert_eq!(ply.promotion(), Some(Shape::Queen));
|
||||
assert_eq!(ply.promotion_shape(), Some(Shape::Queen));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ fn move_flags_capture_promotion() -> TestResult {
|
|||
|
||||
assert!(ply.is_capture());
|
||||
assert!(ply.is_promotion());
|
||||
assert_eq!(ply.promotion(), Some(Shape::Queen));
|
||||
assert_eq!(ply.promotion_shape(), Some(Shape::Queen));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue