From 6a39e28205d44e96da72728c0a3d4d6468962539 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 10 Aug 2026 15:04:16 +0200 Subject: adding json based perft tests --- perft.bash | 39 +++++++++++++++++++++++++++++++++++++++ perft.sh | 32 -------------------------------- src/main.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- src/uci.cpp | 25 ------------------------- 4 files changed, 90 insertions(+), 60 deletions(-) create mode 100755 perft.bash delete mode 100755 perft.sh diff --git a/perft.bash b/perft.bash new file mode 100755 index 0000000..cb0149b --- /dev/null +++ b/perft.bash @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +testPerft() { + local fen="$1" + local depth="$2" + local expected="$3" + + result=$(./build/mono "perft" $depth "$fen") + count=$(echo $result | jq -r '.result') + if [ "$count" = "$expected" ]; then + echo "Results match" + else + echo "Results dont match" + echo "Expected: $expected" + echo "Got: $count" + fi + echo "-------------------" +} + +configs=( + # starting pos + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|1|1" + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|2|400" + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|3|8902" + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|4|197281" + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|5|4865609" + + # kiwipete + "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -|1|48" + "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -|2|2039" + "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -|3|97862" + "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -|4|4085603" + "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -|5|193690690" +) + +for config in "${configs[@]}"; do + IFS='|' read -r fen depth expected <<< "$config" + testPerft "$fen" "$depth" "$expected" +done \ No newline at end of file diff --git a/perft.sh b/perft.sh deleted file mode 100755 index 7bf1043..0000000 --- a/perft.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -testPerft() { - local fen="$1" - local depth="$2" - local expected="$3" - - printf "position fen %s\nperft %s\nquit\n" "$fen" "$depth" | ./build/mono - echo "Expected: $expected" - echo "-------------------" -} - -configs=( - # starting pos - "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|1|20" - "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|2|400" - "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|3|8902" - "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|4|197281" - "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1|5|4865609" - - # kiwipete - "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -|1|48" - "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -|2|2039" - "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -|3|97862" - "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -|4|4085603" - "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -|5|193690690" -) - -for config in "${configs[@]}"; do - IFS='|' read -r fen depth expected <<< "$config" - testPerft "$fen" "$depth" "$expected" -done \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 4469e40..a2af33f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,13 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "board/board.hpp" #include "misc.hpp" #include "uci.hpp" #include "zobrist.hpp" -#include -int main() { +static void perft(int argc, char *argv[]) { + if (argc != 4 || std::string(argv[1]) != "perft") { + std::cout << "Usage: ./mono\n"; + std::cout << " ./mono perft \n"; + exit(1); + } + + int depth = -1; + try { + depth = std::stoi(argv[2]); + } catch (const std::exception &) { + std::cout << "info string usage: ./mono perft \n"; + exit(1); + } + + if (depth < 0) { + std::cout << "info string usage: ./mono perft \n"; + exit(1); + } + + std::string fen = argv[3]; + + auto start = std::chrono::steady_clock::now(); + + Game game = initBoard(fen, nullptr); + uint64_t count = MoveGenTest(depth, &game); + + auto end = std::chrono::steady_clock::now(); + auto ms = std::chrono::duration_cast(end - start) + .count(); + std::ostringstream oss; + oss << "{\"ms\": " << ms << ", \"result\": " << count << "}"; + + std::cout << oss.str() << std::endl; +} + +int main(int argc, char *argv[]) { InitZobrist(); - std::cout << engine_info(); + if (argc != 1) { + perft(argc, argv); + return 0; + } + std::cout << engine_info(); Uci(); return 0; } diff --git a/src/uci.cpp b/src/uci.cpp index 0805c6c..1854019 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -286,31 +286,6 @@ void Uci() { MakeMove(move, &game); } - } else if (cmd.starts_with("perft")) { - std::istringstream iss(cmd); - - std::string word; - int depth = -1; - - if (!(iss >> word >> depth) || word != "perft" || depth < 0) { - cout << "info string usage: perft \n"; - cout.flush(); - continue; - } - - auto start = std::chrono::steady_clock::now(); - - uint64_t count = MoveGenTest(depth, &game); - - auto end = std::chrono::steady_clock::now(); - auto ms = - std::chrono::duration_cast(end - start) - .count(); - std::ostringstream oss; - oss << "{\"ms\": " << ms << ", \"result\": " << count << "}"; - std::string json = oss.str(); - - std::cout << json << std::endl; } } } -- cgit v1.2.3