diff options
Diffstat (limited to 'src/board')
-rw-r--r-- | src/board/engine.rs | 69 | ||||
-rw-r--r-- | src/board/mod.rs | 2 |
2 files changed, 39 insertions, 32 deletions
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 { |