From 8048bb98f10c75f061d8b0d8a557858e4dfa6619 Mon Sep 17 00:00:00 2001 From: Terje Kirstihagen <42723273+TerjeKir@users.noreply.github.com> Date: Thu, 9 Jan 2025 08:11:37 +0100 Subject: [PATCH] Replace material correction history with minor/major correction history (#767) Elo | 1.75 +- 1.41 (95%) SPRT | 10.0+0.10s Threads=1 Hash=32MB LLR | 2.95 (-2.94, 2.94) [0.00, 3.00] Games | N: 91182 W: 25296 L: 24837 D: 41049 Penta | [1656, 10875, 20093, 11288, 1679] http://chess.grantnet.us/test/38670/ Elo | 2.25 +- 1.75 (95%) SPRT | 60.0+0.60s Threads=1 Hash=128MB LLR | 2.95 (-2.94, 2.94) [0.00, 3.00] Games | N: 45420 W: 11777 L: 11483 D: 22160 Penta | [312, 5383, 11038, 5653, 324] http://chess.grantnet.us/test/38677/ Bench: 25487944 --- src/board.c | 28 +++++++++++++++++++++++++++- src/board.h | 2 ++ src/history.h | 15 ++++++++++----- src/makemove.c | 33 ++++++++++++++++++++++++++++++--- src/threads.c | 3 ++- src/threads.h | 3 ++- 6 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/board.c b/src/board.c index 2c498e62..a9bce297 100644 --- a/src/board.c +++ b/src/board.c @@ -128,6 +128,28 @@ static Key GenMaterialKey(const Position *pos) { return key; } +static Key GenMinorKey(const Position *pos) { + + Key key = 0; + + for (Square sq = A1; sq <= H8; ++sq) + if (PieceTypeOf(pieceOn(sq)) == KNIGHT || PieceTypeOf(pieceOn(sq)) == BISHOP || PieceTypeOf(pieceOn(sq)) == KING) + key ^= PieceKeys[pieceOn(sq)][sq]; + + return key; +} + +static Key GenMajorKey(const Position *pos) { + + Key key = 0; + + for (Square sq = A1; sq <= H8; ++sq) + if (PieceTypeOf(pieceOn(sq)) == ROOK || PieceTypeOf(pieceOn(sq)) == QUEEN || PieceTypeOf(pieceOn(sq)) == KING) + key ^= PieceKeys[pieceOn(sq)][sq]; + + return key; +} + // Generates a hash key from scratch static Key GenNonPawnKey(const Position *pos, const Color color) { @@ -253,6 +275,8 @@ void ParseFen(const char *fen, Position *pos) { pos->checkers = Checkers(pos); pos->key = GenPosKey(pos); pos->materialKey = GenMaterialKey(pos); + pos->minorKey = GenMinorKey(pos); + pos->majorKey = GenMajorKey(pos); pos->nonPawnKey[WHITE] = GenNonPawnKey(pos, WHITE); pos->nonPawnKey[BLACK] = GenNonPawnKey(pos, BLACK); pos->phase = UpdatePhase(pos->phaseValue); @@ -540,8 +564,10 @@ bool PositionOk(const Position *pos) { assert(pos->castlingRights >= 0 && pos->castlingRights <= 15); assert(GenPosKey(pos) == pos->key); - assert(GenMaterialKey(pos) == pos->materialKey); assert(GenPawnKey(pos) == pos->pawnKey); + assert(GenMaterialKey(pos) == pos->materialKey); + assert(GenMinorKey(pos) == pos->minorKey); + assert(GenMajorKey(pos) == pos->majorKey); assert(GenNonPawnKey(pos, WHITE) == pos->nonPawnKey[WHITE]); assert(GenNonPawnKey(pos, BLACK) == pos->nonPawnKey[BLACK]); diff --git a/src/board.h b/src/board.h index 25928c93..bd879afe 100644 --- a/src/board.h +++ b/src/board.h @@ -53,6 +53,8 @@ typedef struct Position { Key key; Key materialKey; Key pawnKey; + Key minorKey; + Key majorKey; Key nonPawnKey[COLOR_NB]; uint64_t nodes; diff --git a/src/history.h b/src/history.h index bb226cc9..2173ab60 100644 --- a/src/history.h +++ b/src/history.h @@ -31,7 +31,8 @@ #define NoisyEntry(move) (&thread->captureHistory[piece(move)][toSq(move)][PieceTypeOf(capturing(move))]) #define ContEntry(offset, move) (&(*(ss-offset)->continuation)[piece(move)][toSq(move)]) #define PawnCorrEntry() (&thread->pawnCorrHistory[thread->pos.stm][PawnCorrIndex(&thread->pos)]) -#define MatCorrEntry() (&thread->matCorrHistory[thread->pos.stm][MatCorrIndex(&thread->pos)]) +#define MinorCorrEntry() (&thread->minorCorrHistory[thread->pos.stm][MinorCorrIndex(&thread->pos)]) +#define MajorCorrEntry() (&thread->majorCorrHistory[thread->pos.stm][MajorCorrIndex(&thread->pos)]) #define ContCorrEntry(offset) (&(*(ss-offset)->contCorr)[piece((ss-1)->move)][toSq((ss-1)->move)]) #define NonPawnCorrEntry(color) (&thread->nonPawnCorrHistory[color][thread->pos.stm][NonPawnCorrIndex(&thread->pos, color)]) @@ -40,14 +41,16 @@ #define NoisyHistoryUpdate(move, bonus) (HistoryBonus(NoisyEntry(move), bonus, 16000)) #define ContHistoryUpdate(offset, move, bonus) (HistoryBonus(ContEntry(offset, move), bonus, 21250)) #define PawnCorrHistoryUpdate(bonus) (HistoryBonus(PawnCorrEntry(), bonus, 1662)) -#define MatCorrHistoryUpdate(bonus) (HistoryBonus(MatCorrEntry(), bonus, 1077)) +#define MinorCorrHistoryUpdate(bonus) (HistoryBonus(MinorCorrEntry(), bonus, 1024)) +#define MajorCorrHistoryUpdate(bonus) (HistoryBonus(MajorCorrEntry(), bonus, 1024)) #define ContCorrHistoryUpdate(offset, bonus) (HistoryBonus(ContCorrEntry(offset), bonus, 1220)) #define NonPawnCorrHistoryUpdate(bonus, color) (HistoryBonus(NonPawnCorrEntry(color), bonus, 1024)) INLINE int PawnStructure(const Position *pos) { return pos->pawnKey & (PAWN_HISTORY_SIZE - 1); } INLINE int PawnCorrIndex(const Position *pos) { return pos->pawnKey & (CORRECTION_HISTORY_SIZE - 1); } -INLINE int MatCorrIndex(const Position *pos) { return pos->materialKey & (CORRECTION_HISTORY_SIZE - 1); } +INLINE int MinorCorrIndex(const Position *pos) { return pos->minorKey & (CORRECTION_HISTORY_SIZE - 1); } +INLINE int MajorCorrIndex(const Position *pos) { return pos->majorKey & (CORRECTION_HISTORY_SIZE - 1); } INLINE int NonPawnCorrIndex(const Position *pos, Color c) { return pos->nonPawnKey[c] & (CORRECTION_HISTORY_SIZE - 1); } @@ -121,7 +124,8 @@ INLINE void UpdateHistory(Thread *thread, Stack *ss, Move bestMove, Depth depth, INLINE void UpdateCorrectionHistory(Thread *thread, Stack *ss, int bestScore, int eval, Depth depth) { int bonus = CorrectionBonus(bestScore, eval, depth); PawnCorrHistoryUpdate(bonus); - MatCorrHistoryUpdate(bonus); + MinorCorrHistoryUpdate(bonus); + MajorCorrHistoryUpdate(bonus); NonPawnCorrHistoryUpdate(bonus, WHITE); NonPawnCorrHistoryUpdate(bonus, BLACK); ContCorrHistoryUpdate(2, bonus); @@ -150,7 +154,8 @@ INLINE int GetHistory(const Thread *thread, Stack *ss, Move move) { INLINE int GetCorrectionHistory(const Thread *thread, const Stack *ss) { int c = 6554 * *PawnCorrEntry() - + 4520 * *MatCorrEntry() + + 6800 * *MinorCorrEntry() + + 3700 * *MajorCorrEntry() + 7000 * (*NonPawnCorrEntry(WHITE) + *NonPawnCorrEntry(BLACK)) + 3121 * *ContCorrEntry(2) + 2979 * *ContCorrEntry(3) diff --git a/src/makemove.c b/src/makemove.c index 24f55fe4..8d1a4e7a 100644 --- a/src/makemove.c +++ b/src/makemove.c @@ -46,9 +46,18 @@ static void ClearPiece(Position *pos, const Square sq, const bool hash) { if (PieceTypeOf(piece) == PAWN) pos->pawnKey ^= PieceKeys[piece][sq]; - else + else { pos->nonPawnKey[color] ^= PieceKeys[piece][sq]; + if (pt == KING) { + pos->minorKey ^= PieceKeys[piece][sq]; + pos->majorKey ^= PieceKeys[piece][sq]; + } else if (pt >= ROOK) + pos->majorKey ^= PieceKeys[piece][sq]; + else + pos->minorKey ^= PieceKeys[piece][sq]; + } + // Set square to empty pieceOn(sq) = EMPTY; @@ -84,9 +93,18 @@ static void AddPiece(Position *pos, const Square sq, const Piece piece, const bo if (PieceTypeOf(piece) == PAWN) pos->pawnKey ^= PieceKeys[piece][sq]; - else + else { pos->nonPawnKey[color] ^= PieceKeys[piece][sq]; + if (pt == KING) { + pos->minorKey ^= PieceKeys[piece][sq]; + pos->majorKey ^= PieceKeys[piece][sq]; + } else if (pt >= ROOK) + pos->majorKey ^= PieceKeys[piece][sq]; + else + pos->minorKey ^= PieceKeys[piece][sq]; + } + // Update square pieceOn(sq) = piece; @@ -123,9 +141,18 @@ static void MovePiece(Position *pos, const Square from, const Square to, const b if (PieceTypeOf(piece) == PAWN) pos->pawnKey ^= PieceKeys[piece][from] ^ PieceKeys[piece][to]; - else + else { pos->nonPawnKey[color] ^= PieceKeys[piece][from] ^ PieceKeys[piece][to]; + if (pt == KING) { + pos->minorKey ^= PieceKeys[piece][from] ^ PieceKeys[piece][to]; + pos->majorKey ^= PieceKeys[piece][from] ^ PieceKeys[piece][to]; + } else if (pt >= ROOK) + pos->majorKey ^= PieceKeys[piece][from] ^ PieceKeys[piece][to]; + else + pos->minorKey ^= PieceKeys[piece][from] ^ PieceKeys[piece][to]; + } + // Set old square to empty, new to piece pieceOn(from) = EMPTY; pieceOn(to) = piece; diff --git a/src/threads.c b/src/threads.c index 89127399..ad048798 100644 --- a/src/threads.c +++ b/src/threads.c @@ -145,7 +145,8 @@ void ResetThreads() { memset(Threads[i].captureHistory, 0, sizeof(Threads[i].captureHistory)), memset(Threads[i].continuation, 0, sizeof(Threads[i].continuation)), memset(Threads[i].pawnCorrHistory, 0, sizeof(Threads[i].pawnCorrHistory)), - memset(Threads[i].matCorrHistory, 0, sizeof(Threads[i].matCorrHistory)), + memset(Threads[i].minorCorrHistory,0, sizeof(Threads[i].minorCorrHistory)), + memset(Threads[i].majorCorrHistory,0, sizeof(Threads[i].majorCorrHistory)), memset(Threads[i].contCorrHistory, 0, sizeof(Threads[i].contCorrHistory)); } diff --git a/src/threads.h b/src/threads.h index 8d6f374e..f9c86654 100644 --- a/src/threads.h +++ b/src/threads.h @@ -79,7 +79,8 @@ typedef struct Thread { CaptureToHistory captureHistory; ContinuationHistory continuation[2][2]; CorrectionHistory pawnCorrHistory; - CorrectionHistory matCorrHistory; + CorrectionHistory minorCorrHistory; + CorrectionHistory majorCorrHistory; CorrectionHistory nonPawnCorrHistory[COLOR_NB]; ContiuationCorrectionHistory contCorrHistory;