1use std::time::Instant;
2
3use crate::position::Position;
4use crate::{engine, movegen::*, transposition, BoardState};
5
6fn get_all_legal_positions(
7 pos: &Position,
8 depth: u8,
9 nodes: &mut u64,
10 promotions: &mut u64,
11 castles: &mut u64,
12 en_passant: &mut u64,
13 captures: &mut u64,
14) {
15 let moves = pos.get_legal_moves();
16 if depth == 0 || moves.is_empty() {
17 return;
18 }
19 for mv in moves {
20 match mv.move_type {
21 MoveType::EnPassant(_) => {
22 *en_passant += 1;
23 }
24 MoveType::Promotion(_, capture) => {
25 *promotions += 1;
26 if capture.is_some() {
27 *captures += 1;
28 }
29 }
30 MoveType::Castle(_) => {
31 *castles += 1;
32 }
33 MoveType::Capture(_) => {
34 *captures += 1;
35 }
36 _ => {}
37 }
38 if depth == 1 {
39 *nodes += 1;
40 } else {
41 let p = pos.new_position(mv);
42 get_all_legal_positions(
44 &p,
45 depth - 1,
46 nodes,
47 promotions,
48 castles,
49 en_passant,
50 captures,
51 );
52 }
53 }
54}
55
56pub fn perft(pos: &Position, depth: u8) -> u64 {
57 let mut nodes: u64 = 0;
58 let mut promotions: u64 = 0;
59 let mut castles: u64 = 0;
60 let mut en_passant: u64 = 0;
61 let mut captures: u64 = 0;
62
63 let start = Instant::now();
64
65 get_all_legal_positions(
66 pos,
67 depth,
68 &mut nodes,
69 &mut promotions,
70 &mut castles,
71 &mut en_passant,
72 &mut captures,
73 );
74
75 let duration = start.elapsed();
76
77 println!(
78 "Perft at depth {} (took {:?} to complete):",
79 depth, duration
80 );
81 println!(" - Nodes: {}", nodes);
82 println!(" - Move types breakdown: ");
83 println!(" - Promotions: {}", promotions);
84 println!(" - Castles: {}", castles);
85 println!(" - En Passant: {}", en_passant);
86 println!(" - Captures: {}", captures);
87 println!();
88
89 nodes
90}
91
92pub fn engine_perft(bs: &BoardState, depth: u8, tt: &mut transposition::TranspositionTable) {
93 let start = Instant::now();
95 let (eval, mv) = engine::choose_move(bs, depth, tt);
96 let duration = start.elapsed();
97 println!(
98 "Engine perft at depth {} (took {:?} to complete):",
99 depth, duration
100 );
101 println!(" - Eval: {}", eval);
102 println!(" - Best move: {:?}", mv);
103 println!();
104}