stellar

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

commit bc10eb327280374ae4808e9b1022e9eb70304e2f
parent d38fae0dac850deebce7355d806bfeac15776fd5
author Dimitrije Dobrota <mail@dimitrijedobrota.com>
date Mon, 11 Mar 2024 15:56:57 +0000

Remove constexpr initialization from zobrist

Diffstat:
M CMakeLists.txt | + -
M src/arena/arena.cpp | +
M src/board/board.cpp | ++++++++ ----
M src/board/board.hpp | ++++++++++++ -----------
M src/board/zobrist.hpp | +++++++++++++++++++++++++++++++++++ -----------------------------------------------
M src/engine/engine.cpp | +++++ ----
M src/move/move.cpp | ++ --
M src/perft/CMakeLists.txt | ----
M src/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; }