chess/
perft.rs

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            //let unmake_move = pos.make_move(mv);
43            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 mut tt = transposition::TranspositionTable::new(); // not included in duration
94    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}