commit 2f3a26c1d985412b453547ebd5c01190e378684e
parent fcde3f48c51361419b4d2f43652dd622e50660b7
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Wed, 13 Mar 2024 19:54:46 +0000
Beter enum handling, get rid of to_underlying()
Diffstat:
25 files changed, 118 insertions(+), 152 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -3,7 +3,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(
Stellar
- VERSION 1.3.0
+ VERSION 1.3.1
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
@@ -84,7 +84,7 @@ std::ostream &operator<<(std::ostream &os, const Game &game) {
os << std::format("\n[White \"{}\"]", game.get_white());
os << std::format("\n[Black \"{}\"]", game.get_black());
os << std::format("\n[Result \"{}-{}\"]", (int)game.is_win_white(), (int)game.is_win_black());
- os << std::format("\n[Termination \"{}\"]", name[to_underlying(game.get_terminate())]);
+ os << std::format("\n[Termination \"{}\"]", name[game.get_terminate()]);
if (game.fen != Game::startPosition) {
os << std::format("\n[SetUp \"1\"]");
os << std::format("\n[FEN \"{}\"]", game.fen);
@@ -97,7 +97,7 @@ std::ostream &operator<<(std::ostream &os, const Game &game) {
const color::Color side = board.get_side();
if (side == color::BLACK) os << std::format("1. ... ");
for (int i = 0; i < game.list.size(); i++) {
- if (i % 2 == to_underlying(side)) os << std::format("{}. ", i / 2 + 1);
+ if (i % 2 == side) os << std::format("{}. ", i / 2 + 1);
os << std::format("{} ", Game::san ? Game::to_san(board, game.list[i]) : (std::string)game.list[i]);
game.list[i].make(board);
}
diff --git a/src/arena/logger.hpp b/src/arena/logger.hpp
@@ -22,7 +22,7 @@ inline void set_level(const Level lvl) { active = lvl; }
inline void log(const std::string &message, const Level lvl = Arena) {
static const std::string name[] = {"crit", "arena", "debug", "info"};
if (lvl > active) return;
- std::cerr << std::format("[ {:>5} ] {}\n", name[to_underlying(lvl)], message);
+ std::cerr << std::format("[ {:>5} ] {}\n", name[lvl], message);
}
inline void error(const char *call) { log(std::format("{}, {}", call, std::strerror(errno)), Critical); }
diff --git a/src/arena/match.cpp b/src/arena/match.cpp
@@ -31,7 +31,7 @@ Game Match::play(Settings swhite, Settings sblack, const std::string fen = Game:
break;
}
- Engine *engine = engines[to_underlying(turn)];
+ Engine *engine = engines[turn];
engine->send(std::format("{} moves {}", position, game.get_moves()));
engine->send(get_go(swhite, sblack, turn));
diff --git a/src/attack/bishop.cpp b/src/attack/bishop.cpp
@@ -45,49 +45,44 @@ inline constexpr const bitboard::direction_f dir[4] = {bitboard::noEaOne, bitboa
bitboard::soEaOne, bitboard::soWeOne};
inline constexpr U32 hash(const U64 key, const square::Square square) {
- uint8_t square_i = to_underlying(square);
- return (key * bishop_magic_numbers[square_i]) >> (64 - relevant_bits[square_i]);
+ return (key * bishop_magic_numbers[square]) >> (64 - relevant_bits[square]);
}
inline constexpr U64 mask_fly(const square::Square square, U64 block) {
- uint8_t square_i = to_underlying(square);
- int tr = square_i / 8, tf = square_i % 8;
+ int tr = square / 8, tf = square % 8;
int len[4] = {std::min(7 - tf, 7 - tr), std::min(tf, 7 - tr), std::min(7 - tf, tr), std::min(tf, tr)};
return attack::slider::mask(square, block, dir, len);
}
-std::array<U64, 64> masks = {{0}};
-inline U64 mask(const square::Square square) { return masks[to_underlying(square)]; }
-
+std::array<U64, 64> mask = {{0}};
std::array<std::array<U64, 4098>, 64> attacks = {{{0}}};
void init(void) {
- for (uint8_t square = 0; square < 64; square++) {
+ for (square::Square square = square::a1; square <= square::h8; ++square) {
int tr = square / 8, tf = square % 8;
int len[4] = {std::min(7 - tf, 7 - tr) - 1, std::min(tf, 7 - tr) - 1, std::min(7 - tf, tr) - 1,
std::min(tf, tr) - 1};
- masks[square] = attack::slider::mask(static_cast<square::Square>(square), C64(0), dir, len);
+ mask[square] = attack::slider::mask(square, C64(0), dir, len);
}
- for (uint8_t square = 0; square < 64; square++) {
- square::Square Square = static_cast<square::Square>(square);
- U64 attack_mask = mask(Square);
+ for (square::Square square = square::a1; square <= square::h8; ++square) {
+ U64 attack_mask = mask[square];
uint8_t relevant_bits = bit::count(attack_mask);
U64 occupancy_indices = C64(1) << relevant_bits;
for (U64 idx = 0; idx < occupancy_indices; idx++) {
U64 occupancy = attack::slider::occupancy(idx, relevant_bits, attack_mask);
- U32 magic_index = hash(occupancy, Square);
- attacks[square][magic_index] = mask_fly(Square, occupancy);
+ U32 magic_index = hash(occupancy, square);
+ attacks[square][magic_index] = mask_fly(square, occupancy);
}
}
}
U64 attack(const square::Square square, U64 occupancy) {
- occupancy &= mask(square);
+ occupancy &= mask[square];
occupancy = hash(occupancy, square);
- return attacks[to_underlying(square)][occupancy];
+ return attacks[square][occupancy];
}
} // namespace bishop
diff --git a/src/attack/king.hpp b/src/attack/king.hpp
@@ -14,7 +14,7 @@ namespace king {
static constexpr U64 mask(const square::Square square) {
U64 bitboard = C64(0), attacks = C64(0);
- bit::set(bitboard, to_underlying(square));
+ bit::set(bitboard, square);
attacks |= bitboard::westOne(bitboard) | bitboard::eastOne(bitboard);
attacks |= bitboard::soutOne(bitboard) | bitboard::nortOne(bitboard);
attacks |= bitboard::soutOne(bitboard) | bitboard::nortOne(bitboard);
@@ -27,14 +27,15 @@ static constexpr U64 mask(const square::Square square) {
typedef std::array<U64, 64> attack_array;
const attack_array attacks = []() -> attack_array {
std::array<U64, 64> attacks;
- for (uint8_t square = 0; square < 64; square++)
- attacks[square] = mask(static_cast<square::Square>(square));
+
+ 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[to_underlying(square)];
-}
+inline constexpr U64 attack(const square::Square square, U64 occupancy) { return attacks[square]; }
} // namespace king
} // namespace attack
diff --git a/src/attack/knight.hpp b/src/attack/knight.hpp
@@ -14,7 +14,7 @@ namespace knight {
static constexpr U64 mask(const square::Square square) {
U64 bitboard = C64(0), attacks = C64(0), tmp;
- bit::set(bitboard, to_underlying(square));
+ bit::set(bitboard, square);
tmp = bitboard::nortOne(bitboard::nortOne(bitboard));
attacks |= bitboard::westOne(tmp) | bitboard::eastOne(tmp);
tmp = bitboard::soutOne(bitboard::soutOne(bitboard));
@@ -30,14 +30,15 @@ static constexpr U64 mask(const square::Square square) {
typedef std::array<U64, 64> attack_array;
const attack_array attacks = []() -> attack_array {
std::array<U64, 64> attacks;
- for (uint8_t square = 0; square < 64; square++)
- attacks[square] = mask(static_cast<square::Square>(square));
+
+ 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[to_underlying(square)];
-}
+inline constexpr U64 attack(const square::Square square, U64 occupancy) { return attacks[square]; }
} // namespace knight
} // namespace attack
diff --git a/src/attack/pawnb.hpp b/src/attack/pawnb.hpp
@@ -14,21 +14,22 @@ namespace pawnb {
static constexpr U64 mask(const square::Square square) {
U64 bitboard = C64(0);
- bit::set(bitboard, to_underlying(square));
+ 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 (uint8_t square = 0; square < 64; square++)
- attacks[square] = mask(static_cast<square::Square>(square));
+
+ 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[to_underlying(square)];
-}
+inline constexpr U64 attack(const square::Square square, U64 occupancy) { return attacks[square]; }
} // namespace pawnb
}; // namespace attack
diff --git a/src/attack/pawnw.hpp b/src/attack/pawnw.hpp
@@ -14,21 +14,22 @@ namespace pawnw {
static constexpr U64 mask(const square::Square square) {
U64 bitboard = C64(0);
- bit::set(bitboard, to_underlying(square));
+ 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 (uint8_t square = 0; square < 64; square++)
- attacks[square] = mask(static_cast<square::Square>(square));
+
+ 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[to_underlying(square)];
-}
+inline constexpr U64 attack(const square::Square square, U64 occupancy) { return attacks[square]; }
} // namespace pawnw
} // namespace attack
diff --git a/src/attack/rook.cpp b/src/attack/rook.cpp
@@ -44,49 +44,44 @@ inline constexpr const bitboard::direction_f dir[4] = {bitboard::westOne, bitboa
bitboard::eastOne, bitboard::nortOne};
inline constexpr U32 hash(const U64 key, const square::Square square) {
- uint8_t square_i = to_underlying(square);
- return (key * rook_magic_numbers[square_i]) >> (64 - relevant_bits[square_i]);
+ return (key * rook_magic_numbers[square]) >> (64 - relevant_bits[square]);
}
inline constexpr U64 mask_fly(const square::Square square, U64 block) {
- uint8_t square_i = to_underlying(square);
- int tr = square_i / 8, tf = square_i % 8;
+ int tr = square / 8, tf = square % 8;
int len[4] = {tf, tr, 7 - tf, 7 - tr};
return attack::slider::mask(square, block, dir, len);
}
-std::array<U64, 64> masks = {{0}};
-U64 mask(const square::Square square) { return masks[to_underlying(square)]; }
-
+std::array<U64, 64> mask = {{0}};
std::array<std::array<U64, 4096>, 64> attacks = {{{0}}};
void init(void) {
- for (uint8_t square = 0; square < 64; square++) {
+ for (square::Square square = square::a1; square <= square::h8; ++square) {
const int tr = square / 8, tf = square % 8;
const int len[4] = {tf - 1, tr - 1, 6 - tf, 6 - tr};
- masks[square] = attack::slider::mask(static_cast<square::Square>(square), C64(0), dir, len);
+ mask[square] = attack::slider::mask(square, C64(0), dir, len);
}
- for (uint8_t square = 0; square < 64; square++) {
- square::Square Square = static_cast<square::Square>(square);
- U64 attack_mask = mask(Square);
+ for (square::Square square = square::a1; square <= square::h8; ++square) {
+ U64 attack_mask = mask[square];
uint8_t relevant_bits = bit::count(attack_mask);
U64 occupancy_indices = C64(1) << relevant_bits;
for (U64 idx = 0; idx < occupancy_indices; idx++) {
U64 occupancy = attack::slider::occupancy(idx, relevant_bits, attack_mask);
- U32 magic_index = hash(occupancy, Square);
- attacks[square][magic_index] = mask_fly(Square, occupancy);
+ U32 magic_index = hash(occupancy, square);
+ attacks[square][magic_index] = mask_fly(square, occupancy);
}
}
}
U64 attack(const square::Square square, U64 occupancy) {
- occupancy &= mask(square);
+ occupancy &= mask[square];
occupancy = hash(occupancy, square);
- return attacks[to_underlying(square)][occupancy];
+ return attacks[square][occupancy];
}
} // namespace rook
diff --git a/src/attack/slider.hpp b/src/attack/slider.hpp
@@ -25,7 +25,7 @@ inline constexpr U64 occupancy(U64 index, uint8_t bits_in_mask, U64 attack_mask)
inline constexpr U64 mask(const square::Square square, U64 block, const bitboard::direction_f dir[4],
const int len[4]) {
U64 bitboard = C64(0), attacks = C64(0);
- bit::set(bitboard, to_underlying(square));
+ bit::set(bitboard, square);
for (int i = 0; i < 4; i++) {
U64 tmp = bitboard;
for (int j = 0; j < len[i]; j++) {
diff --git a/src/board/board.cpp b/src/board/board.cpp
@@ -39,13 +39,13 @@ 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 |= Castle::WK;
else if (fen[i] == 'Q')
- castle |= to_underlying(Castle::WQ);
+ castle |= Castle::WQ;
else if (fen[i] == 'k')
- castle |= to_underlying(Castle::BK);
+ castle |= Castle::BK;
else if (fen[i] == 'q')
- castle |= to_underlying(Castle::BQ);
+ castle |= Castle::BQ;
else if (fen[i] == '-') {
i++;
break;
@@ -73,10 +73,10 @@ std::ostream &operator<<(std::ostream &os, const Board &board) {
os << ((board.side == color::WHITE) ? "white" : "black") << "\n";
os << "Enpassant: " << square::to_coordinates(board.enpassant) << "\n";
os << " Castle:";
- os << ((board.castle & to_underlying(Board::Castle::WK)) ? 'K' : '-');
- os << ((board.castle & to_underlying(Board::Castle::WQ)) ? 'Q' : '-');
- os << ((board.castle & to_underlying(Board::Castle::BK)) ? 'k' : '-');
- os << ((board.castle & to_underlying(Board::Castle::BQ)) ? 'q' : '-');
+ os << ((board.castle & Board::Castle::WK) ? 'K' : '-');
+ os << ((board.castle & Board::Castle::WQ) ? 'Q' : '-');
+ os << ((board.castle & Board::Castle::BK) ? 'k' : '-');
+ os << ((board.castle & Board::Castle::BQ) ? 'q' : '-');
os << "\n Hash:" << board.hash << "\n\n";
return os;
diff --git a/src/board/board.hpp b/src/board/board.hpp
@@ -15,7 +15,7 @@
class Board {
public:
- enum class Castle : uint8_t {
+ enum Castle : uint8_t {
WK = 1,
WQ = 2,
BK = 4,
@@ -90,16 +90,12 @@ constexpr U64 Board::get_hash() const { return hash; }
constexpr uint8_t Board::get_castle() const { return castle; }
constexpr square::Square Board::get_enpassant() const { return enpassant; }
-constexpr U64 Board::get_bitboard_color(color::Color side) const { return colors[to_underlying(side)]; }
-
-constexpr U64 Board::get_bitboard_occupancy() const {
- return colors[to_underlying(color::WHITE)] | colors[to_underlying(color::BLACK)];
-}
-
-constexpr U64 Board::get_bitboard_piece(piece::Type piece) const { return pieces[to_underlying(piece)]; }
+constexpr U64 Board::get_bitboard_color(color::Color side) const { return colors[side]; }
+constexpr U64 Board::get_bitboard_occupancy() const { return colors[color::WHITE] | colors[color::BLACK]; }
+constexpr U64 Board::get_bitboard_piece(piece::Type piece) const { return pieces[piece]; }
constexpr U64 Board::get_bitboard_piece(piece::Type piece, color::Color color) const {
- return pieces[to_underlying(piece)] & colors[to_underlying(color)];
+ return pieces[piece] & colors[color];
}
constexpr U64 Board::get_bitboard_piece_attacks(piece::Type type, color::Color color,
@@ -119,14 +115,14 @@ constexpr U64 Board::get_bitboard_square_land(square::Square land, piece::Type p
}
constexpr color::Color Board::get_square_piece_color(square::Square square) const {
- if (bit::get(colors[to_underlying(color::WHITE)], to_underlying(square))) return color::WHITE;
- if (bit::get(colors[to_underlying(color::BLACK)], to_underlying(square))) return color::BLACK;
+ if (bit::get(colors[color::WHITE], square)) return color::WHITE;
+ if (bit::get(colors[color::BLACK], square)) return color::BLACK;
throw std::exception();
}
constexpr piece::Type Board::get_square_piece_type(square::Square square) const {
- for (piece::Type type : piece::TypeIter()) {
- if (bit::get(pieces[to_underlying(type)], to_underlying(square))) return type;
+ for (piece::Type type = piece::PAWN; type <= piece::KING; ++type) {
+ if (bit::get(pieces[type], square)) return type;
}
return piece::Type::NONE;
}
@@ -160,19 +156,19 @@ constexpr void Board::set_enpassant(square::Square target) {
}
constexpr void Board::pop_bitboard_color(color::Color color, square::Square square) {
- bit::pop(colors[to_underlying(color)], to_underlying(square));
+ bit::pop(colors[color], square);
}
constexpr void Board::set_bitboard_color(color::Color color, square::Square square) {
- bit::set(colors[to_underlying(color)], to_underlying(square));
+ bit::set(colors[color], square);
}
constexpr void Board::pop_bitboard_piece(piece::Type type, square::Square square) {
- bit::pop(pieces[to_underlying(type)], to_underlying(square));
+ bit::pop(pieces[type], square);
}
constexpr void Board::set_bitboard_piece(piece::Type type, square::Square square) {
- bit::set(pieces[to_underlying(type)], to_underlying(square));
+ bit::set(pieces[type], square);
}
constexpr void Board::pop_piece(piece::Type type, color::Color side, square::Square square) {
@@ -188,13 +184,13 @@ constexpr void Board::set_piece(piece::Type type, color::Color side, square::Squ
/* Queries */
constexpr bool Board::is_square_occupied(square::Square square) const {
- return bit::get(get_bitboard_occupancy(), to_underlying(square));
+ return bit::get(get_bitboard_occupancy(), square);
}
constexpr bool Board::is_square_attacked(square::Square square, color::Color side) const {
const color::Color side_other = color::other(side);
- for (piece::Type type : piece::TypeIter()) {
+ for (piece::Type type = piece::PAWN; type <= piece::KING; ++type) {
if (get_bitboard_piece_attacks(type, side_other, square) & get_bitboard_piece(type, side)) {
return true;
}
@@ -205,11 +201,11 @@ constexpr bool Board::is_square_attacked(square::Square square, color::Color sid
constexpr bool Board::is_piece_attack_square(piece::Type type, color::Color color, square::Square source,
square::Square target) const {
- return get_bitboard_piece_attacks(type, color, source) & (C64(1) << to_underlying(target));
+ return get_bitboard_piece_attacks(type, color, source) & (C64(1) << target);
}
constexpr bool Board::is_check() const {
- U64 king = pieces[to_underlying(piece::Type::KING)] & colors[to_underlying(side)];
+ U64 king = pieces[piece::Type::KING] & colors[side];
color::Color side_other = (side == color::BLACK) ? color::WHITE : color::BLACK;
auto square = static_cast<square::Square>(bit::lsb_index(king));
return is_square_attacked(square, side_other);
@@ -219,7 +215,7 @@ U64 zobrist::hash(const Board &board) {
U64 key_final = C64(0);
uint8_t square = 0;
- for (piece::Type type : piece::TypeIter()) {
+ for (piece::Type type = piece::PAWN; type <= piece::KING; ++type) {
int piece_white_index = piece::get_index(type, color::WHITE);
U64 bitboard_white = board.get_bitboard_piece(type, color::WHITE);
bitboard_for_each_bit(square, bitboard_white) { key_final ^= keys_piece[piece_white_index][square]; }
@@ -232,8 +228,7 @@ U64 zobrist::hash(const Board &board) {
key_final ^= keys_castle[board.get_castle()];
if (board.get_side() == color::BLACK) key_final ^= keys_side;
- if (board.get_enpassant() != square::Square::no_sq)
- key_final ^= keys_enpassant[to_underlying(board.get_enpassant())];
+ if (board.get_enpassant() != square::Square::no_sq) key_final ^= keys_enpassant[board.get_enpassant()];
return key_final;
}
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::TypeIter()) {
+ for (piece::Type type = piece::PAWN; type <= piece::KING; ++type) {
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++) {
@@ -42,9 +42,9 @@ inline void init() {
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_enpassant(square::Square square) { return keys_enpassant[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)];
+ return keys_piece[piece::get_index(type, color)][square];
}
}; // namespace zobrist
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
@@ -135,11 +135,11 @@ U32 inline move_score(const Move move) {
const piece::Type type = board.get_square_piece_type(move.source());
if (move.is_capture()) {
const piece::Type captured = board.get_square_piece_type(move.target());
- return capture[to_underlying(type)][to_underlying(captured)] + 10000;
+ return capture[type][captured] + 10000;
}
if (killer[0][ply] == move) return 9000;
if (killer[1][ply] == move) return 8000;
- return history[piece::get_index(type, board.get_side())][to_underlying(move.target())];
+ return history[piece::get_index(type, board.get_side())][move.target()];
}
void move_list_sort(MoveList &list, std::vector<int> &score, int crnt) {
@@ -368,7 +368,7 @@ int16_t negamax(int16_t alpha, int16_t beta, uint8_t depth, bool null) {
if (score > alpha) {
if (!move.is_capture()) {
const piece::Type piece = board.get_square_piece_type(move.source());
- history[piece::get_index(piece, board.get_side())][to_underlying(move.target())] += depth;
+ history[piece::get_index(piece, board.get_side())][move.target()] += depth;
}
alpha = score;
diff --git a/src/engine/evaluate.cpp b/src/engine/evaluate.cpp
@@ -89,7 +89,6 @@ int16_t score_position_side(const Board &board, const color::Color side, const u
int16_t total = 0, opening = 0, endgame = 0;
int8_t square_i;
- const uint8_t side_i = to_underlying(side);
const U64 pawns = board.get_bitboard_piece(PAWN);
const U64 pawnsS = board.get_bitboard_piece(PAWN, side);
const U64 pawnsO = pawns & ~pawnsS;
@@ -112,7 +111,7 @@ int16_t score_position_side(const Board &board, const color::Color side, const u
endgame -= score::pawn_double_endgame;
}
- if (!(pawnsO & mask_passed[side_i][square_i])) total += score::pawn_passed[side_i][rank];
+ if (!(pawnsO & mask_passed[side][square_i])) total += score::pawn_passed[side][rank];
}
bitboard = board.get_bitboard_piece(KNIGHT, side);
diff --git a/src/engine/score.hpp b/src/engine/score.hpp
@@ -1,6 +1,7 @@
#ifndef STELLAR_SCORE_H
#define STELLAR_SCORE_H
+#include "piece.hpp"
#include "utils.hpp"
#define MAX_PLY 64
@@ -146,13 +147,13 @@ enum Phase {
};
inline constexpr int16_t get(const piece::Type piece, const Phase phase = OPENING) {
- return value[to_underlying(phase)][to_underlying(piece)];
+ return value[phase][piece];
}
-inline constexpr int16_t get(const piece::Type piece, const color::Color color, const square::Square square,
- const Phase phase = ENDGAME) {
- uint8_t square_i = to_underlying(color == color::WHITE ? square : square::mirror(square));
- return position[to_underlying(phase)][to_underlying(piece)][square_i];
+inline constexpr int16_t get(piece::Type piece, color::Color color, square::Square square,
+ Phase phase = ENDGAME) {
+ if (color != color::WHITE) square = square::mirror(square);
+ return position[phase][piece][square];
}
inline constexpr const uint8_t pawn_double_opening = 5;
diff --git a/src/move/move.cpp b/src/move/move.cpp
@@ -41,7 +41,7 @@ bool Move::make(Board &board) const {
const square::Square source = this->source(), target = this->target();
const auto ntarget =
- static_cast<square::Square>(to_underlying(this->target()) + (color == color::Color::WHITE ? -8 : +8));
+ static_cast<square::Square>(this->target() + (color == color::Color::WHITE ? -8 : +8));
const piece::Type piece = board.get_square_piece_type(source);
@@ -83,8 +83,7 @@ bool Move::make(Board &board) const {
}
}
- board.and_castle(castling_rights[to_underlying(this->source())] &
- castling_rights[to_underlying(this->target())]);
+ board.and_castle(castling_rights[this->source()] & castling_rights[this->target()]);
if (!board.is_check()) {
board.switch_side();
diff --git a/src/move/move.hpp b/src/move/move.hpp
@@ -29,7 +29,7 @@ struct Move {
Move() : source_i(0), target_i(0), flags_i(0) {}
Move(square::Square source, square::Square target, Flag flags)
- : source_i(to_underlying(source)), target_i(to_underlying(target)), flags_i(flags) {}
+ : source_i(source), target_i(target), flags_i(flags) {}
friend bool operator==(const Move a, const Move b) {
return a.source_i == b.source_i && a.target_i == b.target_i && a.flags_i == b.flags_i;
diff --git a/src/move/movelist.cpp b/src/move/movelist.cpp
@@ -63,7 +63,7 @@ void MoveList::generate(const Board &board, bool attacks_only) {
}
// All piece move
- for (const piece::Type type : ++piece::TypeIter()) {
+ for (piece::Type type = piece::KNIGHT; type <= piece::KING; ++type) {
U64 bitboard = board.get_bitboard_piece(type, color);
bitboard_for_each_bit(src_i, bitboard) {
const auto src = static_cast<square::Square>(src_i);
@@ -85,12 +85,12 @@ void MoveList::generate(const Board &board, bool attacks_only) {
// Castling
if (color == color::WHITE) {
if (!board.is_square_attacked(square::e1, color::BLACK)) {
- if (board.get_castle() & to_underlying(Board::Castle::WK)) {
+ if (board.get_castle() & Board::Castle::WK) {
if (!board.is_square_occupied(square::f1) && !board.is_square_occupied(square::g1) &&
!board.is_square_attacked(square::f1, color::BLACK))
list.emplace_back(square::e1, square::g1, Move::CASTLEK);
}
- if (board.get_castle() & to_underlying(Board::Castle::WQ)) {
+ if (board.get_castle() & Board::Castle::WQ) {
if (!board.is_square_occupied(square::d1) && !board.is_square_occupied(square::c1) &&
!board.is_square_occupied(square::b1) &&
!board.is_square_attacked(square::d1, color::BLACK) &&
@@ -100,12 +100,12 @@ void MoveList::generate(const Board &board, bool attacks_only) {
}
} else {
if (!board.is_square_attacked(square::e8, color::WHITE)) {
- if (board.get_castle() & to_underlying(Board::Castle::BK)) {
+ if (board.get_castle() & Board::Castle::BK) {
if (!board.is_square_occupied(square::f8) && !board.is_square_occupied(square::g8) &&
!board.is_square_attacked(square::f8, color::WHITE))
list.emplace_back(square::Square::e8, square::Square::g8, Move::CASTLEK);
}
- if (board.get_castle() & to_underlying(Board::Castle::BQ)) {
+ if (board.get_castle() & Board::Castle::BQ) {
if (!board.is_square_occupied(square::d8) && !board.is_square_occupied(square::c8) &&
!board.is_square_occupied(square::b8) &&
!board.is_square_attacked(square::d8, color::WHITE) &&
diff --git a/src/piece/piece.hpp b/src/piece/piece.hpp
@@ -18,7 +18,8 @@ enum Type {
KING,
NONE = 7,
};
-typedef Iterator<Type, Type::PAWN, Type::KING> TypeIter;
+
+ENABLE_INCR_OPERATORS_ON(Type)
struct Piece {
const uint8_t index;
@@ -68,7 +69,7 @@ inline constexpr const U64 get_index(const Type type, const color::Color color)
inline constexpr const Piece &get_from_code(const char code) {
color::Color color = isupper(code) ? color::WHITE : color::BLACK;
- for (Type type : TypeIter()) {
+ for (Type type = PAWN; type <= KING; ++type) {
const Piece &piece = get(type, color);
if (piece.code == code) return piece;
}
diff --git a/src/utils/bitboard.cpp b/src/utils/bitboard.cpp
@@ -4,6 +4,7 @@
#include <iostream>
namespace bitboard {
+
void print(U64 bitboard) {
for (int rank = 0; rank < 8; rank++) {
for (int file = 0; file < 8; file++) {
@@ -17,4 +18,5 @@ void print(U64 bitboard) {
std::cout << "\n A B C D E F G H\n\n";
std::cout << " Bitboard: " << std::hex << bitboard << std::dec << std::endl;
}
+
} // namespace bitboard
diff --git a/src/utils/bitboard.hpp b/src/utils/bitboard.hpp
@@ -1,6 +1,7 @@
#ifndef STELLAR_BITBOARD_H
#define STELLAR_BITBOARD_H
+#include "square.hpp"
#include "utils.hpp"
namespace bitboard {
diff --git a/src/utils/square.hpp b/src/utils/square.hpp
@@ -6,7 +6,7 @@
namespace square {
-enum Square {
+enum Square : int {
// clang-format off
a1, b1, c1, d1, e1, f1, g1, h1,
a2, b2, c2, d2, e2, f2, g2, h2,
@@ -19,7 +19,7 @@ enum Square {
// clang-format on
};
-typedef Iterator<Square, Square::a1, Square::h8> Iter;
+ENABLE_INCR_OPERATORS_ON(Square)
inline constexpr const Square mirror_array[]{
// clang-format off
@@ -47,13 +47,10 @@ inline constexpr const char *coordinates_array[] = {
// clang-format on
};
-inline constexpr const uint8_t file(const Square square) { return to_underlying(square) & 0x07; }
-inline constexpr const uint8_t rank(const Square square) { return to_underlying(square) >> 3; }
+inline constexpr const uint8_t file(const Square square) { return square & 0x07; }
+inline constexpr const uint8_t rank(const Square square) { return square >> 3; }
inline constexpr const Square mirror(const Square square) { return mirror_array[square]; }
-
-inline constexpr const std::string to_coordinates(const Square square) {
- return coordinates_array[to_underlying(square)];
-}
+inline constexpr const std::string to_coordinates(const Square square) { return coordinates_array[square]; }
inline const Square from_coordinates(const std::string &cord) {
return static_cast<Square>((cord[1] - '1') * 8 + (cord[0] - 'a'));
diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp
@@ -9,31 +9,8 @@
typedef uint64_t U64;
typedef uint32_t U32;
-#include <type_traits>
-
-template <typename E> constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept {
- return static_cast<typename std::underlying_type<E>::type>(e);
-}
-
-template <typename C, C beginVal, C endVal> class Iterator {
- typedef typename std::underlying_type<C>::type val_t;
- int val;
-
- public:
- constexpr Iterator(const C &f) : val(static_cast<val_t>(f)) {}
- constexpr Iterator() : val(static_cast<val_t>(beginVal)) {}
- constexpr Iterator operator++() {
- ++val;
- return *this;
- }
- constexpr C operator*() { return static_cast<C>(val); }
- constexpr Iterator begin() { return *this; }
- constexpr Iterator end() {
- // static const Iterator endIter = ++Iterator(endVal);
- // return endIter;
- return ++Iterator(endVal);
- }
- constexpr bool operator!=(const Iterator &i) { return val != i.val; }
-};
+#define ENABLE_INCR_OPERATORS_ON(T) \
+ inline T &operator++(T &d) { return d = T(int(d) + 1); } \
+ inline T &operator--(T &d) { return d = T(int(d) - 1); }
#endif