From cb72b254db524a398c07ad9c63c13cbbbe8dbba0 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 24 Aug 2026 11:04:44 +0200 Subject: feat(tests): adding hash testing to new tests --- cli/src/main.rs | 105 ++++++++++++++++++++++++++++++++++++++++++++++-- scripts/perft | Bin 631864 -> 0 bytes scripts/test | Bin 0 -> 634488 bytes scripts/tests/hash.bash | 53 ------------------------ src/uci.cpp | 1 - 5 files changed, 101 insertions(+), 58 deletions(-) delete mode 100755 scripts/perft create mode 100755 scripts/test delete mode 100755 scripts/tests/hash.bash diff --git a/cli/src/main.rs b/cli/src/main.rs index 963544c..5a7fd96 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -22,6 +22,12 @@ pub struct PerftTest { pub expected: u64, } +pub struct HashTest { + pub position: &'static str, + pub moves: &'static str, + pub hash: u64, +} + pub const PERFT_TESTS: &[PerftTest; 17] = &[ PerftTest { position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", @@ -112,6 +118,72 @@ pub const PERFT_TESTS: &[PerftTest; 17] = &[ expected: 422333, }, ]; +pub const HASH_TESTS: &[HashTest; 12] = &[ + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "", + hash: 5060803636482931868, + }, + // one moves + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "d2d4", + hash: 9443689642921087454, + }, + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "e2e4", + hash: 9384546495678726550, + }, + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "c2c4", + hash: 14562399549841627035, + }, + // two moves + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "e2e4 e7e5", + hash: 595762792459712928, + }, + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "e2e4 c7c5", + hash: 7227515431820872427, + }, + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "e2e4 e7e6", + hash: 17603279437685838276, + }, + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "e2e4 c7c6", + hash: 1172755318016414253, + }, + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "d2d4 d7d5", + hash: 460664201775194104, + }, + // three moves + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "e2e4 e7e5 g1f3", + hash: 15213300192948443293, + }, + HashTest { + position: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", + moves: "d2d4 d7d5 c2c4", + hash: 9963937660605248767, + }, + // kiwipete + HashTest { + position: "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1", + moves: "", + hash: 14109232545397825053, + }, +]; impl ChessEngine { /// Spawns the engine process and initializes UCI mode @@ -186,8 +258,8 @@ fn test_perft(test: &PerftTest, engine: &mut ChessEngine) { let cmd = "perft ".to_string() + &test.depth.to_string(); engine.send_command(&cmd); - let line = engine.read_line(); - let result = parse_perft_result(&line); + let raw = engine.read_line(); + let result: Result = serde_json::from_str(&raw); match result { Err(err) => { println!("error: {}", err); @@ -208,8 +280,29 @@ fn test_perft(test: &PerftTest, engine: &mut ChessEngine) { } } } -fn parse_perft_result(raw: &str) -> Result { - serde_json::from_str(raw) + +fn test_hash(test: &HashTest, engine: &mut ChessEngine) { + let cmd = "position fen ".to_string() + &test.position + " moves " + &test.moves; + engine.send_command(&cmd); + + engine.send_command("hash"); + let line = engine.read_line(); + let hash: u64 = match line.trim().parse() { + Ok(num) => num, + Err(_) => { + println!("Failed to parse hash: {}", line); + std::process::exit(1) + } + }; + if hash == test.hash { + println!( + "passed {}: position: {}, moves: {}", + hash, test.position, test.moves + ); + } else { + println!("FAILED position: {}, moves: {}", test.position, test.moves); + std::process::exit(1); + } } fn main() { @@ -227,6 +320,10 @@ fn main() { engine.send_command("isready"); engine.wait_for_response("readyok"); + + for test in HASH_TESTS.iter() { + test_hash(&test, &mut engine); + } for test in PERFT_TESTS.iter() { test_perft(test, &mut engine); } diff --git a/scripts/perft b/scripts/perft deleted file mode 100755 index 1319086..0000000 Binary files a/scripts/perft and /dev/null differ diff --git a/scripts/test b/scripts/test new file mode 100755 index 0000000..f8095e9 Binary files /dev/null and b/scripts/test differ diff --git a/scripts/tests/hash.bash b/scripts/tests/hash.bash deleted file mode 100755 index 92be2e6..0000000 --- a/scripts/tests/hash.bash +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash - -status=0 - -testZobrist() { - local name="$1" - local fen="$2" - local moves="$3" - local expected="$4" - - echo "" - - resultRaw=$(./build/mono hash "$fen" $moves) - result=$(echo $resultRaw | jq -r '.hash') - took=$(echo $resultRaw | jq -r '.ms') - if [ "$result" = "$expected" ]; then - echo "OK: $name, Took: $took" - else - echo "WRONG: $name" - echo "Expected: $expected" - echo "Got: $result" - echo "Raw: $resultRaw" - status=1 - fi -} - -configs=( - # starting position - "startpos|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1||5060803636482931868" - # single moves - "1.d4|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|d2d4|9443689642921087454" - "1.e4|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|e2e4|9384546495678726550" - "1.c4|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|c2c4|14562399549841627035" - # two moves - "1.e4 e5|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|e2e4 e7e5|595762792459712928" - "1.e4 c5|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|e2e4 c7c5|7227515431820872427" - "1.e4 e6|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|e2e4 e7e6|17603279437685838276" - "1.e4 c6|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|e2e4 c7c6|1172755318016414253" - "1.d4 d5|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|d2d4 d7d5|460664201775194104" - # three moves - "1.e4 e5 2.Nf3|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|e2e4 e7e5 g1f3|15213300192948443293" - "1.d4 d5 2.c4|rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|d2d4 d7d5 c2c4|9963937660605248767" - # different starting FEN - "Kiwipete|r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1||14109232545397825053" -) - -for config in "${configs[@]}"; do - IFS='|' read -r name fen moves expected <<< "$config" - testZobrist "$name" "$fen" "$moves" "$expected" - if [ $status -ne 0 ]; then - exit "$status" - fi -done diff --git a/src/uci.cpp b/src/uci.cpp index 5f62169..4b36fe6 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -353,7 +353,6 @@ void Uci() { std::cout << hash << "\n"; } if (cmd.starts_with("perft")) { - uint32_t depth = 0; std::stringstream ss(cmd); -- cgit v1.2.3