From 2c3d1bc0218982959d93e052a523c9f3bdc388d9 Mon Sep 17 00:00:00 2001 From: MrGeorgen Date: Mon, 23 Sep 2024 21:51:22 +0200 Subject: [PATCH] repetition table --- include/chess/move.h | 2 +- include/chess/types.h | 13 ++++++- include/chess/util.h | 24 +++++-------- src/chess/move.c | 22 +++++++++++- src/common/postCodeGen/bitboard.c | 1 + src/common/preCodeGen/util.c | 57 +++++++++++++++---------------- 6 files changed, 71 insertions(+), 48 deletions(-) diff --git a/include/chess/move.h b/include/chess/move.h index 8cd836f..bae9a52 100644 --- a/include/chess/move.h +++ b/include/chess/move.h @@ -25,7 +25,7 @@ uint_least8_t validMoves(struct gameState_t gameState, struct move_t *moves); uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece, uint_least8_t src, struct move_t *moves, bool promotion); -void undoMove(uint_least64_t *board, struct move_t move, bool color); +void undoMove(struct gameState_t gameState, struct move_t move, bool color); struct gameState_t makeMove(struct gameState_t gameState, const struct move_t move); void initMagicTable(); bool kingInCheck(const uint_least64_t *board, const bool color); diff --git a/include/chess/types.h b/include/chess/types.h index 48b5ea8..35cc1fc 100644 --- a/include/chess/types.h +++ b/include/chess/types.h @@ -3,6 +3,7 @@ #include #include +#include #define BOARD_SIZE 8 #define TOTAL_BOARD_SIZE (BOARD_SIZE * BOARD_SIZE) @@ -35,6 +36,16 @@ enum directions { NORTH, NORTHWEST, WEST, SOUTHWEST, SOUTH, SOUTHEAST, EAST, NORTHEAST, DIRECTION_LENGTH }; +struct zobristTableElement { + uint_least64_t hash; + int_least16_t value; +}; + +struct zobristTable { + struct zobristTableElement *arr; + size_t length; +}; + struct moveDst_t { uint_least8_t length; uint_least8_t dst[8]; @@ -54,7 +65,7 @@ struct castle_t { struct gameState_t { uint_least64_t *board; uint_least64_t zobrist; - uint_least8_t *repetitionTable; + struct zobristTable repetitionTable; bool color; // color to move struct castle_t canCastle[2]; diff --git a/include/chess/util.h b/include/chess/util.h index eb30d96..8a98f53 100644 --- a/include/chess/util.h +++ b/include/chess/util.h @@ -1,24 +1,18 @@ +#ifndef CHESS_UTIL_H +#define CHESS_UTIL_H + #include #include #include #include -struct zobristTableElement { - uint_least64_t hash; - int_least16_t value; -}; - -struct zobristTable { - struct zobristTableElement *arr; - size_t length; -}; - -struct zobristTableResult { - bool success; - int_least16_t value; -}; - uint_least64_t rand_64(); uint_least64_t zobristPieceI(struct piece_t piece, uint_least8_t field); uint_least8_t getFile(const uint_least8_t field); uint_least8_t getRank(const uint_least8_t field); + +struct zobristTable initZobirstTable(size_t length); +void zobristTableIter(const struct zobristTable table, const uint_least64_t key, void *result, + void (*foreach)(struct zobristTableElement *element, const uint_least64_t key, void *result)); + +#endif diff --git a/src/chess/move.c b/src/chess/move.c index 60f1e70..cce80ef 100644 --- a/src/chess/move.c +++ b/src/chess/move.c @@ -158,7 +158,16 @@ static void castleMoveRook(uint_least64_t *board, uint_least8_t spezialMove, boo } } -void undoMove(uint_least64_t *board, struct move_t move, bool color) { +static void zobristTableUndoMoveCallback(struct zobristTableElement *element, const uint_least64_t key, + void *resultVoid) { + if(element->hash == key) { + if(--element->value == 0) element->hash = 0; + } + fprintf(stderr, "Error: Position does not in repetitionTable in undoMove (move.c)"); +} + +void undoMove(struct gameState_t gameState, struct move_t move, bool color) { + uint_least64_t *board = gameState.board; const struct piece_t srcPiece = {move.srcPiece, color}; const struct piece_t dstPiece = {move.dstPiece, color}; bitboardSet(board, srcPiece, move.src); @@ -397,6 +406,16 @@ uint_least8_t validMoves(struct gameState_t gameState, struct move_t *moves) { return movesLength; } +static void zobristTableMakeMoveCallback(struct zobristTableElement *element, const uint_least64_t key, + void *resultVoid) { + if(element->hash == key) { + ++element->value; + return; + } + element->hash = key; + element->value = 1; +} + struct gameState_t makeMove(struct gameState_t gameState, const struct move_t move) { uint_least64_t *board = gameState.board; const struct piece_t srcPiece = {move.srcPiece, gameState.color}; @@ -417,5 +436,6 @@ struct gameState_t makeMove(struct gameState_t gameState, const struct move_t mo else ++gameState.halfMoveCounter; gameState.color = !gameState.color; gameState.zobrist ^= move.hash; + zobristTableIter(gameState.repetitionTable, gameState.zobrist, NULL, zobristTableMakeMoveCallback); return gameState; } diff --git a/src/common/postCodeGen/bitboard.c b/src/common/postCodeGen/bitboard.c index 1be1599..63528d4 100644 --- a/src/common/postCodeGen/bitboard.c +++ b/src/common/postCodeGen/bitboard.c @@ -134,5 +134,6 @@ struct gameState_t newGameState(uint_least64_t *board, char *FEN) { gameState.enPassantTo += (BOARD_SIZE - *FEN++) * BOARD_SIZE; } gameState.halfMoveCounter = atoi(++FEN); + gameState.repetitionTable = initZobirstTable(1000); return gameState; } diff --git a/src/common/preCodeGen/util.c b/src/common/preCodeGen/util.c index 4c31972..364d347 100644 --- a/src/common/preCodeGen/util.c +++ b/src/common/preCodeGen/util.c @@ -1,3 +1,4 @@ +#include "chess/types.h" #include #include #include @@ -22,28 +23,24 @@ uint_least8_t getRank(const uint_least8_t field) { return field / BOARD_SIZE; } -void initZobirstTable(struct zobristTableElement *table, size_t length) { - for(size_t i = 0; i < length; ++i) { - table[i].hash = 0; // use 0 for no value - } +struct zobristTable initZobirstTable(size_t length) { + struct zobristTableElement *table = calloc(length, sizeof *table); + return (struct zobristTable){table, length}; } static size_t zobristTableInitialI(const struct zobristTable table, const uint_least64_t key) { return key % table.length; } -enum returnStatus { - CONTINUE, - RETURN, -}; - -static void zobristTableIter(const struct zobristTable table, const uint_least64_t key, void *result, - enum returnStatus (*foreach)(const struct zobristTableElement element, const uint_least64_t key, void *result)) { +void zobristTableIter(const struct zobristTable table, const uint_least64_t key, void *result, + void (*callback)(struct zobristTableElement *element, const uint_least64_t key, void *result)) { const size_t initI = zobristTableInitialI(table, key); size_t i = initI; do { - const struct zobristTableElement element = table.arr[i]; - if(foreach(element, key, result) == RETURN) return; + struct zobristTableElement *element = table.arr + i; + if(element->hash == 0 || element->hash == key) { + callback(element, key, result); + } ++i; if(i >= table.length) i = 0; } while(i != initI); @@ -51,29 +48,29 @@ static void zobristTableIter(const struct zobristTable table, const uint_least64 exit(1); } -static enum returnStatus zobristTableGetForeach(const struct zobristTableElement element, const uint_least64_t key, +static void zobristTableItemPtrCallback(struct zobristTableElement *element, const uint_least64_t key, void *resultVoid) { - struct zobristTableResult *result = resultVoid; - if(element.hash == key) { - *result = (struct zobristTableResult){true, element.value}; - return RETURN; - } - if(element.hash == 0) { - result->success = false; - return RETURN; - } - return CONTINUE; + struct zobristTableElement **result = resultVoid; + if(element->hash == key) { + *result = element; + return; + } // if(hash == 0) + *result = NULL; } -struct zobristTableResult zobristTableGet(const struct zobristTable table, const uint_least64_t key) { - struct zobristTableResult result; - zobristTableIter(table, key, &result, zobristTableGetForeach); +static struct zobristTableElement* zobristTableItemPtr(const struct zobristTable table, const uint_least64_t key) { + struct zobristTableElement *result; + zobristTableIter(table, key, &result, zobristTableItemPtrCallback); return result; } -static enum returnStatus zobristTableSetForeach(const struct zobristTableElement element, const uint_least64_t key, - void *resultVoid) { +void zobristTableDelete(struct zobristTable table, const uint_least64_t key) { + struct zobristTableElement *element = zobristTableItemPtr(table, key); + if(element != NULL) element->hash = 0; } -void zobristTableSet(struct zobristTable table, const uint_least64_t key, const int_least16_t value) { +int_least16_t* zobristTableGetPtr(const struct zobristTable table, const uint_least64_t key) { + struct zobristTableElement *element = zobristTableItemPtr(table, key); + if(element == NULL) return NULL; + return &element->value; }