2025-06-16 09:01:58 -07:00
|
|
|
// Eryn Wells <eryn@erynwells.me>
|
|
|
|
|
|
|
|
use crate::{GeneratedMove, Position, ValidateMove};
|
|
|
|
|
|
|
|
pub trait Perft {
|
|
|
|
fn perft(&mut self, depth: usize) -> u64;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Perft for Position {
|
|
|
|
fn perft(&mut self, depth: usize) -> u64 {
|
2025-06-17 16:17:46 -07:00
|
|
|
self.perft_recursive(depth, depth)
|
2025-06-16 09:01:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Position {
|
2025-06-17 16:17:46 -07:00
|
|
|
fn perft_recursive(&mut self, depth: usize, max_depth: usize) -> u64 {
|
2025-06-16 09:01:58 -07:00
|
|
|
if depth == 0 {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2025-06-17 16:17:46 -07:00
|
|
|
let mut total_nodes_counted = 0u64;
|
2025-06-16 09:01:58 -07:00
|
|
|
|
|
|
|
let legal_moves: Vec<GeneratedMove> = self.all_legal_moves(None).collect();
|
|
|
|
|
2025-06-17 16:17:46 -07:00
|
|
|
for ply in legal_moves {
|
|
|
|
let ply = ply.ply();
|
2025-06-16 09:01:58 -07:00
|
|
|
|
2025-06-17 16:17:46 -07:00
|
|
|
let _has_seen_position = self
|
|
|
|
.make_move(ply, ValidateMove::No)
|
2025-06-16 09:01:58 -07:00
|
|
|
.expect("unable to make generated move");
|
|
|
|
|
2025-06-17 16:17:46 -07:00
|
|
|
let nodes_counted = self.perft_recursive(depth - 1, depth);
|
2025-06-16 09:01:58 -07:00
|
|
|
|
|
|
|
total_nodes_counted += nodes_counted;
|
|
|
|
|
|
|
|
self.unmake_last_move().expect("unable to unmake last move");
|
2025-06-17 16:17:46 -07:00
|
|
|
|
|
|
|
if depth == max_depth {
|
|
|
|
println!(" {ply} {nodes_counted}");
|
|
|
|
}
|
2025-06-16 09:01:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
total_nodes_counted
|
|
|
|
}
|
|
|
|
}
|