diff --git a/include/chess/bitboard.h b/include/chess/bitboard.h index f8fce21..1e72b35 100644 --- a/include/chess/bitboard.h +++ b/include/chess/bitboard.h @@ -2,6 +2,8 @@ #include #include +#define REPETETION_TABLE_LENGTH 1024 + bool bitboardGet(const uint_least64_t *board, struct piece_t piece, uint_least8_t i); uint_least64_t bitboardGetMask(const uint_least64_t *board, struct piece_t piece); void bitboardSetMask(uint_least64_t *board, struct piece_t piece, uint_least64_t value); @@ -10,4 +12,5 @@ uint_least64_t bitboardMaskAllPieces(const uint_least64_t *board); void bitboardClear(uint_least64_t *board, struct piece_t piece, uint_least8_t i); void bitboardSet(uint_least64_t *board, struct piece_t piece, uint_least8_t i); struct piece_t pieceAtField(const uint_least64_t *board, uint_least8_t i); -struct gameState_t newGameState(uint_least64_t *board, char *FEN); +struct gameState_t newGameState(uint_least64_t *board, + struct zobristTableElement *repetitionTableStore, char *FEN); diff --git a/include/chess/util.h b/include/chess/util.h index 8a98f53..f267d44 100644 --- a/include/chess/util.h +++ b/include/chess/util.h @@ -11,8 +11,8 @@ 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); +struct zobristTable initZobirstTable(struct zobristTableElement *table, 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)); + void (*callback)(struct zobristTableElement *element, const uint_least64_t key, void *result)); #endif diff --git a/src/chess/evaluate.c b/src/chess/evaluate.c index 9b529cc..b9bed3d 100644 --- a/src/chess/evaluate.c +++ b/src/chess/evaluate.c @@ -64,7 +64,7 @@ static int_least16_t alphaBeta(const struct gameState_t gameState, int_fast16_t const struct move_t move = moves[i]; const struct gameState_t newGameState = makeMove(gameState, move); const int_least16_t score = -alphaBeta(newGameState, -beta, -alpha, depth - 1); - undoMove(gameState.board, move, gameState.color); + undoMove(newGameState, move, gameState.color); if(score >= beta) { return beta; // beta-cutoff } @@ -85,7 +85,7 @@ static struct move_t searchRoot(const struct gameState_t gameState, uint_least8_ const struct move_t move = moves[i]; const struct gameState_t newGameState = makeMove(gameState, move); const int_least16_t score = -alphaBeta(newGameState, -beta, -alpha, depth - 1); - undoMove(gameState.board, move, gameState.color); + undoMove(newGameState, move, gameState.color); if(score > alpha) { alpha = score; // alpha acts like max in MiniMax selectedMove = move; diff --git a/src/chess/main.c b/src/chess/main.c index f375728..9a4a015 100644 --- a/src/chess/main.c +++ b/src/chess/main.c @@ -190,8 +190,9 @@ static void app_activate(GApplication *app, gpointer data) { GtkWindow *window = GTK_WINDOW(gtk_window_new()); static RsvgHandle *piecesSvg[2 * PIECES_LENGTH]; static uint_least64_t board[BITBOARD_LENGTH]; + static struct zobristTableElement repetitionTableStore[REPETETION_TABLE_LENGTH]; static struct gameState_t gameState; - gameState = newGameState(board, START_FEN); + gameState = newGameState(board, repetitionTableStore, START_FEN); { static struct move_t moves[TOTAL_BOARD_SIZE]; static struct drawData_t drawData = {piecesSvg, &gameState, NOT_SELECTED, moves, 0, NOT_SELECTED}; diff --git a/src/chess/move.c b/src/chess/move.c index cce80ef..3670f8f 100644 --- a/src/chess/move.c +++ b/src/chess/move.c @@ -166,7 +166,7 @@ static void zobristTableUndoMoveCallback(struct zobristTableElement *element, co fprintf(stderr, "Error: Position does not in repetitionTable in undoMove (move.c)"); } -void undoMove(struct gameState_t gameState, struct move_t move, bool color) { +void undoMove(const 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}; @@ -177,6 +177,7 @@ void undoMove(struct gameState_t gameState, struct move_t move, bool color) { bitboardSet(board, piece, getCapturePos(move.src, move.dst, move.spezialMove)); } castleMoveRook(board, move.spezialMove, color, true); + zobristTableIter(gameState.repetitionTable, gameState.zobrist, NULL, zobristTableUndoMoveCallback); } static void setCastleInfoRook(struct castle_t *canCastle, uint_least8_t posOnRank) { @@ -257,14 +258,14 @@ static void addMove(struct addMoveCtx_t ctx, struct piece_t movedPiece, uint_lea } move.hash = hash; } - makeMove(gameState, move); + struct gameState_t newGameState = makeMove(gameState, move); { const bool color = gameState.color; if(!kingInCheck(board, color)) { ctx.moves[*movesLength] = move; ++*movesLength; } - undoMove(board, move, color); + undoMove(newGameState, move, color); } } diff --git a/src/common/postCodeGen/bitboard.c b/src/common/postCodeGen/bitboard.c index 63528d4..82b7f34 100644 --- a/src/common/postCodeGen/bitboard.c +++ b/src/common/postCodeGen/bitboard.c @@ -6,6 +6,7 @@ #include #include #include +#include uint_least64_t bitboardGetMask(const uint_least64_t *board, struct piece_t piece) { return board[piece.color * PIECES_LENGTH + piece.type]; @@ -66,7 +67,8 @@ struct piece_t pieceAtField(const uint_least64_t *board, uint_least8_t i) { } } -struct gameState_t newGameState(uint_least64_t *board, char *FEN) { +struct gameState_t newGameState(uint_least64_t *board, + struct zobristTableElement *repetitionTableStore, char *FEN) { struct gameState_t gameState = {board, 0}; for(uint_least8_t i = 0; i < BITBOARD_LENGTH; ++i) { board[i] = 0; @@ -134,6 +136,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); + gameState.repetitionTable = initZobirstTable(repetitionTableStore, REPETETION_TABLE_LENGTH); return gameState; } diff --git a/src/common/preCodeGen/util.c b/src/common/preCodeGen/util.c index 364d347..57a75cc 100644 --- a/src/common/preCodeGen/util.c +++ b/src/common/preCodeGen/util.c @@ -23,8 +23,10 @@ uint_least8_t getRank(const uint_least8_t field) { return field / BOARD_SIZE; } -struct zobristTable initZobirstTable(size_t length) { - struct zobristTableElement *table = calloc(length, sizeof *table); +struct zobristTable initZobirstTable(struct zobristTableElement *table, size_t length) { + for(size_t i = 0; i < length; ++i) { + table[i].hash = 0; + } return (struct zobristTable){table, length}; } diff --git a/test/moveGen.c b/test/moveGen.c index f48b78b..2d49429 100644 --- a/test/moveGen.c +++ b/test/moveGen.c @@ -21,14 +21,15 @@ static uint_least64_t perft(const struct gameState_t gameState, const uint_least for(uint_least8_t i = 0; i < movesLength; ++i) { const struct gameState_t newGameState = makeMove(gameState, moves[i]); nodes += perft(newGameState, depth - 1); - undoMove(gameState.board, moves[i], gameState.color); + undoMove(newGameState, moves[i], gameState.color); } return nodes; } static void test(struct perf_t perf, const uint_least8_t i) { uint_least64_t board[BITBOARD_LENGTH]; - const struct gameState_t gameState = newGameState(board, perf.FEN); + struct zobristTableElement repetitionTableStore[REPETETION_TABLE_LENGTH]; + const struct gameState_t gameState = newGameState(board, repetitionTableStore, perf.FEN); const uint_least64_t nodes = perft(gameState, perf.depth); if(perf.nodes != nodes) { printf("Test %" PRIuLEAST16 " failed: FEN: %s, depth: %" PRIuLEAST8 " calculated nodes: %" PRIuLEAST64 @@ -38,7 +39,7 @@ static void test(struct perf_t perf, const uint_least8_t i) { for(uint_least8_t j = 0; j < movesLength; ++j) { const struct gameState_t newGameState = makeMove(gameState, moves[j]); const uint_least64_t nodes = perft(newGameState, perf.depth - 1); - undoMove(gameState.board, moves[j], gameState.color); + undoMove(newGameState, moves[j], gameState.color); { printMove(moves[j]); printf(" %" PRIuLEAST64 "\n", nodes);