[perft] A small Perft program

This commit is contained in:
Eryn Wells 2025-06-08 17:19:00 -07:00
parent ae0ae49093
commit 0167794346
4 changed files with 80 additions and 1 deletions

11
Cargo.lock generated
View file

@ -295,6 +295,17 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "perft"
version = "0.1.0"
dependencies = [
"anyhow",
"chessfriend_board",
"chessfriend_position",
"clap",
"thiserror",
]
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.21" version = "0.2.21"

View file

@ -4,7 +4,7 @@ members = [
"board", "board",
"core", "core",
"explorer", "explorer",
"moves", "moves", "perft",
"position", "position",
] ]
resolver = "2" resolver = "2"

11
perft/Cargo.toml Normal file
View file

@ -0,0 +1,11 @@
[package]
name = "perft"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1.0.98"
chessfriend_board = { path = "../board" }
chessfriend_position = { path = "../position" }
clap = { version = "4.4.12", features = ["derive"] }
thiserror = "2"

57
perft/src/main.rs Normal file
View file

@ -0,0 +1,57 @@
use chessfriend_position::{fen::FromFenStr, GeneratedMove, Position, ValidateMove};
use clap::Parser;
#[derive(Parser, Debug)]
#[command(name = "Perft")]
struct Arguments {
depth: usize,
#[arg(long, short, value_name = "FEN")]
fen: Option<String>,
}
trait Perft {
fn perft(&mut self, depth: usize) -> u64;
}
impl Perft for Position {
fn perft(&mut self, depth: usize) -> u64 {
if depth == 0 {
return 1;
}
let mut nodes_counted: u64 = 0;
let legal_moves: Vec<GeneratedMove> = self.all_legal_moves(None).collect();
for generated_ply in legal_moves {
self.make_move(generated_ply.into(), ValidateMove::No)
.expect("unable to make generated move");
nodes_counted += self.perft(depth - 1);
self.unmake_last_move().expect("unable to unmake last move");
}
nodes_counted
}
}
fn main() -> anyhow::Result<()> {
let args = Arguments::parse();
let depth = args.depth;
println!("Searching to depth {depth}");
let mut position = if let Some(fen) = args.fen {
Position::from_fen_str(&fen)?
} else {
Position::starting(None)
};
let nodes_searched = position.perft(depth);
println!("Nodes searched: {nodes_searched}");
Ok(())
}