stellar

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

commit edfb2f6999e4cc1e8215e10736850b48a12d424b
parent 8bfcf04517460ec1e051df56703b6881d64f279c
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Wed, 13 Mar 2024 21:06:40 +0000

Merge pawn attacks, better attack dispatch

Diffstat:
MCMakeLists.txt | 2+-
Msrc/attack/CMakeLists.txt | 1+
Msrc/attack/attack.hpp | 21++++++++++++++++++---
Msrc/attack/king.hpp | 2+-
Msrc/attack/knight.hpp | 2+-
Asrc/attack/pawn.hpp | 48++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/attack/pawnb.hpp | 37-------------------------------------
Dsrc/attack/pawnw.hpp | 37-------------------------------------
Msrc/board/board.hpp | 4+++-
Msrc/piece/piece.hpp | 35+++++++++++++----------------------
10 files changed, 86 insertions(+), 103 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) project( Stellar - VERSION 1.3.2 + VERSION 1.3.3 DESCRIPTION "Chess engine written in C++" HOMEPAGE_URL https://git.dimitrijedobrota.com/stellar.git LANGUAGES CXX diff --git a/src/attack/CMakeLists.txt b/src/attack/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(attack attack.cpp bishop.cpp rook.cpp) target_link_libraries(attack PRIVATE bitboard PRIVATE utils + PRIVATE piece ) target_include_directories(attack INTERFACE .) diff --git a/src/attack/attack.hpp b/src/attack/attack.hpp @@ -7,15 +7,30 @@ #include "bishop.hpp" #include "king.hpp" #include "knight.hpp" -#include "pawnb.hpp" -#include "pawnw.hpp" +#include "pawn.hpp" #include "queen.hpp" #include "rook.hpp" +#include "piece.hpp" + namespace attack { void init(void); -using attack_f = U64 (*)(const square::Square, U64); + +inline constexpr const U64 attack_pawn(const color::Color color, const square::Square from) { + return attack::pawn::attack(color, from); +} + +inline constexpr const U64 attack(const piece::Type type, const square::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); + default: return 0; + } +} } // namespace attack diff --git a/src/attack/king.hpp b/src/attack/king.hpp @@ -35,7 +35,7 @@ const attack_array attacks = []() -> attack_array { return attacks; }(); -inline constexpr U64 attack(const square::Square square, U64 occupancy) { return attacks[square]; } +inline constexpr U64 attack(const square::Square square) { return attacks[square]; } } // namespace king } // namespace attack diff --git a/src/attack/knight.hpp b/src/attack/knight.hpp @@ -38,7 +38,7 @@ const attack_array attacks = []() -> attack_array { return attacks; }(); -inline constexpr U64 attack(const square::Square square, U64 occupancy) { return attacks[square]; } +inline constexpr U64 attack(const square::Square square) { return attacks[square]; } } // namespace knight } // namespace attack diff --git a/src/attack/pawn.hpp b/src/attack/pawn.hpp @@ -0,0 +1,48 @@ +#ifndef STELLAR_ATTACK_PAWN_H +#define STELLAR_ATTACK_PAWN_H + +#include "bit.hpp" +#include "bitboard.hpp" +#include "color.hpp" +#include "square.hpp" +#include "utils.hpp" + +#include <array> + +namespace attack { +namespace pawn { + +static constexpr U64 mask_white(const square::Square square) { + U64 bitboard = C64(0); + + bit::set(bitboard, square); + return bitboard::noWeOne(bitboard) | bitboard::noEaOne(bitboard); +} + +static constexpr U64 mask_black(const square::Square square) { + U64 bitboard = C64(0); + + bit::set(bitboard, square); + return bitboard::soWeOne(bitboard) | bitboard::soEaOne(bitboard); +} + +typedef std::array<std::array<U64, 64>, 2> attack_array; +const auto attacks = []() { + attack_array attacks; + + for (square::Square square = square::a1; square <= square::h8; ++square) { + attacks[color::WHITE][square] = mask_white(square); + attacks[color::BLACK][square] = mask_black(square); + } + + return attacks; +}(); + +inline constexpr U64 attack(color::Color color, square::Square square) { + return attacks[color][square]; +} + +} // namespace pawn +} // namespace attack + +#endif diff --git a/src/attack/pawnb.hpp b/src/attack/pawnb.hpp @@ -1,37 +0,0 @@ -#ifndef STELLAR_ATTACK_PAWNB_H -#define STELLAR_ATTACK_PAWNB_H - -#include "bit.hpp" -#include "bitboard.hpp" -#include "square.hpp" -#include "utils.hpp" - -#include <array> - -namespace attack { -namespace pawnb { - -static constexpr U64 mask(const square::Square square) { - U64 bitboard = C64(0); - - bit::set(bitboard, square); - return bitboard::soWeOne(bitboard) | bitboard::soEaOne(bitboard); -} - -typedef std::array<U64, 64> attack_array; -const attack_array attacks = []() -> attack_array { - std::array<U64, 64> attacks; - - for (square::Square square = square::a1; square <= square::h8; ++square) { - attacks[square] = mask(square); - } - - return attacks; -}(); - -inline constexpr U64 attack(const square::Square square, U64 occupancy) { return attacks[square]; } - -} // namespace pawnb -}; // namespace attack - -#endif diff --git a/src/attack/pawnw.hpp b/src/attack/pawnw.hpp @@ -1,37 +0,0 @@ -#ifndef STELLAR_ATTACK_PAWNW_H -#define STELLAR_ATTACK_PAWNW_H - -#include "bit.hpp" -#include "bitboard.hpp" -#include "square.hpp" -#include "utils.hpp" - -#include <array> - -namespace attack { -namespace pawnw { - -static constexpr U64 mask(const square::Square square) { - U64 bitboard = C64(0); - - bit::set(bitboard, square); - return bitboard::noWeOne(bitboard) | bitboard::noEaOne(bitboard); -} - -typedef std::array<U64, 64> attack_array; -const attack_array attacks = []() -> attack_array { - std::array<U64, 64> attacks; - - for (square::Square square = square::a1; square <= square::h8; ++square) { - attacks[square] = mask(square); - } - - return attacks; -}(); - -inline constexpr U64 attack(const square::Square square, U64 occupancy) { return attacks[square]; } - -} // namespace pawnw -} // namespace attack - -#endif diff --git a/src/board/board.hpp b/src/board/board.hpp @@ -1,6 +1,7 @@ #ifndef STELLAR_BOARD_H #define STELLAR_BOARD_H +#include "attack.hpp" #include "bit.hpp" #include "color.hpp" #include "piece.hpp" @@ -100,7 +101,8 @@ constexpr U64 Board::get_bitboard_piece(piece::Type piece, color::Color color) c constexpr U64 Board::get_bitboard_piece_attacks(piece::Type type, color::Color color, square::Square from) const { - return piece::get_attack(type, color, from, get_bitboard_occupancy()); + if (type == piece::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 color, diff --git a/src/piece/piece.hpp b/src/piece/piece.hpp @@ -1,7 +1,6 @@ #ifndef STELLAR_PIECE_H #define STELLAR_PIECE_H -#include "attack.hpp" #include "color.hpp" #include "utils.hpp" @@ -26,37 +25,29 @@ struct Piece { const Type type; const color::Color color; const char code; - const attack::attack_f attack; }; inline constexpr const Piece table[2][6] = { // clang-format off { - { .index = 0, .type = PAWN, .color = color::WHITE, .code = 'P', .attack = attack::pawnw::attack }, - { .index = 1, .type = KNIGHT, .color = color::WHITE, .code = 'N', .attack = attack::knight::attack }, - { .index = 2, .type = BISHOP, .color = color::WHITE, .code = 'B', .attack = attack::bishop::attack }, - { .index = 3, .type = ROOK, .color = color::WHITE, .code = 'R', .attack = attack::rook::attack }, - { .index = 4, .type = QUEEN, .color = color::WHITE, .code = 'Q', .attack = attack::queen::attack }, - { .index = 5, .type = KING, .color = color::WHITE, .code = 'K', .attack = attack::king::attack }, + { .index = 0, .type = PAWN, .color = color::WHITE, .code = 'P' }, + { .index = 1, .type = KNIGHT, .color = color::WHITE, .code = 'N' }, + { .index = 2, .type = BISHOP, .color = color::WHITE, .code = 'B' }, + { .index = 3, .type = ROOK, .color = color::WHITE, .code = 'R' }, + { .index = 4, .type = QUEEN, .color = color::WHITE, .code = 'Q' }, + { .index = 5, .type = KING, .color = color::WHITE, .code = 'K' }, }, { - { .index = 6, .type = PAWN, .color = color::BLACK, .code = 'p', .attack = attack::pawnb::attack }, - { .index = 7, .type = KNIGHT, .color = color::BLACK, .code = 'n', .attack = attack::knight::attack }, - { .index = 8, .type = BISHOP, .color = color::BLACK, .code = 'b', .attack = attack::bishop::attack }, - { .index = 9, .type = ROOK, .color = color::BLACK, .code = 'r', .attack = attack::rook::attack }, - {.index = 10, .type = QUEEN, .color = color::BLACK, .code = 'q', .attack = attack::queen::attack }, - {.index = 11, .type = KING, .color = color::BLACK, .code = 'k', .attack = attack::king::attack }, + { .index = 6, .type = PAWN, .color = color::BLACK, .code = 'p' }, + { .index = 7, .type = KNIGHT, .color = color::BLACK, .code = 'n' }, + { .index = 8, .type = BISHOP, .color = color::BLACK, .code = 'b' }, + { .index = 9, .type = ROOK, .color = color::BLACK, .code = 'r' }, + {.index = 10, .type = QUEEN, .color = color::BLACK, .code = 'q' }, + {.index = 11, .type = KING, .color = color::BLACK, .code = 'k' }, }, // clang-format on }; -inline constexpr const Piece &get(const Type type, const color::Color color) { - return table[static_cast<uint8_t>(color)][static_cast<uint8_t>(type)]; -} - -inline constexpr const U64 get_attack(const Type type, const color::Color color, const square::Square from, - const U64 occupancy) { - return get(type, color).attack(from, occupancy); -} +inline constexpr const Piece &get(const Type type, const color::Color color) { return table[color][type]; } inline constexpr const char get_code(const Type type, const color::Color color = color::BLACK) { return get(type, color).code;