stellarUCI 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:M | CMakeLists.txt | | | +- |
M | src/attack/CMakeLists.txt | | | + |
M | src/attack/attack.hpp | | | ++++++++++++++++++--- |
M | src/attack/king.hpp | | | +- |
M | src/attack/knight.hpp | | | +- |
A | src/attack/pawn.hpp | | | ++++++++++++++++++++++++++++++++++++++++++++++++ |
D | src/attack/pawnb.hpp | | | ------------------------------------- |
D | src/attack/pawnw.hpp | | | ------------------------------------- |
M | src/board/board.hpp | | | +++- |
M | src/piece/piece.hpp | | | +++++++++++++---------------------- |
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;