repetition table

This commit is contained in:
2024-09-23 21:51:22 +02:00
parent 6c5ef0586f
commit 2c3d1bc021
6 changed files with 71 additions and 48 deletions

View File

@ -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, uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece, uint_least8_t src,
struct move_t *moves, bool promotion); 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); struct gameState_t makeMove(struct gameState_t gameState, const struct move_t move);
void initMagicTable(); void initMagicTable();
bool kingInCheck(const uint_least64_t *board, const bool color); bool kingInCheck(const uint_least64_t *board, const bool color);

View File

@ -3,6 +3,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h>
#define BOARD_SIZE 8 #define BOARD_SIZE 8
#define TOTAL_BOARD_SIZE (BOARD_SIZE * BOARD_SIZE) #define TOTAL_BOARD_SIZE (BOARD_SIZE * BOARD_SIZE)
@ -35,6 +36,16 @@ enum directions {
NORTH, NORTHWEST, WEST, SOUTHWEST, SOUTH, SOUTHEAST, EAST, NORTHEAST, DIRECTION_LENGTH 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 { struct moveDst_t {
uint_least8_t length; uint_least8_t length;
uint_least8_t dst[8]; uint_least8_t dst[8];
@ -54,7 +65,7 @@ struct castle_t {
struct gameState_t { struct gameState_t {
uint_least64_t *board; uint_least64_t *board;
uint_least64_t zobrist; uint_least64_t zobrist;
uint_least8_t *repetitionTable; struct zobristTable repetitionTable;
bool color; // color to move bool color; // color to move
struct castle_t canCastle[2]; struct castle_t canCastle[2];

View File

@ -1,24 +1,18 @@
#ifndef CHESS_UTIL_H
#define CHESS_UTIL_H
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <chess/types.h> #include <chess/types.h>
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 rand_64();
uint_least64_t zobristPieceI(struct piece_t piece, uint_least8_t field); uint_least64_t zobristPieceI(struct piece_t piece, uint_least8_t field);
uint_least8_t getFile(const uint_least8_t field); uint_least8_t getFile(const uint_least8_t field);
uint_least8_t getRank(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

View File

@ -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 srcPiece = {move.srcPiece, color};
const struct piece_t dstPiece = {move.dstPiece, color}; const struct piece_t dstPiece = {move.dstPiece, color};
bitboardSet(board, srcPiece, move.src); bitboardSet(board, srcPiece, move.src);
@ -397,6 +406,16 @@ uint_least8_t validMoves(struct gameState_t gameState, struct move_t *moves) {
return movesLength; 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) { struct gameState_t makeMove(struct gameState_t gameState, const struct move_t move) {
uint_least64_t *board = gameState.board; uint_least64_t *board = gameState.board;
const struct piece_t srcPiece = {move.srcPiece, gameState.color}; 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; else ++gameState.halfMoveCounter;
gameState.color = !gameState.color; gameState.color = !gameState.color;
gameState.zobrist ^= move.hash; gameState.zobrist ^= move.hash;
zobristTableIter(gameState.repetitionTable, gameState.zobrist, NULL, zobristTableMakeMoveCallback);
return gameState; return gameState;
} }

View File

@ -134,5 +134,6 @@ struct gameState_t newGameState(uint_least64_t *board, char *FEN) {
gameState.enPassantTo += (BOARD_SIZE - *FEN++) * BOARD_SIZE; gameState.enPassantTo += (BOARD_SIZE - *FEN++) * BOARD_SIZE;
} }
gameState.halfMoveCounter = atoi(++FEN); gameState.halfMoveCounter = atoi(++FEN);
gameState.repetitionTable = initZobirstTable(1000);
return gameState; return gameState;
} }

View File

@ -1,3 +1,4 @@
#include "chess/types.h"
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -22,28 +23,24 @@ uint_least8_t getRank(const uint_least8_t field) {
return field / BOARD_SIZE; return field / BOARD_SIZE;
} }
void initZobirstTable(struct zobristTableElement *table, size_t length) { struct zobristTable initZobirstTable(size_t length) {
for(size_t i = 0; i < length; ++i) { struct zobristTableElement *table = calloc(length, sizeof *table);
table[i].hash = 0; // use 0 for no value return (struct zobristTable){table, length};
}
} }
static size_t zobristTableInitialI(const struct zobristTable table, const uint_least64_t key) { static size_t zobristTableInitialI(const struct zobristTable table, const uint_least64_t key) {
return key % table.length; return key % table.length;
} }
enum returnStatus { void zobristTableIter(const struct zobristTable table, const uint_least64_t key, void *result,
CONTINUE, void (*callback)(struct zobristTableElement *element, const uint_least64_t key, void *result)) {
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)) {
const size_t initI = zobristTableInitialI(table, key); const size_t initI = zobristTableInitialI(table, key);
size_t i = initI; size_t i = initI;
do { do {
const struct zobristTableElement element = table.arr[i]; struct zobristTableElement *element = table.arr + i;
if(foreach(element, key, result) == RETURN) return; if(element->hash == 0 || element->hash == key) {
callback(element, key, result);
}
++i; ++i;
if(i >= table.length) i = 0; if(i >= table.length) i = 0;
} while(i != initI); } while(i != initI);
@ -51,29 +48,29 @@ static void zobristTableIter(const struct zobristTable table, const uint_least64
exit(1); 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) { void *resultVoid) {
struct zobristTableResult *result = resultVoid; struct zobristTableElement **result = resultVoid;
if(element.hash == key) { if(element->hash == key) {
*result = (struct zobristTableResult){true, element.value}; *result = element;
return RETURN; return;
} } // if(hash == 0)
if(element.hash == 0) { *result = NULL;
result->success = false;
return RETURN;
}
return CONTINUE;
} }
struct zobristTableResult zobristTableGet(const struct zobristTable table, const uint_least64_t key) { static struct zobristTableElement* zobristTableItemPtr(const struct zobristTable table, const uint_least64_t key) {
struct zobristTableResult result; struct zobristTableElement *result;
zobristTableIter(table, key, &result, zobristTableGetForeach); zobristTableIter(table, key, &result, zobristTableItemPtrCallback);
return result; return result;
} }
static enum returnStatus zobristTableSetForeach(const struct zobristTableElement element, const uint_least64_t key, void zobristTableDelete(struct zobristTable table, const uint_least64_t key) {
void *resultVoid) { 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;
} }