stellar

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

commitbc10eb327280374ae4808e9b1022e9eb70304e2f
parentd38fae0dac850deebce7355d806bfeac15776fd5
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateMon, 11 Mar 2024 15:56:57 +0000

Remove constexpr initialization from zobrist

Diffstat:
MCMakeLists.txt|+-
Msrc/arena/arena.cpp|+
Msrc/board/board.cpp|++++++++----
Msrc/board/board.hpp|++++++++++++-----------
Msrc/board/zobrist.hpp|+++++++++++++++++++++++++++++++++++-----------------------------------------------
Msrc/engine/engine.cpp|+++++----
Msrc/move/move.cpp|++--
Msrc/perft/CMakeLists.txt|----
Msrc/perft/perft.cpp|+

9 files changed, 64 insertions(+), 73 deletions(-)


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

@@ -3,7 +3,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

project(
Stellar
VERSION 1.2.4
VERSION 1.2.5
DESCRIPTION "Chess engine written in C++"
HOMEPAGE_URL https://git.dimitrijedobrota.com/stellar.git
LANGUAGES CXX

diff --git a/src/arena/arena.cpp b/src/arena/arena.cpp

@@ -97,6 +97,7 @@ int main(int argc, char *argv[]) {

positions.emplace_back(!strcmp(argv[i], "-") ? start_position : argv[i]);
attack::init();
zobrist::init();
Arena arena(engine1, engine2);
arena(positions, settings1, settings2);

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

@@ -1,7 +1,7 @@

#include <cctype>
#include <exception>
#include <cstdio>
#include <cstring>
#include <exception>
#include "board.hpp"
#include "piece.hpp"

@@ -9,6 +9,11 @@

#include "utils.hpp"
#include "zobrist.hpp"
/* Init arrays for Zobris hashing */
std::array<std::array<U64, 64>, 12> zobrist::keys_piece = {{{0}}};
std::array<U64, 64> zobrist::keys_enpassant = {{0}};
std::array<U64, 16> zobrist::keys_castle = {{0}};
/* Getters */
Board::Board(const std::string &fen) {

@@ -34,8 +39,7 @@ Board::Board(const std::string &fen) {

: throw std::runtime_error("Invalid player char");
for (i += 2; fen[i] != ' '; i++) {
if (fen[i] == 'K')
castle |= to_underlying(Castle::WK);
if (fen[i] == 'K') castle |= to_underlying(Castle::WK);
else if (fen[i] == 'Q')
castle |= to_underlying(Castle::WQ);
else if (fen[i] == 'k')

@@ -51,7 +55,7 @@ Board::Board(const std::string &fen) {

enpassant = fen[++i] != '-' ? square::from_coordinates(fen.substr(i, 2)) : square::no_sq;
hash = Zobrist::hash(*this);
hash = zobrist::hash(*this);
}
std::ostream &operator<<(std::ostream &os, const Board &board) {

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

@@ -41,11 +41,11 @@ class Board {

[[nodiscard]] inline constexpr U64 get_bitboard_piece(piece::Type piece, color::Color color) const;
[[nodiscard]] inline constexpr U64 get_bitboard_piece_attacks(piece::Type piece, color::Color color,
square::Square from) const;
square::Square from) const;
[[nodiscard]] inline constexpr U64 get_bitboard_piece_moves(piece::Type piece, color::Color color,
square::Square from) const;
square::Square from) const;
[[nodiscard]] inline constexpr U64 get_bitboard_square_land(square::Square land, piece::Type piece,
color::Color side) const;
color::Color side) const;
[[nodiscard]] inline constexpr color::Color get_square_piece_color(square::Square square) const;
[[nodiscard]] inline constexpr piece::Type get_square_piece_type(square::Square square) const;

@@ -71,8 +71,9 @@ class Board {

[[nodiscard]] inline constexpr bool is_square_attacked(square::Square square, color::Color side) const;
[[nodiscard]] inline constexpr bool is_square_occupied(square::Square square) const;
[[nodiscard]] inline constexpr bool is_piece_attack_square(piece::Type type, color::Color color, square::Square source,
square::Square target) const;
[[nodiscard]] inline constexpr bool is_piece_attack_square(piece::Type type, color::Color color,
square::Square source,
square::Square target) const;
[[nodiscard]] inline constexpr bool is_check() const;
private:

@@ -142,19 +143,19 @@ constexpr const piece::Piece *Board::get_square_piece(square::Square square) con

constexpr void Board::xor_hash(U64 op) { hash ^= op; }
constexpr void Board::and_castle(uint8_t right) {
hash ^= Zobrist::key_castle(castle);
hash ^= zobrist::key_castle(castle);
castle &= right;
hash ^= Zobrist::key_castle(castle);
hash ^= zobrist::key_castle(castle);
}
constexpr void Board::switch_side() {
side = color::other(side);
hash ^= Zobrist::key_side();
hash ^= zobrist::key_side();
}
constexpr void Board::set_enpassant(square::Square target) {
if (enpassant != square::Square::no_sq) hash ^= Zobrist::key_enpassant(enpassant);
if (target != square::Square::no_sq) hash ^= Zobrist::key_enpassant(target);
if (enpassant != square::Square::no_sq) hash ^= zobrist::key_enpassant(enpassant);
if (target != square::Square::no_sq) hash ^= zobrist::key_enpassant(target);
enpassant = target;
}

@@ -214,7 +215,7 @@ constexpr bool Board::is_check() const {

return is_square_attacked(square, side_other);
}
U64 Zobrist::hash(const Board &board) {
U64 zobrist::hash(const Board &board) {
U64 key_final = C64(0);
uint8_t square = 0;

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

@@ -9,57 +9,44 @@

#include <random>
class Board;
class Zobrist {
public:
Zobrist() = delete;
static inline U64 hash(const Board &board);
static inline constexpr U64 key_side() { return keys_side; }
static inline constexpr U64 key_castle(int exp) { return keys_castle[exp]; }
static inline constexpr U64 key_enpassant(square::Square square) {
return keys_enpassant[to_underlying(square)];
}
static inline constexpr U64 key_piece(piece::Type type, color::Color color, square::Square square) {
return keys_piece[piece::get_index(type, color)][to_underlying(square)];
namespace zobrist {
extern std::array<std::array<U64, 64>, 12> keys_piece;
extern std::array<U64, 64> keys_enpassant;
extern std::array<U64, 16> keys_castle;
const U64 keys_side = Random(C32(1699391443))();
inline void init() {
Random gen1(C64(1804289383));
for (piece::Type type : piece::TypeIter()) {
int piece_index_white = piece::get(type, color::Color::WHITE).index;
int piece_index_black = piece::get(type, color::Color::BLACK).index;
for (int square = 0; square < 64; square++) {
keys_piece[piece_index_white][square] = gen1();
keys_piece[piece_index_black][square] = gen1();
}
}
private:
using key_piece_array = std::array<std::array<U64, 64>, 12>;
static inline constexpr const key_piece_array keys_piece = []() constexpr -> key_piece_array {
key_piece_array key_piece;
Random gen(C64(1804289383));
for (piece::Type type : piece::TypeIter()) {
int piece_index_white = piece::get(type, color::Color::WHITE).index;
int piece_index_black = piece::get(type, color::Color::BLACK).index;
for (int square = 0; square < 64; square++) {
key_piece[piece_index_white][square] = gen();
key_piece[piece_index_black][square] = gen();
}
}
return key_piece;
}();
Random gen2(C32(337245213));
for (int castle = 0; castle < 64; castle++) {
keys_enpassant[castle] = gen2();
}
using key_enpassant_array = std::array<U64, 64>;
static inline constexpr const key_enpassant_array keys_enpassant = []() constexpr -> key_enpassant_array {
key_enpassant_array key_enpassant;
Random gen(C32(337245213));
for (int castle = 0; castle < 64; castle++) {
key_enpassant[castle] = gen();
}
return key_enpassant;
}();
Random gen3(C32(3642040919));
for (int castle = 0; castle < 16; castle++) {
keys_castle[castle] = gen3();
}
};
using key_castle_array = std::array<U64, 16>;
static inline constexpr const key_castle_array keys_castle = []() constexpr -> key_castle_array {
key_castle_array key_castle;
Random gen(C32(3642040919));
for (int castle = 0; castle < 16; castle++) {
key_castle[castle] = gen();
}
return key_castle;
}();
inline U64 hash(const Board &board);
inline constexpr U64 key_side() { return keys_side; }
inline constexpr U64 key_castle(int exp) { return keys_castle[exp]; }
inline constexpr U64 key_enpassant(square::Square square) { return keys_enpassant[to_underlying(square)]; }
inline constexpr U64 key_piece(piece::Type type, color::Color color, square::Square square) {
return keys_piece[piece::get_index(type, color)][to_underlying(square)];
}
static inline constexpr const U64 keys_side = Random(C32(1699391443))();
};
}; // namespace zobrist
#endif

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

@@ -17,13 +17,13 @@

#include "utils.hpp"
enum {
FULL_DEPTH = 4,
REDUCTION_LIMIT = 3,
REDUCTION_MOVE = 2
FULL_DEPTH = 4,
REDUCTION_LIMIT = 3,
REDUCTION_MOVE = 2
};
enum {
WINDOW = 50
WINDOW = 50
};
namespace engine {

@@ -474,6 +474,7 @@ Move search_position(const uci::Settings &settingsr) {

int main() {
attack::init();
zobrist::init();
uci::loop();
return 0;
}

diff --git a/src/move/move.cpp b/src/move/move.cpp

@@ -6,12 +6,12 @@

void Move::piece_remove(Board &board, piece::Type type, color::Color color, square::Square square) const {
board.pop_piece(type, color, square);
board.xor_hash(Zobrist::key_piece(type, color, square));
board.xor_hash(zobrist::key_piece(type, color, square));
}
void Move::piece_set(Board &board, piece::Type type, color::Color color, square::Square square) const {
board.set_piece(type, color, square);
board.xor_hash(Zobrist::key_piece(type, color, square));
board.xor_hash(zobrist::key_piece(type, color, square));
}
void Move::piece_move(Board &board, piece::Type type, color::Color color, square::Square source,

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

@@ -12,10 +12,6 @@ target_link_libraries(perft

PRIVATE utils
)
target_precompile_headers(perft
REUSE_FROM engine
)
set_target_properties(perft PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}

diff --git a/src/perft/perft.cpp b/src/perft/perft.cpp

@@ -153,6 +153,7 @@ int main(int argc, char *argv[]) {

}
attack::init();
zobrist::init();
perft_test(fen, depth, thread_num);
return 0;
}