[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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "perft"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chessfriend_board",
|
||||
"chessfriend_position",
|
||||
"clap",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
|
|
|
@ -4,7 +4,7 @@ members = [
|
|||
"board",
|
||||
"core",
|
||||
"explorer",
|
||||
"moves",
|
||||
"moves", "perft",
|
||||
"position",
|
||||
]
|
||||
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