diff --git a/perft/scripts/check-positions b/perft/scripts/check-positions index e5f0626..a7b24ec 100755 --- a/perft/scripts/check-positions +++ b/perft/scripts/check-positions @@ -10,7 +10,7 @@ import json import subprocess -def run_perft(fen, depth, expected_nodes_count): +def run_perft(fen, depth): result = subprocess.run( [ 'cargo', @@ -26,8 +26,8 @@ def run_perft(fen, depth, expected_nodes_count): nodes_count = 0 for line in result.stdout.splitlines(): - if line.startswith('nodes='): - (_, nodes_count) = line.split('=') + if line.startswith('nodes '): + (_, nodes_count) = line.split(' ') nodes_count = int(nodes_count) return nodes_count @@ -61,7 +61,7 @@ def main(argv): print(f'depth={depth}') print(f'expected-nodes={expected_nodes_count}') - nodes_count = run_perft(fen, depth, expected_nodes_count) + nodes_count = run_perft(fen, depth) print(f'nodes={nodes_count}') did_pass = nodes_count == expected_nodes_count diff --git a/perft/src/main.rs b/perft/src/main.rs index 998e28a..70630ae 100644 --- a/perft/src/main.rs +++ b/perft/src/main.rs @@ -14,7 +14,7 @@ fn main() -> anyhow::Result<()> { let args = Arguments::parse(); let depth = args.depth; - println!("depth={depth}"); + println!("depth {depth}"); let mut position = if let Some(fen) = args.fen { Position::from_fen_str(&fen)? @@ -24,7 +24,7 @@ fn main() -> anyhow::Result<()> { let nodes_searched = position.perft(depth); - println!("nodes={nodes_searched}"); + println!("nodes {nodes_searched}"); Ok(()) } diff --git a/position/src/perft.rs b/position/src/perft.rs index 20257fb..57af81a 100644 --- a/position/src/perft.rs +++ b/position/src/perft.rs @@ -8,6 +8,12 @@ pub trait Perft { impl Perft for Position { fn perft(&mut self, depth: usize) -> u64 { + self.perft_recursive(depth, depth) + } +} + +impl Position { + fn perft_recursive(&mut self, depth: usize, max_depth: usize) -> u64 { if depth == 0 { return 1; } @@ -16,50 +22,22 @@ impl Perft for Position { let legal_moves: Vec = self.all_legal_moves(None).collect(); - for generated_ply in legal_moves { - let ply = generated_ply.ply(); + for ply in legal_moves { + let ply = ply.ply(); - let has_seen_position = self + let _has_seen_position = self .make_move(ply, ValidateMove::No) .expect("unable to make generated move"); - // Do not recursive into trees where board positions repeat. - let nodes_counted = if has_seen_position { - 1 - } else { - self.perft(depth - 1) - }; - - total_nodes_counted += nodes_counted; - - self.unmake_last_move().expect("unable to unmake last move"); - } - - total_nodes_counted - } -} - -impl Position { - fn perft_recursive(&mut self, depth: usize) -> u64 { - if depth == 0 { - return 1; - } - - let mut total_nodes_counted: u64 = 0; - - let legal_moves: Vec = self.all_legal_moves(None).collect(); - - for generated_ply in legal_moves { - let ply = generated_ply.ply(); - - self.make_move(ply, ValidateMove::No) - .expect("unable to make generated move"); - - let nodes_counted = self.perft_recursive(depth - 1); + let nodes_counted = self.perft_recursive(depth - 1, depth); total_nodes_counted += nodes_counted; self.unmake_last_move().expect("unable to unmake last move"); + + if depth == max_depth { + println!(" {ply} {nodes_counted}"); + } } total_nodes_counted