-// DTZ tables don't store valid scores for moves that reset the rule50 counter
-// like captures and pawn moves but we can easily recover the correct dtz of the
-// previous move if we know the position's WDL score.
-int dtz_before_zeroing(WDLScore wdl) {
- return wdl == WDLWin ? 1 :
- wdl == WDLCursedWin ? 101 :
- wdl == WDLBlessedLoss ? -101 :
- wdl == WDLLoss ? -1 : 0;
-}
-
-// Return the sign of a number (-1, 0, 1)
-template <typename T> int sign_of(T val) {
- return (T(0) < val) - (val < T(0));
-}
-
-// Numbers in little endian used by sparseIndex[] to point into blockLength[]
-struct SparseEntry {
- char block[4]; // Number of block
- char offset[2]; // Offset within the block
-};
-
-static_assert(sizeof(SparseEntry) == 6, "SparseEntry must be 6 bytes");
-
-typedef uint16_t Sym; // Huffman symbol
-
-struct LR {
- enum Side { Left, Right, Value };
-
- uint8_t lr[3]; // The first 12 bits is the left-hand symbol, the second 12
- // bits is the right-hand symbol. If symbol has length 1,
- // then the first byte is the stored value.
- template<Side S>
- Sym get() {
- return S == Left ? ((lr[1] & 0xF) << 8) | lr[0] :
- S == Right ? (lr[2] << 4) | (lr[1] >> 4) :
- S == Value ? lr[0] : (assert(false), Sym(-1));
- }
-};
-
-static_assert(sizeof(LR) == 3, "LR tree entry must be 3 bytes");
-
-constexpr int TBPIECES = 6;
-
-struct PairsData {
- int flags;
- size_t sizeofBlock; // Block size in bytes
- size_t span; // About every span values there is a SparseIndex[] entry
- int blocksNum; // Number of blocks in the TB file
- int maxSymLen; // Maximum length in bits of the Huffman symbols
- int minSymLen; // Minimum length in bits of the Huffman symbols
- Sym* lowestSym; // lowestSym[l] is the symbol of length l with the lowest value
- LR* btree; // btree[sym] stores the left and right symbols that expand sym
- uint16_t* blockLength; // Number of stored positions (minus one) for each block: 1..65536
- int blockLengthSize; // Size of blockLength[] table: padded so it's bigger than blocksNum
- SparseEntry* sparseIndex; // Partial indices into blockLength[]
- size_t sparseIndexSize; // Size of SparseIndex[] table
- uint8_t* data; // Start of Huffman compressed data
- std::vector<uint64_t> base64; // base64[l - min_sym_len] is the 64bit-padded lowest symbol of length l
- std::vector<uint8_t> symlen; // Number of values (-1) represented by a given Huffman symbol: 1..256
- Piece pieces[TBPIECES]; // Position pieces: the order of pieces defines the groups
- uint64_t groupIdx[TBPIECES+1]; // Start index used for the encoding of the group's pieces
- int groupLen[TBPIECES+1]; // Number of pieces in a given group: KRKN -> (3, 1)
-};
-
-// Helper struct to avoid manually defining entry copy constructor as we
-// should because the default one is not compatible with std::atomic_bool.
-struct Atomic {
- Atomic() = default;
- Atomic(const Atomic& e) { ready = e.ready.load(); } // MSVC 2013 wants assignment within body
- std::atomic_bool ready;
-};
-
-// We define types for the different parts of the WDLEntry and DTZEntry with
-// corresponding specializations for pieces or pawns.
-
-struct WDLEntryPiece {
- PairsData* precomp;
-};
-
-struct WDLEntryPawn {
- uint8_t pawnCount[2]; // [Lead color / other color]
- WDLEntryPiece file[2][4]; // [wtm / btm][FILE_A..FILE_D]
-};
-
-struct DTZEntryPiece {
- PairsData* precomp;
- uint16_t map_idx[4]; // WDLWin, WDLLoss, WDLCursedWin, WDLBlessedLoss
- uint8_t* map;
-};
-
-struct DTZEntryPawn {
- uint8_t pawnCount[2];
- DTZEntryPiece file[4];
- uint8_t* map;
-};
-
-struct TBEntry : public Atomic {
- void* baseAddress;
- uint64_t mapping;
- Key key;
- Key key2;
- int pieceCount;
- bool hasPawns;
- bool hasUniquePieces;
-};
-
-// Now the main types: WDLEntry and DTZEntry
-struct WDLEntry : public TBEntry {
- WDLEntry(const std::string& code);
- ~WDLEntry();
- union {
- WDLEntryPiece pieceTable[2]; // [wtm / btm]
- WDLEntryPawn pawnTable;
- };
-};
-
-struct DTZEntry : public TBEntry {
- DTZEntry(const WDLEntry& wdl);
- ~DTZEntry();
- union {
- DTZEntryPiece pieceTable;
- DTZEntryPawn pawnTable;
- };
-};
-
-typedef decltype(WDLEntry::pieceTable) WDLPieceTable;
-typedef decltype(DTZEntry::pieceTable) DTZPieceTable;
-typedef decltype(WDLEntry::pawnTable ) WDLPawnTable;
-typedef decltype(DTZEntry::pawnTable ) DTZPawnTable;
-
-auto item(WDLPieceTable& e, int stm, int ) -> decltype(e[stm])& { return e[stm]; }
-auto item(DTZPieceTable& e, int , int ) -> decltype(e)& { return e; }
-auto item(WDLPawnTable& e, int stm, int f) -> decltype(e.file[stm][f])& { return e.file[stm][f]; }
-auto item(DTZPawnTable& e, int , int f) -> decltype(e.file[f])& { return e.file[f]; }
-
-template<typename E> struct Ret { typedef int type; };
-template<> struct Ret<WDLEntry> { typedef WDLScore type; };