[perft] A small Perft program
This commit is contained in:
parent
ae0ae49093
commit
0167794346
4 changed files with 80 additions and 1 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -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"
|
||||||
|
|
|
@ -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
11
perft/Cargo.toml
Normal 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
57
perft/src/main.rs
Normal 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(())
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue