zobrist hashing

This commit is contained in:
2024-09-22 11:45:30 +02:00
parent 4d2a86c7b7
commit db958dcac1
21 changed files with 273 additions and 176 deletions

3
.gitignore vendored
View File

@ -1,6 +1,6 @@
/*
!/src
/include/chess/generated/*
/src/generated
!/CMakeLists.txt
!/README.md
!/LICENSE
@ -8,5 +8,6 @@
!/lib
!.gitkeep
!/include
/include/chess/generated/*
!/.gitignore
!/test

View File

@ -1,29 +1,36 @@
cmake_minimum_required(VERSION 3.18)
project(chess C)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_STANDARD 99)
include_directories(include)
file(GLOB SOURCES "src/chess/*.c")
file(GLOB LIB_SOURCES "src/common/*.c")
file(GLOB CODE_GEN_LIB_SOURCES "src/common/preCodeGen/*.c")
file(GLOB LIB_SOURCES "src/common/*/*.c" "src/generated/*.c")
add_executable(genMoveConsts src/generateCode/moveConsts.c src/common/bitboard.c
src/common/print.c)
add_executable(genMoveConsts src/generateCode/moveConsts.c ${CODE_GEN_LIB_SOURCES})
add_custom_command(
OUTPUT moveConsts.h # Output file from code generation
COMMAND genMoveConsts > include/chess/generated/moveConsts.h
DEPENDS genMoveConsts # Depends on the code generation executable
)
add_custom_target(generateCode DEPENDS moveConsts.h)
add_executable(genZobrist src/generateCode/zobrist.c ${CODE_GEN_LIB_SOURCES})
add_custom_command(
OUTPUT zobristConsts.c # Output file from code generation
COMMAND genZobrist > src/generated/zobristConsts.c
DEPENDS genZobrist # Depends on the code generation executable
)
add_custom_target(generateCode DEPENDS moveConsts.h zobristConsts.c)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK4 REQUIRED IMPORTED_TARGET gtk4)
pkg_check_modules(LIBRSVG REQUIRED IMPORTED_TARGET librsvg-2.0)
add_executable(findMagicNumber src/findMagicNumber.c ${LIB_SOURCES})
set_property(TARGET findMagicNumber PROPERTY C_STANDARD 99)
add_dependencies(findMagicNumber generateCode)
add_executable(${PROJECT_NAME} ${SOURCES} ${LIB_SOURCES})
set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 99)
target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::GTK4 PkgConfig::LIBRSVG)
add_dependencies(${PROJECT_NAME} generateCode)
@ -39,11 +46,9 @@ if(CMAKE_BUILD_TYPE MATCHES "Release")
endif()
add_executable(chessNoComputer ${SOURCES} ${LIB_SOURCES})
set_property(TARGET chessNoComputer PROPERTY C_STANDARD 99)
target_link_libraries(chessNoComputer PRIVATE PkgConfig::GTK4 PkgConfig::LIBRSVG)
add_dependencies(chessNoComputer generateCode)
target_compile_definitions(chessNoComputer PUBLIC NO_COMPUTER)
add_executable(moveGenTest test/moveGen.c src/chess/move.c ${LIB_SOURCES})
set_property(TARGET moveGenTest PROPERTY C_STANDARD 99)
add_test(NAME moveGen COMMAND moveGenTest)

View File

@ -2,9 +2,6 @@
#include <stdint.h>
#include <chess/types.h>
bool bitsetGet(uint_least64_t bitset, uint_least8_t i);
uint_least64_t bitsetClear(uint_least64_t bitset, uint_least8_t i);
uint_least64_t bitsetSet(uint_least64_t bitset, uint_least8_t i);
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);
@ -14,5 +11,3 @@ 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);
uint_least8_t getFile(const uint_least8_t field);
uint_least8_t getRank(const uint_least8_t field);

6
include/chess/bitset.h Normal file
View File

@ -0,0 +1,6 @@
#include <stdint.h>
#include <stdbool.h>
bool bitsetGet(uint_least64_t bitset, uint_least8_t i);
uint_least64_t bitsetClear(uint_least64_t bitset, uint_least8_t i);
uint_least64_t bitsetSet(uint_least64_t bitset, uint_least8_t i);

View File

@ -17,6 +17,7 @@ enum spezialMoves {
struct move_t {
uint_least8_t src, dst, spezialMove;
uint_least8_t srcPiece, dstPiece, capturedPiece;
uint_least64_t hash;
};
void genDirectionConsts();
@ -25,7 +26,7 @@ uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece
struct move_t *moves, bool promotion);
void undoMove(uint_least64_t *board, struct move_t move, bool color);
struct gameState_t makeMove(struct gameState_t gameState, struct move_t move);
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);
uint_least8_t getBaseRankI(bool color);

View File

@ -2,26 +2,29 @@
#include <stdint.h>
#include <chess/move.h>
#define fprintArray(file, printer, arr) \
#define fprintArrayCustomLength(file, printer, arr, length) \
do { \
fprintf(file, "{"); \
for(size_t i = 0; i < LENGTH(arr); ++i) { \
for(size_t i = 0; i < length; ++i) { \
printer(file, arr[i]); \
if (i < LENGTH(arr) - 1) { \
if (i < length - 1) { \
fprintf(file, ", "); \
} \
} \
fprintf(file, " }"); \
} while(0)
#define fprintArray(file, printer, arr) fprintArrayCustomLength(file, printer, arr, LENGTH(arr))
#define fdefineArray(file, declaration, printer, arr) \
#define fdefineArrayCustomLength(file, declaration, printer, arr, length) \
do { \
fprintf(file, "%s[%zu] = ", declaration, LENGTH(arr)); \
fprintArray(file, printer, arr); \
fprintf(file, "%s[%zu] = ", declaration, length); \
fprintArrayCustomLength(file, printer, arr, length); \
fprintf(file, ";\n"); \
} while(0)
#define fdefineArray(file, declaration, printer, arr) fdefineArrayCustomLength(file, declaration, printer, arr, LENGTH(arr))
#define defineArray(declaration, printer, arr) fdefineArray(stdout, declaration, printer, arr)
#define defineArrayCustomLength(declaration, printer, arr, length) fdefineArrayCustomLength(stdout, declaration, printer, arr, length)
#define defineArray(declaration, printer, arr) defineArrayCustomLength(declaration, printer, arr, LENGTH(arr))
void printerll(FILE *file, long long num);
void printerull(FILE *file, unsigned long long num);

View File

@ -1,3 +0,0 @@
#include <stdint.h>
uint_least64_t rand_64();

View File

@ -53,6 +53,7 @@ struct castle_t {
struct gameState_t {
uint_least64_t *board;
uint_least64_t zobrist;
bool color; // color to move
struct castle_t canCastle[2];

7
include/chess/util.h Normal file
View File

@ -0,0 +1,7 @@
#include <stdint.h>
#include <chess/types.h>
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);

View File

@ -0,0 +1,16 @@
#ifndef CHESS_ZOBRIST_CONSTS_H
#define CHESS_ZOBRIST_CONSTS_H
#include "chess/types.h"
#include <stdint.h>
#define ZOBRIST_CASTLE_LENGTH 2
#define ZOBRIST_PIECE_LENGTH (TOTAL_BOARD_SIZE * 2 * PIECES_LENGTH)
extern const uint_least64_t ZOBRIST_PIECE[];
extern const uint_least64_t ZOBRIST_BLACK_MOVE;
extern const uint_least64_t ZOBRIST_SHORT_CASTLE[ZOBRIST_CASTLE_LENGTH];
extern const uint_least64_t ZOBRIST_LONG_CASTLE[ZOBRIST_CASTLE_LENGTH];
extern const uint_least64_t ZOBRIST_EN_PASSENT_FILE[BOARD_SIZE];
#endif

View File

@ -10,6 +10,7 @@
#include <chess/move.h>
#include <chess/bitboard.h>
#include "evaluate.h"
#include <chess/util.h>
#define START_FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"

View File

@ -9,6 +9,10 @@
#include <stdio.h>
#include "magicNumber.h"
#include <chess/magic.h>
#include <chess/util.h>
#include <chess/bitset.h>
#include <chess/zobristConsts.h>
#include <string.h>
#ifdef _MSC_VER
#include <intrin.h>
@ -29,7 +33,7 @@ static uint_least8_t trailingBits(uint_least64_t num) {
unsigned long i;
_BitScanForward(&i, num);
return i;
#elif
#else
uint_least8_t count = 0;
while ((num & 1) == 0) { // Keep shifting num right until the least significant bit is 1
num >>= 1;
@ -166,31 +170,87 @@ void undoMove(uint_least64_t *board, struct move_t move, bool color) {
castleMoveRook(board, move.spezialMove, color, true);
}
static void setCastleInfoRook(struct castle_t *canCastle, uint_least8_t posOnRank) {
switch(posOnRank) {
case 0:
canCastle->longCastle = false;
break;
case BOARD_SIZE - 1:
canCastle->shortCastle = false;
break;
}
}
static void setCastleInfo(struct castle_t *canCastle, const bool color, const struct move_t move) {
{
struct castle_t *canCastleCurrentPlayer = canCastle + color;
if(canCastleCurrentPlayer->longCastle || canCastleCurrentPlayer->shortCastle) {
if(move.dstPiece == KING) {
canCastleCurrentPlayer->longCastle = false;
canCastleCurrentPlayer->shortCastle = false;
}
else {
setCastleInfoRook(canCastleCurrentPlayer, move.src - getBaseRankI(color));
}
}
}
{
// if the rook is captured
struct castle_t *canCastleOther = canCastle + !color;
if(canCastleOther->longCastle || canCastleOther->shortCastle) {
setCastleInfoRook(canCastleOther, move.dst - getBaseRankI(!color));
}
}
}
static void addMove(struct addMoveCtx_t ctx, struct piece_t movedPiece, uint_least8_t src,
uint_least8_t dst, uint_least8_t spezialMove, uint_least8_t promotionPiece) {
uint_least64_t *board = ctx.gameState.board;
uint_least8_t *movesLength = ctx.movesLength;
uint_least8_t capturedPiece = NOT_SELECTED;
const uint_least8_t dstPiece = promotionPiece == NOT_SELECTED ? movedPiece.type : promotionPiece;
const struct piece_t pieceAll = {ALL_PIECES, movedPiece.color};
if(bitboardGet(board, pieceAll, dst)) return;
struct gameState_t gameState = ctx.gameState;
uint_least64_t *board = gameState.board;
{
const struct piece_t pieceAllOtherColor = {ALL_PIECES, !movedPiece.color};
const struct piece_t pieceAll = {ALL_PIECES, movedPiece.color};
if(bitboardGet(board, pieceAll, dst)) return;
}
uint_least8_t *movesLength = ctx.movesLength;
uint_least8_t capturedPieceType = NOT_SELECTED;
const uint_least8_t dstPieceType = promotionPiece == NOT_SELECTED ? movedPiece.type : promotionPiece;
uint_least64_t hash = ZOBRIST_PIECE[zobristPieceI(movedPiece, src)] ^ ZOBRIST_BLACK_MOVE;
{
const struct piece_t dstPiece = {dstPieceType, movedPiece.color};
hash ^= ZOBRIST_PIECE[zobristPieceI(dstPiece, dst)];
}
{
const bool otherColor = !movedPiece.color;
const struct piece_t pieceAllOtherColor = {ALL_PIECES, otherColor};
const uint_least8_t capturePos = getCapturePos(src, dst, spezialMove);
if(bitboardGet(board, pieceAllOtherColor, capturePos)) {
for(uint_least8_t pieceType = QUEEN; pieceType < PIECES_LENGTH; ++pieceType) {
const struct piece_t piece = {pieceType, !movedPiece.color};
if(bitboardGet(board, piece, capturePos)) {
capturedPiece = pieceType;
const struct piece_t capturedPiece = {pieceType, otherColor};
hash ^= ZOBRIST_PIECE[zobristPieceI(capturedPiece, dst)];
capturedPieceType = pieceType;
break;
}
}
}
}
const struct move_t move = {src, dst, spezialMove, movedPiece.type, dstPiece, capturedPiece};
makeMove(ctx.gameState, move);
if(gameState.enPassantTo != NOT_SELECTED) hash ^= ZOBRIST_EN_PASSENT_FILE[getFile(gameState.enPassantTo)];
if(spezialMove == FUTURE_EN_PASSANT) hash ^= ZOBRIST_EN_PASSENT_FILE[getFile(src)];
struct move_t move = {src, dst, spezialMove, movedPiece.type, dstPieceType, capturedPieceType, hash};
{
const bool color = ctx.gameState.color;
struct castle_t canCastle[2];
memcpy(canCastle, gameState.canCastle, sizeof canCastle);
setCastleInfo(canCastle, gameState.color, move);
for(uint_least8_t color = BLACK; color <= WHITE; ++color) {
if(canCastle[color].shortCastle != gameState.canCastle[color].shortCastle) hash ^= ZOBRIST_SHORT_CASTLE[color];
if(canCastle[color].longCastle != gameState.canCastle[color].longCastle) hash ^= ZOBRIST_LONG_CASTLE[color];
}
move.hash = hash;
}
makeMove(gameState, move);
{
const bool color = gameState.color;
if(!kingInCheck(board, color)) {
ctx.moves[*movesLength] = move;
++*movesLength;
@ -303,7 +363,7 @@ uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece
uint_least8_t dst = src + DIRECTION_MODIFIER[pawnDirection];
if(!bitboardGetAllPieces(board, dst)) {
movePawn(addmoveCtx, piece.color, src, dst, promotion, 0);
if(getFile(src) == (piece.color == WHITE ? BOARD_SIZE - 2 : 1)) {
if(getRank(src) == (piece.color == WHITE ? BOARD_SIZE - 2 : 1)) {
dst += DIRECTION_MODIFIER[pawnDirection];
if(!bitboardGetAllPieces(board, dst)) {
movePawn(addmoveCtx, piece.color, src, dst, promotion, FUTURE_EN_PASSANT);
@ -337,18 +397,7 @@ uint_least8_t validMoves(struct gameState_t gameState, struct move_t *moves) {
return movesLength;
}
static void setCastleInfo(struct castle_t *canCastle, uint_least8_t posOnRank) {
switch(posOnRank) {
case 0:
canCastle->longCastle = false;
break;
case BOARD_SIZE - 1:
canCastle->shortCastle = false;
break;
}
}
struct gameState_t makeMove(struct gameState_t gameState, struct move_t move) {
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};
const struct piece_t dstPiece = {move.dstPiece, gameState.color};
@ -359,25 +408,7 @@ struct gameState_t makeMove(struct gameState_t gameState, struct move_t move) {
bitboardClear(board, capturedPiece, getCapturePos(move.src, move.dst, move.spezialMove));
}
castleMoveRook(board, move.spezialMove, gameState.color, false);
{
struct castle_t *canCastleCurrentPlayer = gameState.canCastle + gameState.color;
if(canCastleCurrentPlayer->longCastle || canCastleCurrentPlayer->shortCastle) {
if(move.dstPiece == KING) {
canCastleCurrentPlayer->longCastle = false;
canCastleCurrentPlayer->shortCastle = false;
}
else {
setCastleInfo(canCastleCurrentPlayer, move.src - getBaseRankI(gameState.color));
}
}
}
{
// if the rook is captured
struct castle_t *canCastleOther = gameState.canCastle + !gameState.color;
if(canCastleOther->longCastle || canCastleOther->shortCastle) {
setCastleInfo(canCastleOther, move.dst - getBaseRankI(!gameState.color));
}
}
setCastleInfo(gameState.canCastle, gameState.color, move);
{
const int_least8_t dist = (int_least8_t)move.dst - (int_least8_t)move.src;
gameState.enPassantTo = move.spezialMove == FUTURE_EN_PASSANT ? move.src + dist / 2 : NOT_SELECTED;
@ -385,5 +416,6 @@ struct gameState_t makeMove(struct gameState_t gameState, struct move_t move) {
if(move.capturedPiece != NOT_SELECTED || srcPiece.type == PAWN) gameState.halfMoveCounter = 0;
else ++gameState.halfMoveCounter;
gameState.color = !gameState.color;
gameState.zobrist ^= move.hash;
return gameState;
}

View File

@ -1,20 +1,11 @@
#include "chess/zobristConsts.h"
#include <ctype.h>
#include <stdbool.h>
#include <stdint.h>
#include <chess/types.h>
#include <stdlib.h>
bool bitsetGet(uint_least64_t bitset, uint_least8_t i) {
return (bitset >> i) & 1u;
}
uint_least64_t bitsetClear(uint_least64_t bitset, uint_least8_t i) {
return bitset & ~((uint_least64_t)1 << i);
}
uint_least64_t bitsetSet(uint_least64_t bitset, uint_least8_t i) {
return bitset | ((uint_least64_t)1 << i);
}
#include <chess/util.h>
#include <chess/bitset.h>
uint_least64_t bitboardGetMask(const uint_least64_t *board, struct piece_t piece) {
return board[piece.color * PIECES_LENGTH + piece.type];
@ -76,69 +67,72 @@ 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 gameState = {board};
for(uint_least8_t i = 0; i < BITBOARD_LENGTH; ++i) {
board[i] = 0;
}
for(uint_least8_t field = 0; *FEN != ' '; ++FEN) {
struct piece_t piece;
switch(tolower(*FEN)) {
case 'k':
piece.type = KING;
break;
case 'q':
piece.type = QUEEN;
break;
case 'r':
piece.type = ROOK;
break;
case 'n':
piece.type = KNIGHT;
break;
case 'b':
piece.type = BISHOP;
break;
case 'p':
piece.type = PAWN;
break;
case '/':
continue;
default:
if(isdigit(*FEN)) {
field += *FEN - '0';
}
continue;
}
if(isalpha(*FEN)) piece.color = isupper(*FEN);
bitboardSet(board, piece, field);
++field;
}
gameState.color = *++FEN == 'w' ? WHITE : BLACK;
FEN += 2;
if(*FEN == '-') ++FEN;
else {
for(; *FEN != ' '; ++FEN) {
struct castle_t *playerCastle = gameState.canCastle + (isupper(*FEN) ? WHITE : BLACK);
if(tolower(*FEN) == 'k') playerCastle->shortCastle = true;
else playerCastle->longCastle = true;
}
}
if(*++FEN == '-'){
++FEN;
gameState.enPassantTo = NOT_SELECTED;
}
else {
gameState.enPassantTo = *FEN++ - 'a';
gameState.enPassantTo += (BOARD_SIZE - *FEN++) * BOARD_SIZE;
}
gameState.halfMoveCounter = atoi(++FEN);
return gameState;
struct gameState_t gameState = {board, 0};
for(uint_least8_t i = 0; i < BITBOARD_LENGTH; ++i) {
board[i] = 0;
}
uint_least8_t getFile(const uint_least8_t field) {
return field % BOARD_SIZE;
}
uint_least8_t getRank(const uint_least8_t field) {
return field / BOARD_SIZE;
for(uint_least8_t field = 0; *FEN != ' '; ++FEN) {
struct piece_t piece;
switch(tolower(*FEN)) {
case 'k':
piece.type = KING;
break;
case 'q':
piece.type = QUEEN;
break;
case 'r':
piece.type = ROOK;
break;
case 'n':
piece.type = KNIGHT;
break;
case 'b':
piece.type = BISHOP;
break;
case 'p':
piece.type = PAWN;
break;
case '/':
continue;
default:
if(isdigit(*FEN)) {
field += *FEN - '0';
}
continue;
}
if(isalpha(*FEN)) piece.color = isupper(*FEN);
bitboardSet(board, piece, field);
gameState.zobrist ^= ZOBRIST_PIECE[zobristPieceI(piece, field)];
++field;
}
gameState.color = *++FEN == 'w' ? WHITE : BLACK;
if(gameState.color == BLACK) gameState.zobrist ^= ZOBRIST_BLACK_MOVE;
FEN += 2;
if(*FEN == '-') ++FEN;
else {
for(; *FEN != ' '; ++FEN) {
const bool color = isupper(*FEN) ? WHITE : BLACK;
struct castle_t *playerCastle = gameState.canCastle + color;
if(tolower(*FEN) == 'k') {
playerCastle->shortCastle = true;
gameState.zobrist ^= ZOBRIST_SHORT_CASTLE[color];
}
else {
playerCastle->longCastle = true;
gameState.zobrist ^= ZOBRIST_LONG_CASTLE[color];
}
}
}
if(*++FEN == '-'){
++FEN;
gameState.enPassantTo = NOT_SELECTED;
}
else {
const uint_least8_t enPassentFile = *FEN++ - 'a';
gameState.zobrist ^= ZOBRIST_EN_PASSENT_FILE[enPassentFile];
gameState.enPassantTo = enPassentFile;
gameState.enPassantTo += (BOARD_SIZE - *FEN++) * BOARD_SIZE;
}
gameState.halfMoveCounter = atoi(++FEN);
return gameState;
}

View File

@ -1,7 +1,7 @@
#include <stdint.h>
#include <chess/types.h>
#include <chess/generated/moveConsts.h>
#include <chess/bitboard.h>
#include <chess/bitset.h>
uint_least64_t slidingMovementMask(const uint_least8_t *direction, uint_least8_t directionLength,
uint_least8_t field, uint_least64_t blockMask) {

View File

@ -0,0 +1,14 @@
#include <chess/bitset.h>
bool bitsetGet(uint_least64_t bitset, uint_least8_t i) {
return (bitset >> i) & 1u;
}
uint_least64_t bitsetClear(uint_least64_t bitset, uint_least8_t i) {
return bitset & ~((uint_least64_t)1 << i);
}
uint_least64_t bitsetSet(uint_least64_t bitset, uint_least8_t i) {
return bitset | ((uint_least64_t)1 << i);
}

View File

@ -2,7 +2,8 @@
#include "chess/types.h"
#include <stdio.h>
#include <stdint.h>
#include <chess/bitboard.h>
#include <chess/bitset.h>
#include <chess/util.h>
void printerll(FILE *file, long long num) {
fprintf(file, "%lld", num);

View File

@ -0,0 +1,22 @@
#include <stdint.h>
#include <stdlib.h>
#include <chess/util.h>
uint_least64_t rand_64() {
uint_least64_t u1, u2, u3, u4;
u1 = (uint_least64_t)(rand()) & 0xFFFF; u2 = (uint_least64_t)(rand()) & 0xFFFF;
u3 = (uint_least64_t)(rand()) & 0xFFFF; u4 = (uint_least64_t)(rand()) & 0xFFFF;
return u1 | (u2 << 16) | (u3 << 32) | (u4 << 48);
}
uint_least64_t zobristPieceI(struct piece_t piece, uint_least8_t field) {
return field * 2 * PIECES_LENGTH + piece.color * PIECES_LENGTH + piece.type;
}
uint_least8_t getFile(const uint_least8_t field) {
return field % BOARD_SIZE;
}
uint_least8_t getRank(const uint_least8_t field) {
return field / BOARD_SIZE;
}

View File

@ -1,10 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
#include <chess/rand.h>
uint_least64_t rand_64() {
uint_least64_t u1, u2, u3, u4;
u1 = (uint_least64_t)(rand()) & 0xFFFF; u2 = (uint_least64_t)(rand()) & 0xFFFF;
u3 = (uint_least64_t)(rand()) & 0xFFFF; u4 = (uint_least64_t)(rand()) & 0xFFFF;
return u1 | (u2 << 16) | (u3 << 32) | (u4 << 48);
}

View File

@ -9,7 +9,8 @@
#include <chess/magic.h>
#include <chess/generated/moveConsts.h>
#include <chess/bitboard.h>
#include <chess/rand.h>
#include <chess/bitset.h>
#include <chess/util.h>
#define MAX_BITS 12
#define MAX_SIZE (1 << MAX_BITS)

View File

@ -2,8 +2,9 @@
#include <chess/types.h>
#include <stdint.h>
#include <inttypes.h>
#include <chess/bitboard.h>
#include <chess/bitset.h>
#include <chess/print.h>
#include <chess/util.h>
static void printerMoveDst(FILE *file, struct moveDst_t moveDst) {
fprintf(file, "{ %" PRIuLEAST8 ", ", moveDst.length);

View File

@ -1,30 +1,39 @@
#include "chess/types.h"
#include "chess/zobristConsts.h"
#include <stdint.h>
#include <stdio.h>
#include <chess/rand.h>
#include <chess/util.h>
#include <stdlib.h>
#include <chess/print.h>
#include <inttypes.h>
static uint_least64_t zobristPieceI(struct piece_t piece, uint_least8_t field) {
return field * 2 * PIECES_LENGTH + piece.color * PIECES_LENGTH + piece.type;
}
int main() {
uint_least64_t zobristPiece[TOTAL_BOARD_SIZE * 2 * PIECES_LENGTH];
srand(0xc0229b8e);
printf("#ifndef CHESS_GENERATED_ZOBRIST_H\n"
"#define CHESS_GENERATED_ZOBRIST_H\n"
"#include <stdint.h>\n"
);
for(uint_least8_t color = BLACK; color <= WHITE; ++color) {
for(uint_least8_t pieceType = KING; pieceType < PIECES_LENGTH; ++pieceType) {
const struct piece_t piece = {pieceType, color};
for(uint_least8_t field = 0; field < TOTAL_BOARD_SIZE; ++field) {
zobristPiece[zobristPieceI(piece, field)] = rand_64();
printf("#include <stdint.h>\n");
{
uint_least64_t zobristPiece[ZOBRIST_PIECE_LENGTH];
for(uint_least8_t color = BLACK; color <= WHITE; ++color) {
for(uint_least8_t pieceType = KING; pieceType < PIECES_LENGTH; ++pieceType) {
const struct piece_t piece = {pieceType, color};
for(uint_least8_t field = 0; field < TOTAL_BOARD_SIZE; ++field) {
zobristPiece[zobristPieceI(piece, field)] = rand_64();
}
}
}
defineArray("const uint_least64_t ZOBRIST_PIECE", printerull, zobristPiece);
}
printf("const uint_least64_t ZOBRIST_BLACK_MOVE = %" PRIuLEAST64 "u;\n", rand_64());
{
uint_least64_t zobristRest[4 + BOARD_SIZE]; // 4 for castling
for(uint_least8_t i = 0; i < LENGTH(zobristRest); ++i) {
zobristRest[i] = rand_64();
}
uint_least64_t *zobristRestPtr = zobristRest;
const size_t castleLength = 2;
defineArrayCustomLength("const uint_least64_t ZOBRIST_SHORT_CASTLE", printerull, zobristRestPtr, castleLength);
zobristRestPtr += castleLength;
defineArrayCustomLength("const uint_least64_t ZOBRIST_LONG_CASTLE", printerull, zobristRestPtr, castleLength);
zobristRestPtr += castleLength;
defineArrayCustomLength("const uint_least64_t ZOBRIST_EN_PASSENT_FILE", printerull, zobristRestPtr, (size_t)BOARD_SIZE);
}
defineArray("#define defineZobristPiece const static uint_least64_t ZOBRIST_PIECE", printerull, zobristPiece);
printf("#define defineZobristBlackMove const uint_least64_t ZOBRIST_BLACK_MOVE = %" PRIuLEAST64 "\n", rand_64());
}