stellar

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:
MCMakeLists.txt | 2+-
Msrc/arena/arena.cpp | 1+
Msrc/board/board.cpp | 12++++++++----
Msrc/board/board.hpp | 23++++++++++++-----------
Msrc/board/zobrist.hpp | 81+++++++++++++++++++++++++++++++++----------------------------------------------
Msrc/engine/engine.cpp | 9+++++----
Msrc/move/move.cpp | 4++--
Msrc/perft/CMakeLists.txt | 4----
Msrc/perft/perft.cpp | 1+
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; }