aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2023-01-24 21:56:57 +0300
committereug-vs <eugene@eug-vs.xyz>2023-01-24 21:58:09 +0300
commita5fce018294f63cf153b1d9ecc1cb28e82f12c28 (patch)
tree8446b19091f78ea4056cee8ce26e79283f5bc332
parente27b950db851c91231abf3f3a3afebae18af47af (diff)
downloadchessnost-a5fce018294f63cf153b1d9ecc1cb28e82f12c28.tar.gz
refactor: abstract perft result into a structure
-rw-r--r--benches/perft.rs5
-rw-r--r--src/board/engine.rs69
-rw-r--r--src/board/mod.rs2
3 files changed, 42 insertions, 34 deletions
diff --git a/benches/perft.rs b/benches/perft.rs
index c73208f..1d82ed5 100644
--- a/benches/perft.rs
+++ b/benches/perft.rs
@@ -5,7 +5,8 @@ fn main() {
let fen = String::from("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - ");
let mut board = Board::from_FEN(fen);
+ let depth = 4;
let start = Instant::now();
- let result = board.perft(5, false);
- println!("Perft finished in {:?}: {:?}", start.elapsed(), result);
+ let result = board.perft(depth, false);
+ println!("Perft({}) finished in {:?}: {:?}", depth, start.elapsed(), result);
}
diff --git a/src/board/engine.rs b/src/board/engine.rs
index c8b174f..61d9fda 100644
--- a/src/board/engine.rs
+++ b/src/board/engine.rs
@@ -1,9 +1,21 @@
use crate::{bitboard::pop_count, board::*};
+#[derive(Debug, Default, PartialEq)]
+pub struct PerftResult {
+ leaf_nodes: u64,
+ captures: u64,
+ en_passants: u64,
+ castles: u64,
+ checks: u64,
+}
+
impl Board {
- pub fn perft(&mut self, depth: u8, print: bool) -> (u64, u64, u64, u64, u64) {
+ pub fn perft(&mut self, depth: u8, print: bool) -> PerftResult {
+ let mut result = PerftResult::default();
+
if depth == 0 {
- return (1, 0, 0, 0, 0) // This a leaf, exactly one node
+ result.leaf_nodes = 1;
+ return result;
}
let color = self.color_to_move();
@@ -14,12 +26,6 @@ impl Board {
println!("{} moves available", moves.len());
}
- let mut total = 0;
- let mut captures = 0;
- let mut checks = 0;
- let mut castles = 0;
- let mut en_passants = 0;
-
for mov in moves {
let ep_target_before = self.ep_target.clone();
let castling_rights_before = self.castling_rights.clone();
@@ -29,19 +35,19 @@ impl Board {
if depth == 1 {
match mov.kind {
MoveKind::Capture => {
- captures += 1;
+ result.captures += 1;
}
MoveKind::EnPassant => {
- en_passants += 1;
- captures += 1;
+ result.en_passants += 1;
+ result.captures += 1;
}
MoveKind::Castle => {
- castles += 1;
+ result.castles += 1;
}
_ => {}
}
if self.is_king_in_check(color.flip()) {
- checks += 1;
+ result.checks += 1;
}
}
@@ -49,22 +55,23 @@ impl Board {
println!("{:?}", mov);
self.print();
}
- let (children_total, children_tactical, children_checks, children_castles, children_ep) = self.perft(depth - 1, print);
- total += children_total;
- captures += children_tactical;
- checks += children_checks;
- castles += children_castles;
- en_passants += children_ep;
+ let subtree_result = self.perft(depth - 1, print);
+
+ result.leaf_nodes += subtree_result.leaf_nodes;
+ result.captures += subtree_result.captures;
+ result.checks += subtree_result.checks;
+ result.castles += subtree_result.castles;
+ result.en_passants += subtree_result.en_passants;
}
self.unmake_move(mov, captured_piece, ep_target_before, castling_rights_before);
}
if print {
- println!("Found {} nodes in this subtree (depth {})", total, depth);
+ println!("Found {} leaf nodes in this subtree (depth {})", result.leaf_nodes, depth);
}
- (total, captures, checks, castles, en_passants)
+ result
}
pub fn evaluate(&self) -> f32 {
let mut eval = 0f32;
@@ -116,17 +123,17 @@ impl Board {
mod tests {
use std::f32::INFINITY;
- use crate::board::Board;
+ use crate::board::{Board, engine::PerftResult};
#[test]
fn perft() {
let mut board = Board::new();
- assert_eq!(board.perft(0, false), (1, 0, 0, 0, 0));
- assert_eq!(board.perft(1, false), (20, 0, 0, 0, 0));
- assert_eq!(board.perft(2, false), (400, 0, 0, 0, 0));
- assert_eq!(board.perft(3, false), (8902, 34, 12, 0, 0));
- assert_eq!(board.perft(4, false), (197281, 1576, 469, 0, 0));
+ assert_eq!(board.perft(0, false), PerftResult { leaf_nodes: 1, captures: 0, en_passants: 0, castles: 0 , checks: 0 });
+ assert_eq!(board.perft(1, false), PerftResult { leaf_nodes: 20, captures: 0, en_passants: 0, castles: 0 , checks: 0 });
+ assert_eq!(board.perft(2, false), PerftResult { leaf_nodes: 400, captures: 0, en_passants: 0, castles: 0 , checks: 0 });
+ assert_eq!(board.perft(3, false), PerftResult { leaf_nodes: 8902, captures: 34, en_passants: 0, castles: 0 , checks: 12 });
+ assert_eq!(board.perft(4, false), PerftResult { leaf_nodes: 197281, captures: 1576, en_passants: 0, castles: 0 , checks: 469 });
// assert_eq!(board.perft(5, false), (4865609, 82719, 27351, 0, 258));
// assert_eq!(board.perft(6, false), (119060324, 2812008, 809099, 0, 5248));
}
@@ -135,10 +142,10 @@ mod tests {
fn position_perft() {
let fen = String::from("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - ");
let mut board = Board::from_FEN(fen);
- assert_eq!(board.perft(0, false), (1, 0, 0, 0, 0));
- assert_eq!(board.perft(1, false), (48, 8, 0, 2, 0));
- assert_eq!(board.perft(2, false), (2039, 351, 3, 91, 1));
- assert_eq!(board.perft(3, false), (97862, 17102, 993, 3162, 45));
+ assert_eq!(board.perft(0, false), PerftResult { leaf_nodes: 1, captures: 0, en_passants: 0, castles: 0 , checks: 0 });
+ assert_eq!(board.perft(1, false), PerftResult { leaf_nodes: 48, captures: 8, en_passants: 0, castles: 2 , checks: 0 });
+ assert_eq!(board.perft(2, false), PerftResult { leaf_nodes: 2039, captures: 351, en_passants: 1, castles: 91 , checks: 3 });
+ assert_eq!(board.perft(3, false), PerftResult { leaf_nodes: 97862, captures: 17102, en_passants: 45, castles: 3162, checks: 993 });
}
#[test]
diff --git a/src/board/mod.rs b/src/board/mod.rs
index 10d0a73..e2d4d60 100644
--- a/src/board/mod.rs
+++ b/src/board/mod.rs
@@ -1,4 +1,4 @@
-use crate::{bitboard::{Bitboard, serialize_bitboard, bitscan, pop_count}, moves::{Move, MoveKind}, attacks::Attacks, square::Square};
+use crate::{bitboard::{Bitboard, serialize_bitboard, bitscan}, moves::{Move, MoveKind}, attacks::Attacks, square::Square};
mod engine;
pub enum CastlingSide {