diff options
| -rwxr-xr-x | scripts/tests/hash.bash (renamed from scripts/tests/zobrist.bash) | 12 | ||||
| -rw-r--r-- | src/board/board.cpp | 6 | ||||
| -rw-r--r-- | src/board/board.hpp | 2 | ||||
| -rw-r--r-- | src/bot.cpp | 4 | ||||
| -rw-r--r-- | src/hash.cpp (renamed from src/zobrist.cpp) | 54 | ||||
| -rw-r--r-- | src/hash.hpp | 14 | ||||
| -rw-r--r-- | src/main.cpp | 20 | ||||
| -rw-r--r-- | src/misc.cpp | 9 | ||||
| -rw-r--r-- | src/uci.cpp | 6 | ||||
| -rw-r--r-- | src/zobrist.hpp | 11 |
10 files changed, 61 insertions, 77 deletions
diff --git a/scripts/tests/zobrist.bash b/scripts/tests/hash.bash index bcfc437..92be2e6 100755 --- a/scripts/tests/zobrist.bash +++ b/scripts/tests/hash.bash @@ -10,16 +10,16 @@ testZobrist() { echo "" - resultRaw=$(./build/mono zobrist "$fen" $moves) + resultRaw=$(./build/mono hash "$fen" $moves) result=$(echo $resultRaw | jq -r '.hash') took=$(echo $resultRaw | jq -r '.ms') if [ "$result" = "$expected" ]; then - echo "PASS: $name, Took: $took" + echo "OK: $name, Took: $took" else - echo "FAIL: $name" - echo " Expected: $expected" - echo " Got: $result" - echo " Raw: $resultRaw" + echo "WRONG: $name" + echo "Expected: $expected" + echo "Got: $result" + echo "Raw: $resultRaw" status=1 fi } diff --git a/src/board/board.cpp b/src/board/board.cpp index faabfac..7084c9d 100644 --- a/src/board/board.cpp +++ b/src/board/board.cpp @@ -6,8 +6,8 @@ #include <iostream> #include "board.hpp" +#include "hash.hpp" #include "moves.hpp" -#include "zobrist.hpp" int PositionToIndex(Position i) { return (i.rank * 8) + i.file; } @@ -176,7 +176,7 @@ Undo MakeMove(uint16_t move, Game *g) { undo.OldBlackCastleKing = g->blackCastleKing; undo.OldBlackCastleQueen = g->blackCastleQueen; - undo.ZobristKey = g->hash; + undo.Hash = g->hash; // play move Piece movingPiece = g->pieces[fromSquare]; @@ -448,5 +448,5 @@ void UndoMove(Undo undo, Game *g) { g->PieceBitboard = g->WhitePieceBitboard | g->BlackPieceBitboard; - g->hash = undo.ZobristKey; + g->hash = undo.Hash; }; diff --git a/src/board/board.hpp b/src/board/board.hpp index 2b3ac6a..f9947ed 100644 --- a/src/board/board.hpp +++ b/src/board/board.hpp @@ -97,7 +97,7 @@ struct Undo { int oldHalfMoveClock; int oldMoveClock; - uint64_t ZobristKey; + uint64_t Hash; GameState oldState; // castling diff --git a/src/bot.cpp b/src/bot.cpp index 969606e..9e9b624 100644 --- a/src/bot.cpp +++ b/src/bot.cpp @@ -15,8 +15,8 @@ #include "book.hpp" #include "bot.hpp" #include "evaluate.hpp" +#include "hash.hpp" #include "moves.hpp" -#include "zobrist.hpp" constexpr int DEFAULT_TIME = 7; constexpr int Q_DEPTH_LIMIT = 4; @@ -320,7 +320,7 @@ uint16_t GetBestMove(Game *b, int maxDepth, move_options options) { searchStopped = false; Nodes = 0; - uint64_t hash = GenerateZobristKey(b); + uint64_t hash = GenerateHashFromScratch(b); if (b->MoveClock <= BOOK_DEPTH) { std::optional<uint16_t> bookMove = ProbeBook(hash, *b); diff --git a/src/zobrist.cpp b/src/hash.cpp index afef3e6..5d6a72d 100644 --- a/src/zobrist.cpp +++ b/src/hash.cpp @@ -1,17 +1,15 @@ -#include "zobrist.hpp" +#include "hash.hpp" #include "board/board.hpp" #include <cassert> #include <cstdint> +#include <sys/types.h> static uint64_t PieceKeys[2][7][64]; static uint64_t SideKey; static uint64_t CastleKeys[4]; static uint64_t EnPassantKeys[8]; -// Polyglot book format random numbers. -// Layout: [0..767] piece keys (type*2+color)*64+square, [768..771] castling -// WK/WQ/BK/BQ, [772..779] en passant file a-h, [780] side to move. -static const uint64_t PolyglotRandom64[781] = { +static const uint64_t Random64[781] = { 0x9D39247E33776D41, 0x2AF7398005AAA5C7, 0x44DB015024623547, 0x9C15F73E62A76AE2, 0x75834465489C0C89, 0x3290AC3A203001BF, 0x0FBBAD1F61042279, 0xE83A908FF2FB60CA, 0x0D7E765D58755C10, @@ -280,14 +278,9 @@ static bool IsEnpassantLegal(Game *g) { return false; } - // Polyglot spec: en passant key is included only if the player to move - // has a pawn adjacent to the en passant target square. int epFile = g->enPassant.file; int epRank = g->enPassant.rank; - // The capturing pawn sits one rank away from the ep target: - // white to move: pawn is one rank below (epRank - 1) - // black to move: pawn is one rank above (epRank + 1) int pawnRank = g->turn ? (epRank - 1) : (epRank + 1); if (pawnRank < 0 || pawnRank > 7) { @@ -299,53 +292,36 @@ static bool IsEnpassantLegal(Game *g) { if (epFile > 0) { leftSide = (g->PieceBitboards[g->turn][PAWN] & - (1ULL << (pawnRank * 8 + epFile - 1))) > 0; + (1ULL << ((pawnRank * 8) + epFile - 1))) > 0; } if (epFile < 7) { rightSide = (g->PieceBitboards[g->turn][PAWN] & - (1ULL << (pawnRank * 8 + epFile + 1))) > 0; + (1ULL << ((pawnRank * 8) + epFile + 1))) > 0; } return leftSide || rightSide; } -// PolyglotRandom64 layout (standard Polyglot spec): -// [0..767] piece keys, kind = (pieceType-1)*2 + color: -// [0-63] black pawn, [64-127] white pawn, [128-191] black knight, -// [192-255] white knight, [256-319] black bishop, [320-383] white -// bishop, [384-447] black rook, [448-511] white rook, [512-575] -// black queen, [576-639] white queen, [640-703] black king, -// [704-767] white king -// [768] white kingside castling -// [769] white queenside castling -// [770] black kingside castling -// [771] black queenside castling -// [772..779] en passant file a-h -// [780] side to move (XORed when white to move) -void InitZobrist() { +void InitHashing() { int idx = 0; - // Piece keys: interleaved by kind = (pieceType-1)*2 + color for (int kind = 0; kind < 12; ++kind) { - int color = kind % 2; // 0=black, 1=white - int pieceType = (kind / 2) + 1; // PAWN=1..KING=6 + int color = kind % 2; + int pieceType = (kind / 2) + 1; for (int square = 0; square < 64; ++square) { - PieceKeys[color][pieceType][square] = PolyglotRandom64[idx++]; + PieceKeys[color][pieceType][square] = Random64[idx++]; } } - // Castling keys (one per right, indices 768-771) - for (int i = 0; i < 4; ++i) { - CastleKeys[i] = PolyglotRandom64[idx++]; + for (ulong &CastleKey : CastleKeys) { + CastleKey = Random64[idx++]; } - // En passant keys (one per file, indices 772-779) - for (int file = 0; file < 8; ++file) { - EnPassantKeys[file] = PolyglotRandom64[idx++]; + for (ulong &EnPassantKey : EnPassantKeys) { + EnPassantKey = Random64[idx++]; } - // Side to move key (index 780) - SideKey = PolyglotRandom64[idx]; + SideKey = Random64[idx]; } void xorCastleKey(bool color, bool IS_KING_SIDE, Game *g) { @@ -381,7 +357,7 @@ void xorSquare(uint8_t square, Game *g) { /* * should be only called at start of game */ -uint64_t GenerateZobristKey(Game *b) { +uint64_t GenerateHashFromScratch(Game *b) { uint64_t key = 0; for (int square = 0; square < 64; square++) { diff --git a/src/hash.hpp b/src/hash.hpp new file mode 100644 index 0000000..6253363 --- /dev/null +++ b/src/hash.hpp @@ -0,0 +1,14 @@ +#ifndef SRC_HASH_H_ +#define SRC_HASH_H_ + +#include "board/board.hpp" +#include <cstdint> + +void InitHashing(); +uint64_t GenerateHashFromScratch(Game *b); +void xorCastleKey(bool color, bool IS_KING_SIDE, Game *g); +void xorSidekey(Game *g); +void xorEnpassantKey(Game *g); +void xorSquare(uint8_t square, Game *g); + +#endif /* SRC_HASH_H_ */ diff --git a/src/main.cpp b/src/main.cpp index 98ff360..27b428d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,10 +8,10 @@ #include "board/board.hpp" #include "board/fen.hpp" +#include "hash.hpp" #include "misc.hpp" #include "moves.hpp" #include "uci.hpp" -#include "zobrist.hpp" static void perft(int argc, char *argv[]) { if (argc < 4 || std::string(argv[1]) != "perft") { @@ -49,9 +49,9 @@ static void perft(int argc, char *argv[]) { std::cout << oss.str() << "\n"; } -static void zobristCmd(int argc, char *argv[]) { - if (argc < 3 || std::string(argv[1]) != "zobrist") { - std::cout << "Usage: ./mono zobrist <fen> [moves...]\n"; +static void hashCmd(int argc, char *argv[]) { + if (argc < 3) { + std::cout << "Usage: ./mono hash <fen> [moves...]\n"; exit(1); } @@ -65,7 +65,7 @@ static void zobristCmd(int argc, char *argv[]) { auto start = std::chrono::steady_clock::now(); - uint64_t hash = GenerateZobristKey(&game); + uint64_t hash = GenerateHashFromScratch(&game); auto end = std::chrono::steady_clock::now(); auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start) .count(); @@ -76,7 +76,7 @@ static void zobristCmd(int argc, char *argv[]) { } int main(int argc, char *argv[]) { - InitZobrist(); + InitHashing(); initMagicBitboards(); if (argc >= 2 && std::string(argv[1]) == "perft") { @@ -84,11 +84,15 @@ int main(int argc, char *argv[]) { return 0; } - if (argc >= 2 && std::string(argv[1]) == "zobrist") { - zobristCmd(argc, argv); + if (argc >= 2 && std::string(argv[1]) == "hash") { + hashCmd(argc, argv); return 0; } + if (argc != 1) { + std::cout << "Usage: ./mono \n"; + return 0; + } std::cerr << engine_info(); Uci(); return 0; diff --git a/src/misc.cpp b/src/misc.cpp index a69054b..b49c5c4 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -59,14 +59,15 @@ uint64_t MoveGenTestDivide(uint32_t depth, Game *g) { char toFile = static_cast<char>('a' + toPos.file); std::cout << fromFile << (fromPos.rank + 1) << toFile << (toPos.rank + 1); PieceType promo = getPromotionTypeFromMove(move); - if (promo == QUEEN) + if (promo == QUEEN) { std::cout << 'q'; - else if (promo == ROOK) + } else if (promo == ROOK) { std::cout << 'r'; - else if (promo == KNIGHT) + } else if (promo == KNIGHT) { std::cout << 'n'; - else if (promo == BISHOP) + } else if (promo == BISHOP) { std::cout << 'b'; + } std::cout << ": " << count << "\n"; total += count; } diff --git a/src/uci.cpp b/src/uci.cpp index 6e30014..e65bf73 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -15,10 +15,10 @@ #include "board/fen.hpp" #include "book.hpp" #include "bot.hpp" +#include "hash.hpp" #include "misc.hpp" #include "moves.hpp" #include "uci.hpp" -#include "zobrist.hpp" static const std::string starting_fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; @@ -94,7 +94,7 @@ Game initBoard( setBoardFen(startingFEN, &g); - uint64_t key = GenerateZobristKey(&g); + uint64_t key = GenerateHashFromScratch(&g); g.history.push_back(key); g.hash = key; @@ -349,7 +349,7 @@ void Uci() { movesCommnad(&game); } if (cmd == "hash") { - uint64_t hash = GenerateZobristKey(&game); + uint64_t hash = GenerateHashFromScratch(&game); std::cout << hash << "\n"; } } diff --git a/src/zobrist.hpp b/src/zobrist.hpp deleted file mode 100644 index b72b0f2..0000000 --- a/src/zobrist.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include <cstdint> - -struct Game; - -void InitZobrist(); -uint64_t GenerateZobristKey(Game *b); -void xorCastleKey(bool color, bool IS_KING_SIDE, Game *g); -void xorSidekey(Game *g); -void xorEnpassantKey(Game *g); -void xorSquare(uint8_t square, Game *g);
\ No newline at end of file |
