stellar

UCI Chess engine written in C++20
git clone git://git.dimitrijedobrota.com/stellar.git
Log | Files | Refs | README | LICENSE |

commit3ca8bda95f268b5177b3a0c22bf7bbcd21df775c
parent317a3513ae4fca24f5ab9d34b38e198c396b5774
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateMon, 7 Aug 2023 10:31:05 +0200

Initialize Zobrist keys and generate hash

Diffstat:
Msrc/attacks/magic_generate.c|+--
Msrc/board/CMakeLists.txt|+
Msrc/board/board.c|+++++
Asrc/board/zobrist.c|++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/engine/CMakeLists.txt|+
Msrc/engine/engine.c|+++++++++----
Msrc/include/board.h|++
Asrc/include/zobrist.h|+++++++++

8 files changed, 94 insertions(+), 6 deletions(-)


diff --git a/src/attacks/magic_generate.c b/src/attacks/magic_generate.c

@@ -10,8 +10,7 @@

const char *FORMAT = "C64(0x%llx),\n";
U64 generate_magic_number() {
return random_get_U64() & random_get_U64() &
random_get_U64();
return random_get_U64() & random_get_U64() & random_get_U64();
}
U64 find_magic_number(Square square, int relevant_bits, int bishop) {

diff --git a/src/board/CMakeLists.txt b/src/board/CMakeLists.txt

@@ -1,5 +1,6 @@

add_library(board OBJECT
board.c
zobrist.c
)
target_include_directories(board

diff --git a/src/board/board.c b/src/board/board.c

@@ -6,6 +6,7 @@

#include <cul/mem.h>
#include "board.h"
#include "zobrist.h"
Board *board_new(void) {
Board *p;

@@ -22,6 +23,8 @@ eCastle board_castle(const Board *self) { return self->castle; }

eColor board_side(const Board *self) { return self->side; }
U64 board_color(const Board *self, eColor color) { return self->color[color]; }
U64 board_piece(const Board *self, ePiece piece) { return self->piece[piece]; }
U64 board_hash(const Board *self) { return self->hash; }
U64 board_occupancy(const Board *self) {
return self->color[WHITE] | self->color[BLACK];
}

@@ -177,6 +180,7 @@ Board *board_from_FEN(Board *board, const char *fen) {

board->enpassant = coordinates_to_square(fen);
}
board->hash = zobrist_hash(board);
return board;
}

@@ -213,5 +217,6 @@ void board_print(const Board *self) {

printf(" Castling: %c%c%c%c\n", (self->castle & WK) ? 'K' : '-',
(self->castle & WQ) ? 'Q' : '-', (self->castle & BK) ? 'k' : '-',
(self->castle & BQ) ? 'q' : '-');
printf(" Hash: %llu\n", self->hash);
printf("\n");
}

diff --git a/src/board/zobrist.c b/src/board/zobrist.c

@@ -0,0 +1,66 @@

#include "zobrist.h"
#include "board.h"
#include "piece.h"
#include "random.h"
#include "utils.h"
U64 castle_keys[16];
U64 enpassant_keys[64];
U64 piece_keys[16][64];
U64 side_key;
void init_hash_keys() {
random_state_reset();
for (int piece = PAWN; piece <= KING; piece++) {
int piece_index_white = piece_index(piece_get(piece, WHITE));
int piece_index_black = piece_index(piece_get(piece, BLACK));
for (int square = 0; square < 64; square++) {
piece_keys[piece_index_white][square] = random_get_U64();
piece_keys[piece_index_black][square] = random_get_U64();
}
}
for (int square = 0; square < 64; square++) {
enpassant_keys[square] = random_get_U64();
}
for (int castle = 0; castle < 16; castle++) {
castle_keys[castle] = random_get_U64();
}
side_key = random_get_U64();
}
void zobrist_init(void) { init_hash_keys(); }
U64 zobrist_hash(const Board *board) {
U64 key_final = C64(0);
Square square;
for (int piece = PAWN; piece <= KING; piece++) {
Piece piece_white = piece_get(piece, WHITE);
U64 bitboard_white = board_pieceSet(board, piece_white);
int piece_white_index = piece_index(piece_white);
bitboard_for_each_bit(square, bitboard_white) {
key_final ^= piece_keys[piece_white_index][square];
}
Piece piece_black = piece_get(piece, BLACK);
U64 bitboard_black = board_pieceSet(board, piece_black);
int piece_black_index = piece_index(piece_black);
bitboard_for_each_bit(square, bitboard_black) {
key_final ^= piece_keys[piece_black_index][square];
}
}
key_final ^= castle_keys[board_castle(board)];
if (board_side(board)) key_final ^= side_key;
if (board_enpassant(board) != no_sq)
key_final ^= enpassant_keys[board_enpassant(board)];
return key_final;
}

diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt

@@ -7,6 +7,7 @@ target_link_libraries(engine

PRIVATE piece
PRIVATE score
PRIVATE utils
PRIVATE random
)
target_link_libraries(engine PRIVATE "cul")

diff --git a/src/engine/engine.c b/src/engine/engine.c

@@ -9,6 +9,7 @@

#include "perft.h"
#include "score.h"
#include "utils.h"
#include "zobrist.h"
#include <cul/assert.h>
#include <cul/mem.h>

@@ -455,7 +456,7 @@ Board *Instruction_parse(Instruction *self, Board *board) {

}
void uci_loop(void) {
Board *board = NULL;
Board board;
Instruction *instruction;
char input[200000];

@@ -469,18 +470,22 @@ void uci_loop(void) {

if (!fgets(input, sizeof(input), stdin)) continue;
instruction = Instruction_new(input);
if (!(board = Instruction_parse(instruction, board))) break;
if (!Instruction_parse(instruction, &board)) break;
Instruction_free(&instruction);
}
Instruction_free(&instruction);
board_free(&board);
}
/* MAIN */
int main(void) {
void init(void) {
attacks_init();
zobrist_init();
}
int main(void) {
init();
uci_loop();
return 0;
}

diff --git a/src/include/board.h b/src/include/board.h

@@ -15,6 +15,7 @@ typedef struct Board Board;

struct Board {
U64 color[2];
U64 piece[6];
U64 hash;
eColor side;
Square enpassant;
eCastle castle;

@@ -30,6 +31,7 @@ U64 board_piece(const Board *self, ePiece piece);

eCastle board_castle(const Board *self);
eColor board_side(const Board *self);
Square board_enpassant(const Board *self);
U64 board_hash(const Board *self);
void board_enpassant_set(Board *self, Square target);

diff --git a/src/include/zobrist.h b/src/include/zobrist.h

@@ -0,0 +1,9 @@

#ifndef STELLAR_ZOBRIST_H
#define STELLAR_ZOBRIST_H
#include "board.h"
void zobrist_init(void);
U64 zobrist_hash(const Board *board);
#endif