[perft, position] Print moves and nodes counted at first level
At the first level of depth, print the move and the number of nodes counted in the tree underneath that node. This behavior imitates Stockfish, and helps with debugging. Clean up the output of the Perft binary, and update the check-positions script to compensate.
This commit is contained in:
parent
37cb9bcaa0
commit
d73630c85e
3 changed files with 20 additions and 42 deletions
|
@ -10,7 +10,7 @@ import json
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
def run_perft(fen, depth, expected_nodes_count):
|
def run_perft(fen, depth):
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
[
|
[
|
||||||
'cargo',
|
'cargo',
|
||||||
|
@ -26,8 +26,8 @@ def run_perft(fen, depth, expected_nodes_count):
|
||||||
|
|
||||||
nodes_count = 0
|
nodes_count = 0
|
||||||
for line in result.stdout.splitlines():
|
for line in result.stdout.splitlines():
|
||||||
if line.startswith('nodes='):
|
if line.startswith('nodes '):
|
||||||
(_, nodes_count) = line.split('=')
|
(_, nodes_count) = line.split(' ')
|
||||||
nodes_count = int(nodes_count)
|
nodes_count = int(nodes_count)
|
||||||
|
|
||||||
return nodes_count
|
return nodes_count
|
||||||
|
@ -61,7 +61,7 @@ def main(argv):
|
||||||
print(f'depth={depth}')
|
print(f'depth={depth}')
|
||||||
print(f'expected-nodes={expected_nodes_count}')
|
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}')
|
print(f'nodes={nodes_count}')
|
||||||
|
|
||||||
did_pass = nodes_count == expected_nodes_count
|
did_pass = nodes_count == expected_nodes_count
|
||||||
|
|
|
@ -14,7 +14,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
let args = Arguments::parse();
|
let args = Arguments::parse();
|
||||||
let depth = args.depth;
|
let depth = args.depth;
|
||||||
|
|
||||||
println!("depth={depth}");
|
println!("depth {depth}");
|
||||||
|
|
||||||
let mut position = if let Some(fen) = args.fen {
|
let mut position = if let Some(fen) = args.fen {
|
||||||
Position::from_fen_str(&fen)?
|
Position::from_fen_str(&fen)?
|
||||||
|
@ -24,7 +24,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
let nodes_searched = position.perft(depth);
|
let nodes_searched = position.perft(depth);
|
||||||
|
|
||||||
println!("nodes={nodes_searched}");
|
println!("nodes {nodes_searched}");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,12 @@ pub trait Perft {
|
||||||
|
|
||||||
impl Perft for Position {
|
impl Perft for Position {
|
||||||
fn perft(&mut self, depth: usize) -> u64 {
|
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 {
|
if depth == 0 {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -16,50 +22,22 @@ impl Perft for Position {
|
||||||
|
|
||||||
let legal_moves: Vec<GeneratedMove> = self.all_legal_moves(None).collect();
|
let legal_moves: Vec<GeneratedMove> = self.all_legal_moves(None).collect();
|
||||||
|
|
||||||
for generated_ply in legal_moves {
|
for ply in legal_moves {
|
||||||
let ply = generated_ply.ply();
|
let ply = ply.ply();
|
||||||
|
|
||||||
let has_seen_position = self
|
let _has_seen_position = self
|
||||||
.make_move(ply, ValidateMove::No)
|
.make_move(ply, ValidateMove::No)
|
||||||
.expect("unable to make generated move");
|
.expect("unable to make generated move");
|
||||||
|
|
||||||
// Do not recursive into trees where board positions repeat.
|
let nodes_counted = self.perft_recursive(depth - 1, depth);
|
||||||
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<GeneratedMove> = 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);
|
|
||||||
|
|
||||||
total_nodes_counted += nodes_counted;
|
total_nodes_counted += nodes_counted;
|
||||||
|
|
||||||
self.unmake_last_move().expect("unable to unmake last move");
|
self.unmake_last_move().expect("unable to unmake last move");
|
||||||
|
|
||||||
|
if depth == max_depth {
|
||||||
|
println!(" {ply} {nodes_counted}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
total_nodes_counted
|
total_nodes_counted
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue