[moves] Add several macros to help with testing: ply! and assert_move_list!
ply! implements a small DSL for writing moves in code using a natural-ish algebraic notation. assert_move_list! takes a generator and an expected list of moves and asserts that they're equal. This macro is mostly a copy from one I wrote earlier in the position crate.
This commit is contained in:
parent
09bf17d66b
commit
3f3842c7c8
4 changed files with 90 additions and 0 deletions
|
@ -2,6 +2,9 @@
|
|||
|
||||
mod pawn;
|
||||
|
||||
#[cfg(test)]
|
||||
mod testing;
|
||||
|
||||
pub use pawn::PawnMoveGenerator;
|
||||
|
||||
use crate::Move;
|
||||
|
@ -11,6 +14,12 @@ pub struct GeneratedMove {
|
|||
pub(crate) ply: Move,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for GeneratedMove {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.ply.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Move> for GeneratedMove {
|
||||
fn from(value: Move) -> Self {
|
||||
GeneratedMove { ply: value }
|
||||
|
|
31
moves/src/generators/testing.rs
Normal file
31
moves/src/generators/testing.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_move_list {
|
||||
($generator:expr, [ $($expected:expr),* $(,)? ]) => {
|
||||
{
|
||||
let generated_moves: std::collections::HashSet<$crate::GeneratedMove> = $generator.collect();
|
||||
let expected_moves: std::collections::HashSet<$crate::GeneratedMove> = [
|
||||
$($expected.into(),)*
|
||||
].into();
|
||||
|
||||
assert_eq!(
|
||||
generated_moves,
|
||||
expected_moves,
|
||||
"\n\tMatching: {:?}\n\tGenerated, not expected: {:?}\n\tExpected, not generated: {:?}",
|
||||
generated_moves
|
||||
.intersection(&expected_moves)
|
||||
.map(|mv| format!("{}", mv))
|
||||
.collect::<Vec<String>>(),
|
||||
generated_moves
|
||||
.difference(&expected_moves)
|
||||
.map(|mv| format!("{}", mv))
|
||||
.collect::<Vec<String>>(),
|
||||
expected_moves
|
||||
.difference(&generated_moves)
|
||||
.map(|mv| format!("{}", mv))
|
||||
.collect::<Vec<String>>(),
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -9,4 +9,5 @@ mod moves;
|
|||
|
||||
pub use builder::{Builder, Error as BuildMoveError, Result as BuildMoveResult};
|
||||
pub use defs::{Kind, PromotionShape};
|
||||
pub use generators::GeneratedMove;
|
||||
pub use moves::Move;
|
||||
|
|
|
@ -4,6 +4,54 @@ use crate::defs::{Kind, PromotionShape};
|
|||
use chessfriend_core::{Rank, Shape, Square, Wing};
|
||||
use std::fmt;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! ply {
|
||||
($origin:ident - $target:ident) => {
|
||||
$crate::Move::quiet(
|
||||
chessfriend_core::Square::$origin,
|
||||
chessfriend_core::Square::$target,
|
||||
)
|
||||
};
|
||||
($origin:ident -- $target:ident) => {
|
||||
$crate::Move::double_push(
|
||||
chessfriend_core::Square::$origin,
|
||||
chessfriend_core::Square::$target,
|
||||
)
|
||||
};
|
||||
($origin:ident x $target:ident) => {
|
||||
$crate::Move::capture(
|
||||
chessfriend_core::Square::$origin,
|
||||
chessfriend_core::Square::$target,
|
||||
)
|
||||
};
|
||||
($origin:ident x $target:ident e$(.)?p$(.)?) => {
|
||||
$crate::Move::en_passant_capture(
|
||||
chessfriend_core::Square::$origin,
|
||||
chessfriend_core::Square::$target,
|
||||
)
|
||||
};
|
||||
($origin:ident x $target:ident = $promotion:ident) => {
|
||||
$crate::Move::capture_promotion(
|
||||
chessfriend_core::Square::$origin,
|
||||
chessfriend_core::Square::$target,
|
||||
$crate::PromotionShape::$promotion,
|
||||
)
|
||||
};
|
||||
($origin:ident - $target:ident = $promotion:ident) => {
|
||||
$crate::Move::promotion(
|
||||
chessfriend_core::Square::$origin,
|
||||
chessfriend_core::Square::$target,
|
||||
$crate::PromotionShape::$promotion,
|
||||
)
|
||||
};
|
||||
(0-0) => {
|
||||
$crate::Move::castle(chessfriend_core::Wing::KingSide)
|
||||
};
|
||||
(0-0-0) => {
|
||||
$crate::Move::castle(chessfriend_core::Wing::QueenSide)
|
||||
};
|
||||
}
|
||||
|
||||
/// A single player's move. In game theory parlance, this is a "ply".
|
||||
///
|
||||
/// ## TODO
|
||||
|
@ -39,6 +87,7 @@ impl Move {
|
|||
Move(origin_bits(origin) | target_bits(target) | flag_bits)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn capture_promotion(origin: Square, target: Square, shape: PromotionShape) -> Self {
|
||||
let flag_bits = Kind::CapturePromotion as u16;
|
||||
let shape_bits = shape as u16;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue