Implement a new method on Position that evaluates whether the active color can castle on a given wing of the board. Then, implement making a castling move in the position. Make a new Wing enum in the core crate to specify kingside or queenside. Replace the Castle enum from the board crate with this one. This caused a lot of churn... Along the way fix a bunch of tests. Note: there's still no way to actually make a castling move in explorer.
108 lines
2.9 KiB
Rust
108 lines
2.9 KiB
Rust
// Eryn Wells <eryn@erynwells.me>
|
|
|
|
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(), 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(), 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(())
|
|
}
|