From 77660d21f884ad6d3d4718e5321a846914a02bad Mon Sep 17 00:00:00 2001 From: stefiosif Date: Mon, 3 Feb 2025 22:07:48 +0200 Subject: [PATCH] Add more tests --- src/board/game.rs | 203 ++++++++++--------------------------------- src/board/zobrist.rs | 152 +++++--------------------------- src/movegen/move.rs | 11 ++- src/search/perft.rs | 105 +++++++--------------- 4 files changed, 106 insertions(+), 365 deletions(-) diff --git a/src/board/game.rs b/src/board/game.rs index c551f67..954ac57 100644 --- a/src/board/game.rs +++ b/src/board/game.rs @@ -317,174 +317,61 @@ impl Default for Game { #[cfg(test)] mod tests { - use crate::{ - board::{fen::from_fen, square::Square}, - movegen::r#move::MoveType, - }; + use rstest::rstest; + + use crate::board::{fen::from_fen, square::Square}; use super::*; const FEN: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R w KQk g6 0 1"; - const FEN_QUIET: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2BQ3/1P1PNPP1/R3K2R b KQk - 1 1"; - #[test] - fn test_make_move_quiet() -> Result<(), String> { - let mut game = from_fen(FEN)?; - let f3e3 = Move::new(Square::F3, Square::E3); - game.make_move(&f3e3); + #[rstest] + #[rustfmt::skip] + #[case::quiet("b2b3", "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/PP1B1Q2/3PNPP1/R3K2R b KQk - 0 1")] + #[case::double_push("b2b4", "1r2k2r/2P1pq1p/2npb3/1p3ppP/pP2P3/P2B1Q2/3PNPP1/R3K2R b KQk b3 0 1")] + #[case::king_castle("e1g1", "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R4RK1 b k - 1 1")] + #[case::queen_castle("e1c1", "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/2KR3R b k - 1 1")] + #[case::capture("d3b5", "1r2k2r/2P1pq1p/2npb3/1B3ppP/p3P3/P4Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::en_passant("h5g6", "1r2k2r/2P1pq1p/2npb1P1/1p3p2/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_knight("c7c8n", "1rN1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_bishop("c7c8b", "1rB1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_rook("c7c8r", "1rR1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_queen("c7c8q", "1rQ1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_capture_knight("c7b8n", "1N2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_capture_bishop("c7b8b", "1B2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_capture_rook("c7b8r", "1R2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_capture_queen("c7b8q", "1Q2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + fn test_make_move(#[case] mv: &str, #[case] expected_fen: &str) { + let mut game = from_fen(FEN).unwrap(); + let mv = Move::parse_from_str(&game, mv).unwrap(); + game.make_move(&mv); - assert_eq!(game, from_fen(FEN_QUIET)?); - - Ok(()) + assert_eq!(game, from_fen(expected_fen).unwrap()); } - const FEN_CAPTURE: &str = "1r2k2r/2P1pq1p/2npb3/1p3QpP/p3P3/P2B4/1P1PNPP1/R3K2R b KQk - 0 1"; - - #[test] - fn test_make_move_capture() -> Result<(), String> { - let mut game = from_fen(FEN)?; - let f3f5 = Move::new_with_type(Square::F3, Square::F5, MoveType::Capture); - game.make_move(&f3f5); - - assert_eq!(game, from_fen(FEN_CAPTURE)?); - - Ok(()) - } - - const FEN_EN_PASSANT: &str = - "1r2k2r/2P1pq1p/2npb1P1/1p3p2/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1"; - - #[test] - fn test_make_move_en_passant() -> Result<(), String> { - let mut game = from_fen(FEN)?; - let h5g6 = Move::new_with_type(Square::H5, Square::G6, MoveType::EnPassant); - game.make_move(&h5g6); - - assert_eq!(game, from_fen(FEN_EN_PASSANT)?); - - Ok(()) - } - - const FEN_DOUBLE_PUSH: &str = - "1r2k2r/2P1pq1p/2npb3/1p3ppP/pP2P3/P2B1Q2/3PNPP1/R3K2R b KQk b3 0 1"; - - #[test] - fn test_make_move_double_push() -> Result<(), String> { - let mut game = from_fen(FEN)?; - let b2b4 = Move::new_with_type(Square::B2, Square::B4, MoveType::DoublePush); - game.make_move(&b2b4); - assert_eq!(game, from_fen(FEN_DOUBLE_PUSH)?); - - Ok(()) - } - - const FEN_PROMOTION: &str = "1rQ1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1"; - - #[test] - fn test_make_move_promotion() -> Result<(), String> { - let mut game = from_fen(FEN)?; - let c7c8 = Move::new_with_type(Square::C7, Square::C8, MoveType::PromotionQueen); - game.make_move(&c7c8); - assert_eq!(game, from_fen(FEN_PROMOTION)?); - - Ok(()) - } - - const FEN_PROMOTION_CAPTURE: &str = - "1Q2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1"; - - #[test] - fn test_make_move_promotion_capture() -> Result<(), String> { - let mut game = from_fen(FEN)?; - let c7b8 = Move::new_with_type(Square::C7, Square::B8, MoveType::PromotionCaptureQueen); - game.make_move(&c7b8); - assert_eq!(game, from_fen(FEN_PROMOTION_CAPTURE)?); - - Ok(()) - } - - const FEN_CASTLE: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R4RK1 b k - 1 1"; - - #[test] - fn test_make_move_castle() -> Result<(), String> { - let mut game = from_fen(FEN)?; - let e1g1 = Move::new_with_type(Square::E1, Square::G1, MoveType::KingCastle); - game.make_move(&e1g1); - assert_eq!(game, from_fen(FEN_CASTLE)?); - Ok(()) - } - - const FEN_1: &str = "1r2k2r/2P1p1qp/2npb3/1p3p2/p3P1pP/P2B1Q2/1P1PNPP1/R3K2R w KQk - 0 1"; - const FEN_2: &str = "1r2k2r/2P1p1qp/2npb3/1p3p2/pP2P1pP/P2B1Q2/3PNPP1/R3K2R b KQk b3 0 1"; - - #[test] - fn test_unmake_quiet_and_double_push() -> Result<(), String> { - let mut game = from_fen(FEN_1)?; - let game_before_make = game.clone(); - let mv = Move::new_with_type(Square::B2, Square::B3, MoveType::Quiet); + #[rstest] + #[case::quiet("b2b3")] + #[case::double_push("b2b4")] + #[case::king_castle("e1g1")] + #[case::queen_castle("e1c1")] + #[case::capture("d3b5")] + #[case::en_passant("h5g6")] + #[case::promotion_knight("c7c8n")] + #[case::promotion_bishop("c7c8b")] + #[case::promotion_rook("c7c8r")] + #[case::promotion_queen("c7c8q")] + #[case::promotion_capture_knight("c7b8n")] + #[case::promotion_capture_bishop("c7b8b")] + #[case::promotion_capture_rook("c7b8r")] + #[case::promotion_capture_queen("c7b8q")] + fn test_unmake_move(#[case] mv: &str) { + let mut game = from_fen(FEN).unwrap(); + let game_copy = game.clone(); + let mv = Move::parse_from_str(&game, mv).unwrap(); game.make_move(&mv); game.unmake_move(); - assert_eq!(game_before_make, game); - - let mv = Move::new_with_type(Square::B2, Square::B4, MoveType::DoublePush); - game.make_move(&mv); - game.unmake_move(); - - assert_eq!(game_before_make, game); - - Ok(()) - } - - #[test] - fn test_unmake_capture_and_promotion() -> Result<(), String> { - let mut game = from_fen(FEN_1)?; - let game_before_make = game.clone(); - let mv = Move::new_with_type(Square::D3, Square::B5, MoveType::Capture); - game.make_move(&mv); - game.unmake_move(); - - assert_eq!(game_before_make, game); - - let mv = Move::new_with_type(Square::C7, Square::C8, MoveType::PromotionQueen); - game.make_move(&mv); - game.unmake_move(); - - assert_eq!(game_before_make, game); - - let mv = Move::new_with_type(Square::C7, Square::B8, MoveType::PromotionCaptureQueen); - game.make_move(&mv); - game.unmake_move(); - - assert_eq!(game_before_make, game); - - Ok(()) - } - - #[test] - fn test_unmake_en_passant() -> Result<(), String> { - let mut game = from_fen(FEN_2)?; - let game_before_make = game.clone(); - let mv = Move::new_with_type(Square::A4, Square::B3, MoveType::EnPassant); - game.make_move(&mv); - game.unmake_move(); - - assert_eq!(game_before_make, game); - - Ok(()) - } - - #[test] - fn test_unmake_castle() -> Result<(), String> { - let mut game = from_fen(FEN_1)?; - let game_before_make = game.clone(); - let mv = Move::new_with_type(Square::E1, Square::C1, MoveType::KingCastle); - game.make_move(&mv); - game.unmake_move(); - - assert_eq!(game_before_make, game); - - Ok(()) + assert_eq!(game, game_copy); } #[test] @@ -512,13 +399,11 @@ mod tests { #[test] fn test_make_and_unmake_null_move() -> Result<(), String> { let mut game = from_fen(FEN_W)?; - game.make_null_move(); assert_eq!(game, from_fen(FEN_B)?); game.unmake_null_move(); - assert!(game == from_fen(FEN_W)?); Ok(()) diff --git a/src/board/zobrist.rs b/src/board/zobrist.rs index 261622f..622066a 100644 --- a/src/board/zobrist.rs +++ b/src/board/zobrist.rs @@ -209,138 +209,34 @@ impl ZobristHash { #[cfg(test)] mod tests { - use crate::{ - board::{fen::from_fen, square::Square}, - movegen::r#move::{Move, MoveType}, - }; + use crate::board::fen::from_fen; + use crate::movegen::r#move::Move; + use rstest::rstest; const FEN: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R w KQk g6 0 1"; - #[test] - fn test_identical_boards() -> Result<(), String> { - let game1 = from_fen(FEN)?; - let game2 = from_fen(FEN)?; - - assert_eq!(game1, game2); - - Ok(()) - } - - const FEN_QUIET: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2BQ3/1P1PNPP1/R3K2R b KQk - 1 1"; - - #[test] - fn test_update_quiet() -> Result<(), String> { - let mut incremental = from_fen(FEN)?; - incremental.make_move(&Move::new(Square::F3, Square::E3)); - let from_scratch = from_fen(FEN_QUIET)?; + #[rstest] + #[rustfmt::skip] + #[case::quiet("b2b3", "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/PP1B1Q2/3PNPP1/R3K2R b KQk - 0 1")] + #[case::double_push("b2b4", "1r2k2r/2P1pq1p/2npb3/1p3ppP/pP2P3/P2B1Q2/3PNPP1/R3K2R b KQk b3 0 1")] + #[case::king_castle("e1g1", "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R4RK1 b k - 1 1")] + #[case::queen_castle("e1c1", "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/2KR3R b k - 1 1")] + #[case::capture("d3b5", "1r2k2r/2P1pq1p/2npb3/1B3ppP/p3P3/P4Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::en_passant("h5g6", "1r2k2r/2P1pq1p/2npb1P1/1p3p2/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_knight("c7c8n", "1rN1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_bishop("c7c8b", "1rB1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_rook("c7c8r", "1rR1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_queen("c7c8q", "1rQ1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_capture_knight("c7b8n", "1N2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_capture_bishop("c7b8b", "1B2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_capture_rook("c7b8r", "1R2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + #[case::promotion_capture_queen("c7b8q", "1Q2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1")] + fn test_update(#[case] mv_str: &str, #[case] fen: &str) { + let mut incremental = from_fen(FEN).unwrap(); + let mv = Move::parse_from_str(&incremental, mv_str).unwrap(); + incremental.make_move(&mv); + let from_scratch = from_fen(fen).unwrap(); assert_eq!(incremental.hash, from_scratch.hash); - - Ok(()) - } - - const FEN_CAPTURE: &str = "1r2k2r/2P1pq1p/2npb3/1p3QpP/p3P3/P2B4/1P1PNPP1/R3K2R b KQk - 0 1"; - - #[test] - fn test_update_capture() -> Result<(), String> { - let mut incremental = from_fen(FEN)?; - incremental.make_move(&Move::new_with_type( - Square::F3, - Square::F5, - MoveType::Capture, - )); - let from_scratch = from_fen(FEN_CAPTURE)?; - - assert_eq!(incremental.hash, from_scratch.hash); - - Ok(()) - } - - const FEN_EN_PASSANT: &str = - "1r2k2r/2P1pq1p/2npb1P1/1p3p2/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1"; - - #[test] - fn test_update_en_passant() -> Result<(), String> { - let mut incremental = from_fen(FEN)?; - incremental.make_move(&Move::new_with_type( - Square::H5, - Square::G6, - MoveType::EnPassant, - )); - let from_scratch = from_fen(FEN_EN_PASSANT)?; - - assert_eq!(incremental.hash, from_scratch.hash); - - Ok(()) - } - - const FEN_DOUBLE_PUSH: &str = - "1r2k2r/2P1pq1p/2npb3/1p3ppP/pP2P3/P2B1Q2/3PNPP1/R3K2R b KQk b3 0 1"; - - #[test] - fn test_update_double_push() -> Result<(), String> { - let mut incremental = from_fen(FEN)?; - incremental.make_move(&Move::new_with_type( - Square::B2, - Square::B4, - MoveType::DoublePush, - )); - let from_scratch = from_fen(FEN_DOUBLE_PUSH)?; - - assert_eq!(incremental.hash, from_scratch.hash); - - Ok(()) - } - - const FEN_PROMOTION: &str = "1rQ1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1"; - - #[test] - fn test_update_promotion() -> Result<(), String> { - let mut incremental = from_fen(FEN)?; - incremental.make_move(&Move::new_with_type( - Square::C7, - Square::C8, - MoveType::PromotionQueen, - )); - let from_scratch = from_fen(FEN_PROMOTION)?; - - assert_eq!(incremental.hash, from_scratch.hash); - - Ok(()) - } - - const FEN_PROMOTION_CAPTURE: &str = - "1Q2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1"; - - #[test] - fn test_update_promotion_capture() -> Result<(), String> { - let mut incremental = from_fen(FEN)?; - incremental.make_move(&Move::new_with_type( - Square::C7, - Square::B8, - MoveType::PromotionCaptureQueen, - )); - let from_scratch = from_fen(FEN_PROMOTION_CAPTURE)?; - - assert_eq!(incremental.hash, from_scratch.hash); - - Ok(()) - } - - const FEN_CASTLE: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R4RK1 b k - 1 1"; - - #[test] - fn test_update_castle() -> Result<(), String> { - let mut incremental = from_fen(FEN)?; - incremental.make_move(&Move::new_with_type( - Square::E1, - Square::G1, - MoveType::KingCastle, - )); - let from_scratch = from_fen(FEN_CASTLE)?; - - assert_eq!(incremental.hash, from_scratch.hash); - - Ok(()) } } diff --git a/src/movegen/move.rs b/src/movegen/move.rs index 63c2b5a..b09520a 100644 --- a/src/movegen/move.rs +++ b/src/movegen/move.rs @@ -251,10 +251,10 @@ impl Move { #[cfg(test)] mod tests { + use super::Move; use crate::board::fen::from_fen; use crate::board::square::Square; use crate::movegen::r#move::MoveType; - use super::Move; use rstest::rstest; @@ -291,8 +291,12 @@ mod tests { "c7c8b" => Move::new_with_type(Square::C7, Square::C8, MoveType::PromotionBishop), "c7c8r" => Move::new_with_type(Square::C7, Square::C8, MoveType::PromotionRook), "c7c8q" => Move::new_with_type(Square::C7, Square::C8, MoveType::PromotionQueen), - "c7b8n" => Move::new_with_type(Square::C7, Square::B8, MoveType::PromotionCaptureKnight), - "c7b8b" => Move::new_with_type(Square::C7, Square::B8, MoveType::PromotionCaptureBishop), + "c7b8n" => { + Move::new_with_type(Square::C7, Square::B8, MoveType::PromotionCaptureKnight) + } + "c7b8b" => { + Move::new_with_type(Square::C7, Square::B8, MoveType::PromotionCaptureBishop) + } "c7b8r" => Move::new_with_type(Square::C7, Square::B8, MoveType::PromotionCaptureRook), "c7b8q" => Move::new_with_type(Square::C7, Square::B8, MoveType::PromotionCaptureQueen), _ => unreachable!(), @@ -301,7 +305,6 @@ mod tests { assert_eq!(expected, actual); } - #[rstest] #[case("c7c8qq")] #[should_panic(expected = "Invalid move characters length")] diff --git a/src/search/perft.rs b/src/search/perft.rs index 4d0667f..8ac0774 100644 --- a/src/search/perft.rs +++ b/src/search/perft.rs @@ -1,15 +1,20 @@ use crate::board::game::Game; -pub fn driver(game: &mut Game, nodes: &mut u64, depth: u8) { +pub fn driver(game: &mut Game, nodes: &mut u64, depth_nodes: &mut u64, depth: u8) { if depth == 0 { *nodes += 1; + *depth_nodes += 1; return; } let color = game.current_player(); let pseudo_moves = game.board.pseudo_moves_all(); + let current_depth_nodes = *depth_nodes; for mv in pseudo_moves { + if depth == MAX_DEPTH { + println!("{mv:?}"); + } game.make_move(&mv); if game.board.king_under_check(color) { @@ -17,18 +22,26 @@ pub fn driver(game: &mut Game, nodes: &mut u64, depth: u8) { continue; } - driver(game, nodes, depth - 1); + driver(game, nodes, depth_nodes, depth - 1); game.unmake_move(); } + + let nodes_at_current_depth = *depth_nodes - current_depth_nodes; + println!("Nodes at depth {depth}: {nodes_at_current_depth}"); } -const MAX_DEPTH: u8 = 3; +const MAX_DEPTH: u8 = 2; pub fn perftree_script() { let fen = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1"; let mut game = crate::board::fen::from_fen(fen).expect("Invalid FEN string"); - let (mut nodes, depth): (u64, u8) = (0, MAX_DEPTH); - driver(&mut game, &mut nodes, depth); + let mut nodes: u64 = 0; + let mut depth_nodes: u64 = 0; + let depth: u8 = MAX_DEPTH; + + driver(&mut game, &mut nodes, &mut depth_nodes, depth); + + println!("Total nodes: {nodes}"); } use std::collections::HashMap; @@ -57,9 +70,9 @@ pub fn _square_to_notation(square: u8) -> &'static str { #[cfg(test)] mod tests { - use crate::{board::fen::from_fen, movegen::attack_generator::init_attacks}; - use super::driver; + use crate::{board::fen::from_fen, movegen::attack_generator::init_attacks}; + use rstest::rstest; // Examples from https://www.chessprogramming.org/Perft_Results const FEN_PERFT: [&str; 6] = [ @@ -71,76 +84,20 @@ mod tests { "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10", ]; - fn perft(fen: &str, depth: u8) -> Result { + #[rstest] + #[case(0, 4865609)] + #[case(1, 193690690)] + #[case(2, 674624)] + #[case(3, 15833292)] + #[case(4, 89941194)] + #[case(5, 164075551)] + fn test_perft(#[case] num: usize, #[case] expected_nodes: u64) { init_attacks(); - let time_now = std::time::Instant::now(); - - let mut game = from_fen(fen)?; + let mut game = from_fen(FEN_PERFT[num]).unwrap(); let mut nodes = 0; - driver(&mut game, &mut nodes, depth); + driver(&mut game, &mut nodes, &mut 0, 5); - dbg!(nodes, time_now.elapsed()); - - Ok(nodes) - } - - const FEN: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R w KQk g6 0 1"; - - // #[ignore] - #[test] - fn test_nodes() -> Result<(), String> { - init_attacks(); - perft(FEN, 4)?; - - Ok(()) - } - - #[test] - fn test_perft_1() -> Result<(), String> { - init_attacks(); - assert_eq!(perft(FEN_PERFT[0], 5)?, 4865609); - - Ok(()) - } - - #[test] - fn test_perft_2() -> Result<(), String> { - init_attacks(); - assert_eq!(perft(FEN_PERFT[1], 5)?, 193690690); - - Ok(()) - } - - #[test] - fn test_perft_3() -> Result<(), String> { - init_attacks(); - assert_eq!(perft(FEN_PERFT[2], 5)?, 674624); - - Ok(()) - } - - #[test] - fn test_perft_4() -> Result<(), String> { - init_attacks(); - assert_eq!(perft(FEN_PERFT[3], 5)?, 15833292); - - Ok(()) - } - - #[test] - fn test_perft_5() -> Result<(), String> { - init_attacks(); - assert_eq!(perft(FEN_PERFT[4], 5)?, 89941194); - - Ok(()) - } - - #[test] - fn test_perft_6() -> Result<(), String> { - init_attacks(); - assert_eq!(perft(FEN_PERFT[5], 5)?, 164075551); - - Ok(()) + assert_eq!(nodes, expected_nodes); } }