stellar

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

commit 8bfcd0ddad32537cc686a87dc8200626e7be81d5
parent 9f2c299a72ac90aa9d2a927666375cc5b6d527b3
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Wed, 13 Mar 2024 21:48:55 +0000

Move Type enum to utils

Diffstat:
MCMakeLists.txt | 2+-
Msrc/arena/game.cpp | 10+++++-----
Msrc/attack/attack.hpp | 12++++++------
Msrc/bitboard/bitboard.cpp | 11-----------
Msrc/bitboard/bitboard.hpp | 3---
Msrc/board/board.hpp | 60++++++++++++++++++++++++++++--------------------------------
Msrc/board/zobrist.hpp | 4++--
Msrc/engine/engine.cpp | 14+++++++-------
Msrc/engine/evaluate.cpp | 9+--------
Msrc/engine/score.hpp | 6++----
Msrc/move/move.cpp | 14+++++++-------
Msrc/move/move.hpp | 8++++----
Msrc/move/movelist.cpp | 4++--
Msrc/piece/piece.hpp | 12------------
Msrc/utils/utils.hpp | 14++++++++++++++
15 files changed, 79 insertions(+), 104 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) project( Stellar - VERSION 1.3.4 + VERSION 1.3.5 DESCRIPTION "Chess engine written in C++" HOMEPAGE_URL https://git.dimitrijedobrota.com/stellar.git LANGUAGES CXX diff --git a/src/arena/game.cpp b/src/arena/game.cpp @@ -35,11 +35,11 @@ const std::string Game::to_san(const Board &board, const Move move) { if (move.is_castle_king()) return "O-O"; if (move.is_castle_queen()) return "O-O-O"; - const piece::Type piece = board.get_square_piece_type(move.source()); - const piece::Type target = board.get_square_piece_type(move.target()); + const Type piece = board.get_square_piece_type(move.source()); + const Type target = board.get_square_piece_type(move.target()); std::string res; - if (piece != piece::PAWN) { + if (piece != PAWN) { U64 potential = board.get_bitboard_square_land(move.target(), piece, board.get_side()); if (bit::count(potential) > 1) { @@ -60,10 +60,10 @@ const std::string Game::to_san(const Board &board, const Move move) { } res += piece::get_code(piece, WHITE); - if (target != piece::NONE) res += "x"; + if (target != Type::NONE) res += "x"; res += to_coordinates(move.target()); } else { - if (target != piece::NONE) res += std::format("{}x", to_coordinates(move.source())[0]); + if (target != Type::NONE) res += std::format("{}x", to_coordinates(move.source())[0]); res += to_coordinates(move.target()); if (move.is_promote()) res += piece::get_code(move.promoted(), WHITE); if (move.is_enpassant()) res += " e.p."; diff --git a/src/attack/attack.hpp b/src/attack/attack.hpp @@ -20,13 +20,13 @@ inline constexpr const U64 attack_pawn(const Color color, const Square from) { return attack::pawn::attack(color, from); } -inline constexpr const U64 attack(const piece::Type type, const Square from, const U64 occupancy) { +inline constexpr const U64 attack(const Type type, const Square from, const U64 occupancy) { switch (type) { - case piece::QUEEN: return attack::queen::attack(from, occupancy); - case piece::ROOK: return attack::rook::attack(from, occupancy); - case piece::BISHOP: return attack::bishop::attack(from, occupancy); - case piece::KING: return attack::king::attack(from); - case piece::KNIGHT: return attack::knight::attack(from); + case QUEEN: return attack::queen::attack(from, occupancy); + case ROOK: return attack::rook::attack(from, occupancy); + case BISHOP: return attack::bishop::attack(from, occupancy); + case KING: return attack::king::attack(from); + case KNIGHT: return attack::knight::attack(from); default: return 0; } } diff --git a/src/bitboard/bitboard.cpp b/src/bitboard/bitboard.cpp @@ -6,17 +6,6 @@ namespace bitboard { -/* -void init() { -for (Square s1 = Square::a1; s1 <= Square::h8; ++s1) { - for (Square s2 = Square::a1; s2 <= Square::h8; ++s2) { - line[s1][s2] |= - (piece::get_attack(piece::BISHOP, s1, 0) & piece::get_attack(piece::BISHOP, s2, 0)) | s1 | s2; - } -} -} -*/ - void print(U64 bitboard) { for (int rank = 0; rank < 8; rank++) { for (int file = 0; file < 8; file++) { diff --git a/src/bitboard/bitboard.hpp b/src/bitboard/bitboard.hpp @@ -5,7 +5,6 @@ namespace bitboard { -void init(void); void print(U64 bitboard); inline constexpr const U64 notAFile = C64(0xfefefefefefefefe); @@ -21,8 +20,6 @@ inline constexpr U64 soWeOne(U64 b) { return (b & notAFile) >> 9; } inline constexpr U64 noEaOne(U64 b) { return (b & notHFile) << 9; } inline constexpr U64 noWeOne(U64 b) { return (b & notAFile) << 7; } -extern U64 line[Square::no_sq][Square::no_sq]; - } // namespace bitboard #endif diff --git a/src/board/board.hpp b/src/board/board.hpp @@ -36,18 +36,15 @@ class Board { [[nodiscard]] inline constexpr U64 get_bitboard_color(Color side) const; [[nodiscard]] inline constexpr U64 get_bitboard_occupancy() const; - [[nodiscard]] inline constexpr U64 get_bitboard_piece(piece::Type piece) const; - [[nodiscard]] inline constexpr U64 get_bitboard_piece(piece::Type piece, Color color) const; + [[nodiscard]] inline constexpr U64 get_bitboard_piece(Type piece) const; + [[nodiscard]] inline constexpr U64 get_bitboard_piece(Type piece, Color color) const; - [[nodiscard]] inline constexpr U64 get_bitboard_piece_attacks(piece::Type piece, Color color, - Square from) const; - [[nodiscard]] inline constexpr U64 get_bitboard_piece_moves(piece::Type piece, Color color, - Square from) const; - [[nodiscard]] inline constexpr U64 get_bitboard_square_land(Square land, piece::Type piece, - Color side) const; + [[nodiscard]] inline constexpr U64 get_bitboard_piece_attacks(Type piece, Color color, Square from) const; + [[nodiscard]] inline constexpr U64 get_bitboard_piece_moves(Type piece, Color color, Square from) const; + [[nodiscard]] inline constexpr U64 get_bitboard_square_land(Square land, Type piece, Color side) const; [[nodiscard]] inline constexpr Color get_square_piece_color(Square square) const; - [[nodiscard]] inline constexpr piece::Type get_square_piece_type(Square square) const; + [[nodiscard]] inline constexpr Type get_square_piece_type(Square square) const; [[nodiscard]] inline constexpr const piece::Piece *get_square_piece(Square square) const; /* Setters */ @@ -60,17 +57,17 @@ class Board { inline constexpr void pop_bitboard_color(Color color, Square square); inline constexpr void set_bitboard_color(Color color, Square square); - inline constexpr void pop_bitboard_piece(piece::Type type, Square square); - inline constexpr void set_bitboard_piece(piece::Type type, Square square); + inline constexpr void pop_bitboard_piece(Type type, Square square); + inline constexpr void set_bitboard_piece(Type type, Square square); - inline constexpr void pop_piece(piece::Type type, Color side, Square square); - inline constexpr void set_piece(piece::Type type, Color side, Square square); + inline constexpr void pop_piece(Type type, Color side, Square square); + inline constexpr void set_piece(Type type, Color side, Square square); /* Queries */ [[nodiscard]] inline constexpr bool is_square_attacked(Square square, Color side) const; [[nodiscard]] inline constexpr bool is_square_occupied(Square square) const; - [[nodiscard]] inline constexpr bool is_piece_attack_square(piece::Type type, Color color, Square source, + [[nodiscard]] inline constexpr bool is_piece_attack_square(Type type, Color color, Square source, Square target) const; [[nodiscard]] inline constexpr bool is_check() const; @@ -90,22 +87,22 @@ constexpr Square Board::get_enpassant() const { return enpassant; } constexpr U64 Board::get_bitboard_color(Color side) const { return colors[side]; } constexpr U64 Board::get_bitboard_occupancy() const { return colors[WHITE] | colors[BLACK]; } -constexpr U64 Board::get_bitboard_piece(piece::Type piece) const { return pieces[piece]; } +constexpr U64 Board::get_bitboard_piece(Type piece) const { return pieces[piece]; } -constexpr U64 Board::get_bitboard_piece(piece::Type piece, Color color) const { +constexpr U64 Board::get_bitboard_piece(Type piece, Color color) const { return pieces[piece] & colors[color]; } -constexpr U64 Board::get_bitboard_piece_attacks(piece::Type type, Color color, Square from) const { - if (type == piece::PAWN) return attack::attack_pawn(color, from); +constexpr U64 Board::get_bitboard_piece_attacks(Type type, Color color, Square from) const { + if (type == PAWN) return attack::attack_pawn(color, from); return attack::attack(type, from, get_bitboard_occupancy()); } -constexpr U64 Board::get_bitboard_piece_moves(piece::Type type, Color color, Square square) const { +constexpr U64 Board::get_bitboard_piece_moves(Type type, Color color, Square square) const { return get_bitboard_piece_attacks(type, color, square) & ~get_bitboard_color(color); } -constexpr U64 Board::get_bitboard_square_land(Square land, piece::Type piece, Color side) const { +constexpr U64 Board::get_bitboard_square_land(Square land, Type piece, Color side) const { return get_bitboard_piece_attacks(piece, other(side), land) & get_bitboard_piece(piece, side); } @@ -116,11 +113,11 @@ constexpr Color Board::get_square_piece_color(Square square) const { throw std::exception(); } -constexpr piece::Type Board::get_square_piece_type(Square square) const { - for (piece::Type type = piece::PAWN; type <= piece::KING; ++type) { +constexpr Type Board::get_square_piece_type(Square square) const { + for (Type type = PAWN; type <= KING; ++type) { if (bit::get(pieces[type], square)) return type; } - return piece::Type::NONE; + return Type::NONE; } constexpr const piece::Piece *Board::get_square_piece(Square square) const { @@ -153,15 +150,15 @@ constexpr void Board::set_enpassant(Square target) { constexpr void Board::pop_bitboard_color(Color color, Square square) { bit::pop(colors[color], square); } constexpr void Board::set_bitboard_color(Color color, Square square) { bit::set(colors[color], square); } -constexpr void Board::pop_bitboard_piece(piece::Type type, Square square) { bit::pop(pieces[type], square); } -constexpr void Board::set_bitboard_piece(piece::Type type, Square square) { bit::set(pieces[type], square); } +constexpr void Board::pop_bitboard_piece(Type type, Square square) { bit::pop(pieces[type], square); } +constexpr void Board::set_bitboard_piece(Type type, Square square) { bit::set(pieces[type], square); } -constexpr void Board::pop_piece(piece::Type type, Color side, Square square) { +constexpr void Board::pop_piece(Type type, Color side, Square square) { pop_bitboard_color(side, square); pop_bitboard_piece(type, square); } -constexpr void Board::set_piece(piece::Type type, Color side, Square square) { +constexpr void Board::set_piece(Type type, Color side, Square square) { set_bitboard_color(side, square); set_bitboard_piece(type, square); } @@ -175,7 +172,7 @@ constexpr bool Board::is_square_occupied(Square square) const { constexpr bool Board::is_square_attacked(Square square, Color side) const { const Color side_other = other(side); - for (piece::Type type = piece::PAWN; type <= piece::KING; ++type) { + for (Type type = PAWN; type <= KING; ++type) { if (get_bitboard_piece_attacks(type, side_other, square) & get_bitboard_piece(type, side)) { return true; } @@ -184,13 +181,12 @@ constexpr bool Board::is_square_attacked(Square square, Color side) const { return false; } -constexpr bool Board::is_piece_attack_square(piece::Type type, Color color, Square source, - Square target) const { +constexpr bool Board::is_piece_attack_square(Type type, Color color, Square source, Square target) const { return get_bitboard_piece_attacks(type, color, source) & (C64(1) << target); } constexpr bool Board::is_check() const { - U64 king = pieces[piece::Type::KING] & colors[side]; + U64 king = pieces[Type::KING] & colors[side]; Color side_other = (side == BLACK) ? WHITE : BLACK; auto square = static_cast<Square>(bit::lsb_index(king)); return is_square_attacked(square, side_other); @@ -200,7 +196,7 @@ U64 zobrist::hash(const Board &board) { U64 key_final = C64(0); uint8_t square = 0; - for (piece::Type type = piece::PAWN; type <= piece::KING; ++type) { + for (Type type = PAWN; type <= KING; ++type) { int piece_white_index = piece::get_index(type, WHITE); U64 bitboard_white = board.get_bitboard_piece(type, WHITE); bitboard_for_each_bit(square, bitboard_white) { key_final ^= keys_piece[piece_white_index][square]; } diff --git a/src/board/zobrist.hpp b/src/board/zobrist.hpp @@ -19,7 +19,7 @@ const U64 keys_side = Random(C32(1699391443))(); inline void init() { Random gen1(C64(1804289383)); - for (piece::Type type = piece::PAWN; type <= piece::KING; ++type) { + for (Type type = PAWN; type <= KING; ++type) { int piece_index_white = piece::get(type, Color::WHITE).index; int piece_index_black = piece::get(type, Color::BLACK).index; for (int square = 0; square < 64; square++) { @@ -43,7 +43,7 @@ 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) { return keys_enpassant[square]; } -inline constexpr U64 key_piece(piece::Type type, Color color, Square square) { +inline constexpr U64 key_piece(Type type, Color color, Square square) { return keys_piece[piece::get_index(type, color)][square]; } diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp @@ -132,9 +132,9 @@ U32 inline move_score(const Move move) { // clang-format on }; - const piece::Type type = board.get_square_piece_type(move.source()); + const Type type = board.get_square_piece_type(move.source()); if (move.is_capture()) { - const piece::Type captured = board.get_square_piece_type(move.target()); + const Type captured = board.get_square_piece_type(move.target()); return capture[type][captured] + 10000; } if (killer[0][ply] == move) return 9000; @@ -279,7 +279,7 @@ int16_t negamax(int16_t alpha, int16_t beta, uint8_t depth, bool null) { // if (ply > MAX_PLY - 1) return evaluate::score_position(board); if (!pv_node && !isCheck) { - static constexpr const U32 score_pawn = score::get(piece::Type::PAWN); + static constexpr const U32 score_pawn = score::get(PAWN); int16_t staticEval = evaluate::score_position(board); // evaluation pruning @@ -316,9 +316,9 @@ int16_t negamax(int16_t alpha, int16_t beta, uint8_t depth, bool null) { // futility pruning condition static constexpr const int16_t margin[] = { 0, - score::get(piece::Type::PAWN), - score::get(piece::Type::KNIGHT), - score::get(piece::Type::ROOK), + score::get(PAWN), + score::get(KNIGHT), + score::get(ROOK), }; if (depth < 4 && abs(alpha) < MATE_SCORE && staticEval + margin[depth] <= alpha) futility = 1; } @@ -367,7 +367,7 @@ int16_t negamax(int16_t alpha, int16_t beta, uint8_t depth, bool null) { if (settings->stopped) return 0; if (score > alpha) { if (!move.is_capture()) { - const piece::Type piece = board.get_square_piece_type(move.source()); + const Type piece = board.get_square_piece_type(move.source()); history[piece::get_index(piece, board.get_side())][move.target()] += depth; } diff --git a/src/engine/evaluate.cpp b/src/engine/evaluate.cpp @@ -63,20 +63,13 @@ inline constexpr const mask_passed_array mask_passed = []() constexpr -> mask_pa return mask_passed; }(); -using piece::Type::BISHOP; -using piece::Type::KING; -using piece::Type::KNIGHT; -using piece::Type::PAWN; -using piece::Type::QUEEN; -using piece::Type::ROOK; - using score::Phase::ENDGAME; using score::Phase::OPENING; uint16_t score_game_phase(const Board &board) { int16_t total = 0; for (int type_i = KNIGHT; type_i < KING; type_i++) { - const piece::Type type = static_cast<piece::Type>(type_i); + const Type type = static_cast<Type>(type_i); total += bit::count(board.get_bitboard_piece(type)) * score::get(type); } return total; diff --git a/src/engine/score.hpp b/src/engine/score.hpp @@ -146,11 +146,9 @@ enum Phase { ENDGAME, }; -inline constexpr int16_t get(const piece::Type piece, const Phase phase = OPENING) { - return value[phase][piece]; -} +inline constexpr int16_t get(const Type piece, const Phase phase = OPENING) { return value[phase][piece]; } -inline constexpr int16_t get(piece::Type piece, Color color, Square square, Phase phase = ENDGAME) { +inline constexpr int16_t get(Type piece, Color color, Square square, Phase phase = ENDGAME) { if (color != WHITE) square = get_mirror(square); return position[phase][piece][square]; } diff --git a/src/move/move.cpp b/src/move/move.cpp @@ -5,23 +5,23 @@ #include <algorithm> #include <iomanip> -void Move::piece_remove(Board &board, piece::Type type, Color color, Square square) const { +void Move::piece_remove(Board &board, Type type, Color color, Square square) const { board.pop_piece(type, color, square); board.xor_hash(zobrist::key_piece(type, color, square)); } -void Move::piece_set(Board &board, piece::Type type, Color color, Square square) const { +void Move::piece_set(Board &board, Type type, Color color, Square square) const { board.set_piece(type, color, square); board.xor_hash(zobrist::key_piece(type, color, square)); } -void Move::piece_move(Board &board, piece::Type type, Color color, Square source, Square target) const { +void Move::piece_move(Board &board, Type type, Color color, Square source, Square target) const { piece_remove(board, type, color, source); piece_set(board, type, color, target); } -using piece::Type::PAWN; -using piece::Type::ROOK; +using Type::PAWN; +using Type::ROOK; bool Move::make(Board &board) const { static constexpr const int castling_rights[64] = { @@ -42,7 +42,7 @@ bool Move::make(Board &board) const { const auto ntarget = static_cast<Square>(this->target() + (color == Color::WHITE ? -8 : +8)); - const piece::Type piece = board.get_square_piece_type(source); + const Type piece = board.get_square_piece_type(source); if (!is_capture()) { if (is_promote()) { @@ -52,7 +52,7 @@ bool Move::make(Board &board) const { piece_move(board, piece, color, source, target); } } else { - const piece::Type captured = board.get_square_piece_type(target); + const Type captured = board.get_square_piece_type(target); if (is_enpassant()) { piece_move(board, piece, color, source, target); piece_remove(board, PAWN, colorOther, ntarget); diff --git a/src/move/move.hpp b/src/move/move.hpp @@ -50,7 +50,7 @@ struct Move { [[nodiscard]] bool is_enpassant() const { return flags_i == ENPASSANT; } - [[nodiscard]] const piece::Type promoted() const { return static_cast<piece::Type>((flags_i & 0x3) + 1); } + [[nodiscard]] const Type promoted() const { return static_cast<Type>((flags_i & 0x3) + 1); } bool make(Board &board) const; @@ -59,9 +59,9 @@ struct Move { void print() const; private: - inline void piece_remove(Board &board, piece::Type type, Color color, Square square) const; - inline void piece_set(Board &board, piece::Type type, Color color, Square square) const; - inline void piece_move(Board &board, piece::Type type, Color color, Square source, Square target) const; + inline void piece_remove(Board &board, Type type, Color color, Square square) const; + inline void piece_set(Board &board, Type type, Color color, Square square) const; + inline void piece_move(Board &board, Type type, Color color, Square source, Square target) const; unsigned source_i : 6; unsigned target_i : 6; diff --git a/src/move/movelist.cpp b/src/move/movelist.cpp @@ -10,7 +10,7 @@ ((color == BLACK && source >= Square::a7 && source <= Square::h7) || \ (color == WHITE && source >= Square::a2 && source <= Square::h2)) -using piece::Type::PAWN; +using Type::PAWN; void MoveList::generate(const Board &board, bool attacks_only) { uint8_t src_i = 0, tgt_i = 0; @@ -62,7 +62,7 @@ void MoveList::generate(const Board &board, bool attacks_only) { } // All piece move - for (piece::Type type = piece::KNIGHT; type <= piece::KING; ++type) { + for (Type type = KNIGHT; type <= KING; ++type) { U64 bitboard = board.get_bitboard_piece(type, color); bitboard_for_each_bit(src_i, bitboard) { const auto src = static_cast<Square>(src_i); diff --git a/src/piece/piece.hpp b/src/piece/piece.hpp @@ -8,18 +8,6 @@ namespace piece { -enum Type { - PAWN = 0, - KNIGHT, - BISHOP, - ROOK, - QUEEN, - KING, - NONE = 7, -}; - -ENABLE_INCR_OPERATORS_ON(Type) - struct Piece { const uint8_t index; const Type type; diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp @@ -57,4 +57,18 @@ constexpr uint8_t get_file(const Square square) { return square & 0x07; } constexpr uint8_t get_rank(const Square square) { return square >> 3; } constexpr Square get_mirror(const Square square) { return mirror_array[square]; } +/* piece */ + +enum Type { + PAWN = 0, + KNIGHT, + BISHOP, + ROOK, + QUEEN, + KING, + NONE = 7, +}; + +ENABLE_INCR_OPERATORS_ON(Type) + #endif