commit 9f2c299a72ac90aa9d2a927666375cc5b6d527b3
parent edfb2f6999e4cc1e8215e10736850b48a12d424b
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Wed, 13 Mar 2024 21:41:22 +0000
Merge square and color into utils out of namespace
Diffstat:
37 files changed, 336 insertions(+), 364 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -3,7 +3,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(
Stellar
- VERSION 1.3.3
+ VERSION 1.3.4
DESCRIPTION "Chess engine written in C++"
HOMEPAGE_URL https://git.dimitrijedobrota.com/stellar.git
LANGUAGES CXX
diff --git a/src/arena/engine.cpp b/src/arena/engine.cpp
@@ -13,7 +13,6 @@ Engine::Pipes::Pipes() {
}
}
-
void Engine::Pipes::close() {
if (::close(fd[0]) < 0 || ::close(fd[1])) {
logger::error("close");
diff --git a/src/arena/game.cpp b/src/arena/game.cpp
@@ -3,6 +3,7 @@
#include "board.hpp"
#include "logger.hpp"
#include "timer.hpp"
+#include "utils_ui.hpp"
#include <format>
@@ -45,12 +46,12 @@ const std::string Game::to_san(const Board &board, const Move move) {
int file[9] = {0}, rank[9] = {0};
uint8_t square_i = 0;
bitboard_for_each_bit(square_i, potential) {
- const std::string crd = square::to_coordinates(static_cast<square::Square>(square_i));
+ const std::string crd = to_coordinates(static_cast<Square>(square_i));
file[crd[0] & 0x3]++;
rank[crd[1] & 0x3]++;
}
- const std::string crd = square::to_coordinates(move.source());
+ const std::string crd = to_coordinates(move.source());
if (file[crd[0] & 0x3] == 1) res += crd[0];
else if (rank[crd[1] & 0x3] == 1)
res += crd[1];
@@ -58,13 +59,13 @@ const std::string Game::to_san(const Board &board, const Move move) {
res += crd;
}
- res += piece::get_code(piece, color::WHITE);
+ res += piece::get_code(piece, WHITE);
if (target != piece::NONE) res += "x";
- res += square::to_coordinates(move.target());
+ res += to_coordinates(move.target());
} else {
- if (target != piece::NONE) res += std::format("{}x", square::to_coordinates(move.source())[0]);
- res += square::to_coordinates(move.target());
- if (move.is_promote()) res += piece::get_code(move.promoted(), color::WHITE);
+ if (target != piece::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.";
}
@@ -94,8 +95,8 @@ std::ostream &operator<<(std::ostream &os, const Game &game) {
if (!game.list.size()) return os;
Board board(game.fen);
- const color::Color side = board.get_side();
- if (side == color::BLACK) os << std::format("1. ... ");
+ const Color side = board.get_side();
+ if (side == BLACK) os << std::format("1. ... ");
for (int i = 0; i < game.list.size(); i++) {
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]);
diff --git a/src/arena/game.hpp b/src/arena/game.hpp
@@ -23,12 +23,12 @@ class Game {
[[nodiscard]] const std::string &get_black() const { return black; }
[[nodiscard]] const Terminate get_terminate() const { return terminate; }
- [[nodiscard]] const bool is_win_white() const { return !draw && winner == color::WHITE; }
- [[nodiscard]] const bool is_win_black() const { return !draw && winner == color::BLACK; }
+ [[nodiscard]] const bool is_win_white() const { return !draw && winner == WHITE; }
+ [[nodiscard]] const bool is_win_black() const { return !draw && winner == BLACK; }
[[nodiscard]] const bool is_draw() const { return draw; }
void set_terminate(const Terminate terminate) { this->terminate = terminate; }
- void set_winner(const color::Color winner) { this->winner = winner; }
+ void set_winner(const Color winner) { this->winner = winner; }
void set_draw(const bool draw) { this->draw = draw; }
static void set_san(bool san) { Game::san = san; }
@@ -47,7 +47,7 @@ class Game {
MoveList list;
bool draw = false;
- color::Color winner;
+ Color winner;
Terminate terminate = Terminate::Deatch;
static bool san;
diff --git a/src/arena/match.cpp b/src/arena/match.cpp
@@ -2,6 +2,7 @@
#include "logger.hpp"
#include "repetition.hpp"
#include "timer.hpp"
+#include "utils_ui.hpp"
uint16_t Match::id_t = 0;
Match::~Match() { logger::log(std::format("Match {}: destroyed", id), logger::Debug); }
@@ -23,11 +24,11 @@ Game Match::play(Settings swhite, Settings sblack, const std::string fen = Game:
engines[0]->send("ucinewgame");
engines[1]->send("ucinewgame");
- color::Color turn = board.get_side();
+ Color turn = board.get_side();
while (true) {
const MoveList list = MoveList(board, false, true);
if (!list.size()) {
- game.set_winner(color::other(turn));
+ game.set_winner(other(turn));
break;
}
@@ -45,15 +46,14 @@ Game Match::play(Settings swhite, Settings sblack, const std::string fen = Game:
std::string move_str = response.substr(9);
if ((move = parse_move(list, move_str)) == Move() || !move.make(board)) {
- logger::log(
- std::format("Match {}: {} illegal {}", id, color::to_string(turn), (std::string)move));
+ logger::log(std::format("Match {}: {} illegal {}", id, to_string(turn), (std::string)move));
game.set_terminate(Game::Illegal);
- game.set_winner(color::other(turn));
+ game.set_winner(other(turn));
break;
}
if (rtable.is_repetition(board.get_hash())) {
- logger::log(std::format("Match {}: {} repetition", id, color::to_string(turn)));
+ logger::log(std::format("Match {}: {} repetition", id, to_string(turn)));
game.set_terminate(Game::Repetition);
game.set_draw(true);
break;
@@ -64,21 +64,21 @@ Game Match::play(Settings swhite, Settings sblack, const std::string fen = Game:
game.play(move);
uint64_t time_passed = timer::get_ms() - time_start;
- if (turn == color::WHITE ? swhite.time <= time_passed : sblack.time <= time_passed) {
- logger::log(std::format("Match {}: {} timeout", id, color::to_string(turn)));
+ if (turn == WHITE ? swhite.time <= time_passed : sblack.time <= time_passed) {
+ logger::log(std::format("Match {}: {} timeout", id, to_string(turn)));
game.set_terminate(Game::Timeout);
- game.set_winner(color::other(turn));
+ game.set_winner(other(turn));
break;
}
- if (turn == color::WHITE && !swhite.depth) swhite.time -= time_passed;
- if (turn == color::BLACK && !sblack.depth) sblack.time -= time_passed;
+ if (turn == WHITE && !swhite.depth) swhite.time -= time_passed;
+ if (turn == BLACK && !sblack.depth) sblack.time -= time_passed;
- turn = color::other(turn);
+ turn = other(turn);
}
if (!game.is_draw()) {
- logger::log(std::format("Match {}: winner is {}", id, color::to_string(turn)));
+ logger::log(std::format("Match {}: winner is {}", id, to_string(turn)));
} else {
logger::log(std::format("Match {}: ended in a draw", id));
}
@@ -87,19 +87,19 @@ Game Match::play(Settings swhite, Settings sblack, const std::string fen = Game:
return game;
}
-std::string Match::get_go(Settings &swhite, Settings &sblack, color::Color side) {
+std::string Match::get_go(Settings &swhite, Settings &sblack, Color side) {
std::string go = "go";
- if (side == color::WHITE && swhite.depth) go += " depth " + std::to_string(swhite.depth);
+ if (side == WHITE && swhite.depth) go += " depth " + std::to_string(swhite.depth);
else {
- if (side == color::WHITE && swhite.togo) go += " movestogo " + std::to_string(swhite.togo);
+ if (side == WHITE && swhite.togo) go += " movestogo " + std::to_string(swhite.togo);
if (!sblack.depth && swhite.time) go += " wtime " + std::to_string(swhite.time);
if (swhite.inc) go += " winc " + std::to_string(swhite.inc);
if (swhite.movetime) go += " movetime " + std::to_string(swhite.movetime);
}
- if (side == color::BLACK && sblack.depth) go += " depth " + std::to_string(sblack.depth);
+ if (side == BLACK && sblack.depth) go += " depth " + std::to_string(sblack.depth);
else {
- if (side == color::BLACK && sblack.togo) go += " movestogo " + std::to_string(sblack.togo);
+ if (side == BLACK && sblack.togo) go += " movestogo " + std::to_string(sblack.togo);
if (!swhite.depth && sblack.time) go += " btime " + std::to_string(sblack.time);
if (sblack.inc) go += " binc " + std::to_string(sblack.inc);
if (swhite.movetime) go += " movetime " + std::to_string(sblack.movetime);
@@ -108,8 +108,8 @@ std::string Match::get_go(Settings &swhite, Settings &sblack, color::Color side)
}
Move Match::parse_move(const MoveList list, const std::string &move_string) {
- const square::Square source = square::from_coordinates(move_string.substr(0, 2));
- const square::Square target = square::from_coordinates(move_string.substr(2, 2));
+ const Square source = from_coordinates(move_string.substr(0, 2));
+ const Square target = from_coordinates(move_string.substr(2, 2));
for (int i = 0; i < list.size(); i++) {
const Move crnt = list[i];
diff --git a/src/arena/match.hpp b/src/arena/match.hpp
@@ -17,7 +17,7 @@ class Match {
Game play(Settings swhite, Settings sblack, const std::string fen);
private:
- static std::string get_go(Settings &swhite, Settings &sblack, color::Color side);
+ static std::string get_go(Settings &swhite, Settings &sblack, Color side);
static Move parse_move(const MoveList list, const std::string &move_string);
std::array<Engine *, 2> engines;
diff --git a/src/attack/attack.hpp b/src/attack/attack.hpp
@@ -1,7 +1,6 @@
#ifndef STELLAR_ATTACK_H
#define STELLAR_ATTACK_H
-#include "square.hpp"
#include "utils.hpp"
#include "bishop.hpp"
@@ -17,11 +16,11 @@ namespace attack {
void init(void);
-inline constexpr const U64 attack_pawn(const color::Color color, const square::Square from) {
+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::Square from, const U64 occupancy) {
+inline constexpr const U64 attack(const piece::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);
diff --git a/src/attack/bishop.cpp b/src/attack/bishop.cpp
@@ -44,11 +44,11 @@ static inline constexpr const int relevant_bits[64] = {
inline constexpr const bitboard::direction_f dir[4] = {bitboard::noEaOne, bitboard::noWeOne,
bitboard::soEaOne, bitboard::soWeOne};
-inline constexpr U32 hash(const U64 key, const square::Square square) {
+inline constexpr U32 hash(const U64 key, const Square square) {
return (key * bishop_magic_numbers[square]) >> (64 - relevant_bits[square]);
}
-inline constexpr U64 mask_fly(const square::Square square, U64 block) {
+inline constexpr U64 mask_fly(const Square square, U64 block) {
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)};
@@ -59,14 +59,14 @@ std::array<U64, 64> mask = {{0}};
std::array<std::array<U64, 4098>, 64> attacks = {{{0}}};
void init(void) {
- for (square::Square square = square::a1; square <= square::h8; ++square) {
+ for (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};
mask[square] = attack::slider::mask(square, C64(0), dir, len);
}
- for (square::Square square = square::a1; square <= square::h8; ++square) {
+ for (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;
@@ -79,7 +79,7 @@ void init(void) {
}
}
-U64 attack(const square::Square square, U64 occupancy) {
+U64 attack(const Square square, U64 occupancy) {
occupancy &= mask[square];
occupancy = hash(occupancy, square);
return attacks[square][occupancy];
diff --git a/src/attack/bishop.hpp b/src/attack/bishop.hpp
@@ -1,16 +1,15 @@
#ifndef STELLAR_BISHOP_H
#define STELLAR_BISHOP_H
-#include "square.hpp"
#include "utils.hpp"
namespace attack {
namespace bishop {
void init(void);
-U64 attack(const square::Square square, U64 occupancy);
+U64 attack(const Square square, U64 occupancy);
-}
+} // namespace bishop
} // namespace attack
#endif
diff --git a/src/attack/king.hpp b/src/attack/king.hpp
@@ -3,7 +3,6 @@
#include "bit.hpp"
#include "bitboard.hpp"
-#include "square.hpp"
#include "utils.hpp"
#include <array>
@@ -11,7 +10,7 @@
namespace attack {
namespace king {
-static constexpr U64 mask(const square::Square square) {
+static constexpr U64 mask(const Square square) {
U64 bitboard = C64(0), attacks = C64(0);
bit::set(bitboard, square);
@@ -28,14 +27,14 @@ 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) {
+ for (Square square = Square::a1; square <= Square::h8; ++square) {
attacks[square] = mask(square);
}
return attacks;
}();
-inline constexpr U64 attack(const square::Square square) { return attacks[square]; }
+inline constexpr U64 attack(const Square square) { return attacks[square]; }
} // namespace king
} // namespace attack
diff --git a/src/attack/knight.hpp b/src/attack/knight.hpp
@@ -3,7 +3,6 @@
#include "bit.hpp"
#include "bitboard.hpp"
-#include "square.hpp"
#include "utils.hpp"
#include <array>
@@ -11,7 +10,7 @@
namespace attack {
namespace knight {
-static constexpr U64 mask(const square::Square square) {
+static constexpr U64 mask(const Square square) {
U64 bitboard = C64(0), attacks = C64(0), tmp;
bit::set(bitboard, square);
@@ -31,14 +30,14 @@ 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) {
+ for (Square square = Square::a1; square <= Square::h8; ++square) {
attacks[square] = mask(square);
}
return attacks;
}();
-inline constexpr U64 attack(const square::Square square) { return attacks[square]; }
+inline constexpr U64 attack(const Square square) { return attacks[square]; }
} // namespace knight
} // namespace attack
diff --git a/src/attack/pawn.hpp b/src/attack/pawn.hpp
@@ -3,8 +3,6 @@
#include "bit.hpp"
#include "bitboard.hpp"
-#include "color.hpp"
-#include "square.hpp"
#include "utils.hpp"
#include <array>
@@ -12,14 +10,14 @@
namespace attack {
namespace pawn {
-static constexpr U64 mask_white(const square::Square square) {
+static constexpr U64 mask_white(const 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) {
+static constexpr U64 mask_black(const Square square) {
U64 bitboard = C64(0);
bit::set(bitboard, square);
@@ -30,17 +28,15 @@ 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);
+ for (Square square = Square::a1; square <= Square::h8; ++square) {
+ attacks[WHITE][square] = mask_white(square);
+ attacks[BLACK][square] = mask_black(square);
}
return attacks;
}();
-inline constexpr U64 attack(color::Color color, square::Square square) {
- return attacks[color][square];
-}
+inline constexpr U64 attack(Color color, Square square) { return attacks[color][square]; }
} // namespace pawn
} // namespace attack
diff --git a/src/attack/queen.hpp b/src/attack/queen.hpp
@@ -7,7 +7,7 @@
namespace attack {
namespace queen {
-inline U64 attack(const square::Square square, U64 occupancy) {
+inline U64 attack(const Square square, U64 occupancy) {
return rook::attack(square, occupancy) | bishop::attack(square, occupancy);
}
diff --git a/src/attack/rook.cpp b/src/attack/rook.cpp
@@ -43,11 +43,11 @@ inline constexpr const U64 rook_magic_numbers[64] = {
inline constexpr const bitboard::direction_f dir[4] = {bitboard::westOne, bitboard::soutOne,
bitboard::eastOne, bitboard::nortOne};
-inline constexpr U32 hash(const U64 key, const square::Square square) {
+inline constexpr U32 hash(const U64 key, const Square square) {
return (key * rook_magic_numbers[square]) >> (64 - relevant_bits[square]);
}
-inline constexpr U64 mask_fly(const square::Square square, U64 block) {
+inline constexpr U64 mask_fly(const Square square, U64 block) {
int tr = square / 8, tf = square % 8;
int len[4] = {tf, tr, 7 - tf, 7 - tr};
@@ -58,14 +58,14 @@ std::array<U64, 64> mask = {{0}};
std::array<std::array<U64, 4096>, 64> attacks = {{{0}}};
void init(void) {
- for (square::Square square = square::a1; square <= square::h8; ++square) {
+ for (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};
mask[square] = attack::slider::mask(square, C64(0), dir, len);
}
- for (square::Square square = square::a1; square <= square::h8; ++square) {
+ for (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;
@@ -78,7 +78,7 @@ void init(void) {
}
}
-U64 attack(const square::Square square, U64 occupancy) {
+U64 attack(const Square square, U64 occupancy) {
occupancy &= mask[square];
occupancy = hash(occupancy, square);
return attacks[square][occupancy];
diff --git a/src/attack/rook.hpp b/src/attack/rook.hpp
@@ -1,14 +1,13 @@
#ifndef STELLAR_ATTACK_ROOK_H
#define STELLAR_ATTACK_ROOK_H
-#include "square.hpp"
#include "utils.hpp"
namespace attack {
namespace rook {
void init(void);
-U64 attack(const square::Square square, U64 occupancy);
+U64 attack(const Square square, U64 occupancy);
} // namespace rook
} // namespace attack
diff --git a/src/attack/slider.hpp b/src/attack/slider.hpp
@@ -3,7 +3,6 @@
#include "bit.hpp"
#include "bitboard.hpp"
-#include "square.hpp"
#include "utils.hpp"
namespace attack {
@@ -22,7 +21,7 @@ inline constexpr U64 occupancy(U64 index, uint8_t bits_in_mask, U64 attack_mask)
return occupancy;
}
-inline constexpr U64 mask(const square::Square square, U64 block, const bitboard::direction_f dir[4],
+inline constexpr U64 mask(const Square square, U64 block, const bitboard::direction_f dir[4],
const int len[4]) {
U64 bitboard = C64(0), attacks = C64(0);
bit::set(bitboard, square);
diff --git a/src/bitboard/bitboard.cpp b/src/bitboard/bitboard.cpp
@@ -1,10 +1,22 @@
#include "bitboard.hpp"
#include "bit.hpp"
+#include "piece.hpp"
#include <iostream>
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
@@ -1,11 +1,11 @@
#ifndef STELLAR_BITBOARD_H
#define STELLAR_BITBOARD_H
-#include "square.hpp"
#include "utils.hpp"
namespace bitboard {
+void init(void);
void print(U64 bitboard);
inline constexpr const U64 notAFile = C64(0xfefefefefefefefe);
@@ -21,6 +21,8 @@ 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.cpp b/src/board/board.cpp
@@ -5,8 +5,7 @@
#include "board.hpp"
#include "piece.hpp"
-#include "square.hpp"
-#include "utils.hpp"
+#include "utils_ui.hpp"
#include "zobrist.hpp"
/* Init arrays for Zobris hashing */
@@ -21,7 +20,7 @@ Board::Board(const std::string &fen) {
for (i = 0; fen[i] != ' '; i++) {
if (isalpha(fen[i])) {
const piece::Piece &piece = piece::get_from_code(fen[i]);
- set_piece(piece.type, piece.color, static_cast<square::Square>(rank * 8 + file));
+ set_piece(piece.type, piece.color, static_cast<Square>(rank * 8 + file));
file++;
} else if (isdigit(fen[i])) {
file += fen[i] - '0';
@@ -34,9 +33,7 @@ Board::Board(const std::string &fen) {
}
}
- side = fen[++i] == 'w' ? color::WHITE
- : fen[i] == 'b' ? color::BLACK
- : throw std::runtime_error("Invalid player char");
+ side = fen[++i] == 'w' ? WHITE : fen[i] == 'b' ? BLACK : throw std::runtime_error("Invalid player char");
for (i += 2; fen[i] != ' '; i++) {
if (fen[i] == 'K') castle |= Castle::WK;
@@ -53,7 +50,7 @@ Board::Board(const std::string &fen) {
throw std::runtime_error("Invalid castle rights");
}
- enpassant = fen[++i] != '-' ? square::from_coordinates(fen.substr(i, 2)) : square::no_sq;
+ enpassant = fen[++i] != '-' ? from_coordinates(fen.substr(i, 2)) : Square::no_sq;
hash = zobrist::hash(*this);
}
@@ -62,7 +59,7 @@ std::ostream &operator<<(std::ostream &os, const Board &board) {
for (int rank = 0; rank < 8; rank++) {
for (int file = 0; file < 8; file++) {
if (!file) os << 8 - rank << " ";
- auto square = static_cast<square::Square>((7 - rank) * 8 + file);
+ auto square = static_cast<Square>((7 - rank) * 8 + file);
const piece::Piece *piece = board.get_square_piece(square);
os << (piece ? piece->code : '.') << " ";
}
@@ -70,8 +67,8 @@ std::ostream &operator<<(std::ostream &os, const Board &board) {
}
os << " A B C D E F G H\n";
os << " Side: ";
- os << ((board.side == color::WHITE) ? "white" : "black") << "\n";
- os << "Enpassant: " << square::to_coordinates(board.enpassant) << "\n";
+ os << ((board.side == WHITE) ? "white" : "black") << "\n";
+ os << "Enpassant: " << to_coordinates(board.enpassant) << "\n";
os << " Castle:";
os << ((board.castle & Board::Castle::WK) ? 'K' : '-');
os << ((board.castle & Board::Castle::WQ) ? 'Q' : '-');
diff --git a/src/board/board.hpp b/src/board/board.hpp
@@ -3,9 +3,7 @@
#include "attack.hpp"
#include "bit.hpp"
-#include "color.hpp"
#include "piece.hpp"
-#include "square.hpp"
#include "utils.hpp"
#include "zobrist.hpp"
@@ -31,105 +29,101 @@ class Board {
/* Getters */
[[nodiscard]] inline constexpr U64 get_hash() const;
- [[nodiscard]] inline constexpr color::Color get_side() const;
+ [[nodiscard]] inline constexpr Color get_side() const;
[[nodiscard]] inline constexpr uint8_t get_castle() const;
- [[nodiscard]] inline constexpr square::Square get_enpassant() const;
+ [[nodiscard]] inline constexpr Square get_enpassant() const;
- [[nodiscard]] inline constexpr U64 get_bitboard_color(color::Color side) const;
+ [[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 color) const;
+ [[nodiscard]] inline constexpr U64 get_bitboard_piece(piece::Type piece, Color color) const;
- [[nodiscard]] inline constexpr U64 get_bitboard_piece_attacks(piece::Type piece, color::Color color,
- square::Square from) const;
- [[nodiscard]] inline constexpr U64 get_bitboard_piece_moves(piece::Type piece, color::Color color,
- square::Square from) const;
- [[nodiscard]] inline constexpr U64 get_bitboard_square_land(square::Square land, piece::Type piece,
- color::Color side) 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 color::Color get_square_piece_color(square::Square square) const;
- [[nodiscard]] inline constexpr piece::Type get_square_piece_type(square::Square square) const;
- [[nodiscard]] inline constexpr const piece::Piece *get_square_piece(square::Square square) 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 const piece::Piece *get_square_piece(Square square) const;
/* Setters */
inline constexpr void xor_hash(U64 op);
inline constexpr void switch_side();
inline constexpr void and_castle(uint8_t right);
- inline constexpr void set_enpassant(square::Square target);
+ inline constexpr void set_enpassant(Square target);
- inline constexpr void pop_bitboard_color(color::Color color, square::Square square);
- inline constexpr void set_bitboard_color(color::Color color, square::Square square);
+ 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 square);
- inline constexpr void set_bitboard_piece(piece::Type type, square::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_piece(piece::Type type, color::Color side, square::Square square);
- inline constexpr void set_piece(piece::Type type, color::Color side, square::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);
/* Queries */
- [[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_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,
+ Square target) const;
[[nodiscard]] inline constexpr bool is_check() const;
private:
U64 colors[2] = {0};
U64 pieces[6] = {0};
U64 hash = 0;
- color::Color side = color::WHITE;
- square::Square enpassant = square::Square::no_sq;
+ Color side = WHITE;
+ Square enpassant = Square::no_sq;
uint8_t castle = 0;
};
-constexpr color::Color Board::get_side() const { return side; }
+constexpr Color Board::get_side() const { return side; }
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 Square Board::get_enpassant() const { return enpassant; }
-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_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(piece::Type piece, color::Color color) const {
+constexpr U64 Board::get_bitboard_piece(piece::Type piece, Color color) const {
return pieces[piece] & colors[color];
}
-constexpr U64 Board::get_bitboard_piece_attacks(piece::Type type, color::Color color,
- square::Square from) const {
+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);
return attack::attack(type, from, get_bitboard_occupancy());
}
-constexpr U64 Board::get_bitboard_piece_moves(piece::Type type, color::Color color,
- square::Square square) const {
+constexpr U64 Board::get_bitboard_piece_moves(piece::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::Square land, piece::Type piece,
- color::Color side) const {
+constexpr U64 Board::get_bitboard_square_land(Square land, piece::Type piece, Color side) const {
- return get_bitboard_piece_attacks(piece, color::other(side), land) & get_bitboard_piece(piece, side);
+ return get_bitboard_piece_attacks(piece, other(side), land) & get_bitboard_piece(piece, side);
}
-constexpr color::Color Board::get_square_piece_color(square::Square square) const {
- if (bit::get(colors[color::WHITE], square)) return color::WHITE;
- if (bit::get(colors[color::BLACK], square)) return color::BLACK;
+constexpr Color Board::get_square_piece_color(Square square) const {
+ if (bit::get(colors[WHITE], square)) return WHITE;
+ if (bit::get(colors[BLACK], square)) return BLACK;
throw std::exception();
}
-constexpr piece::Type Board::get_square_piece_type(square::Square square) const {
+constexpr piece::Type Board::get_square_piece_type(Square square) const {
for (piece::Type type = piece::PAWN; type <= piece::KING; ++type) {
if (bit::get(pieces[type], square)) return type;
}
return piece::Type::NONE;
}
-constexpr const piece::Piece *Board::get_square_piece(square::Square square) const {
+constexpr const piece::Piece *Board::get_square_piece(Square square) const {
try {
return &piece::get(get_square_piece_type(square), get_square_piece_color(square));
} catch (std::exception &e) {
@@ -147,50 +141,39 @@ constexpr void Board::and_castle(uint8_t right) {
}
constexpr void Board::switch_side() {
- side = color::other(side);
+ side = other(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);
+constexpr void Board::set_enpassant(Square target) {
+ if (enpassant != Square::no_sq) hash ^= zobrist::key_enpassant(enpassant);
+ if (target != Square::no_sq) hash ^= zobrist::key_enpassant(target);
enpassant = target;
}
-constexpr void Board::pop_bitboard_color(color::Color color, square::Square square) {
- bit::pop(colors[color], square);
-}
-
-constexpr void Board::set_bitboard_color(color::Color color, square::Square square) {
- bit::set(colors[color], square);
-}
-
-constexpr void Board::pop_bitboard_piece(piece::Type type, square::Square square) {
- bit::pop(pieces[type], square);
-}
-
-constexpr void Board::set_bitboard_piece(piece::Type type, square::Square square) {
- bit::set(pieces[type], square);
-}
+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_piece(piece::Type type, color::Color side, square::Square square) {
+constexpr void Board::pop_piece(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::Color side, square::Square square) {
+constexpr void Board::set_piece(piece::Type type, Color side, Square square) {
set_bitboard_color(side, square);
set_bitboard_piece(type, square);
}
/* Queries */
-constexpr bool Board::is_square_occupied(square::Square square) const {
+constexpr bool Board::is_square_occupied(Square square) const {
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);
+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) {
if (get_bitboard_piece_attacks(type, side_other, square) & get_bitboard_piece(type, side)) {
@@ -201,15 +184,15 @@ constexpr bool Board::is_square_attacked(square::Square square, color::Color sid
return false;
}
-constexpr bool Board::is_piece_attack_square(piece::Type type, color::Color color, square::Square source,
- square::Square target) const {
+constexpr bool Board::is_piece_attack_square(piece::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];
- color::Color side_other = (side == color::BLACK) ? color::WHITE : color::BLACK;
- auto square = static_cast<square::Square>(bit::lsb_index(king));
+ Color side_other = (side == BLACK) ? WHITE : BLACK;
+ auto square = static_cast<Square>(bit::lsb_index(king));
return is_square_attacked(square, side_other);
}
@@ -218,19 +201,19 @@ U64 zobrist::hash(const Board &board) {
uint8_t square = 0;
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);
+ 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]; }
- int piece_black_index = piece::get_index(type, color::BLACK);
- U64 bitboard_black = board.get_bitboard_piece(type, color::BLACK);
+ int piece_black_index = piece::get_index(type, BLACK);
+ U64 bitboard_black = board.get_bitboard_piece(type, BLACK);
bitboard_for_each_bit(square, bitboard_black) { key_final ^= keys_piece[piece_black_index][square]; }
}
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[board.get_enpassant()];
+ if (board.get_side() == BLACK) key_final ^= keys_side;
+ if (board.get_enpassant() != 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
@@ -20,8 +20,8 @@ const U64 keys_side = Random(C32(1699391443))();
inline void init() {
Random gen1(C64(1804289383));
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;
+ 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++) {
keys_piece[piece_index_white][square] = gen1();
keys_piece[piece_index_black][square] = gen1();
@@ -42,8 +42,8 @@ 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[square]; }
-inline constexpr U64 key_piece(piece::Type type, color::Color color, square::Square square) {
+inline constexpr U64 key_enpassant(Square square) { return keys_enpassant[square]; }
+inline constexpr U64 key_piece(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
@@ -194,7 +194,7 @@ int stats_move_make(Board ©, const Move move) {
void stats_move_make_pruning(Board ©) {
copy = board;
board.switch_side();
- board.set_enpassant(square::no_sq);
+ board.set_enpassant(Square::no_sq);
ply++;
}
diff --git a/src/engine/evaluate.cpp b/src/engine/evaluate.cpp
@@ -3,7 +3,6 @@
#include "bitboard.hpp"
#include "piece.hpp"
#include "score.hpp"
-#include "square.hpp"
#include "utils.hpp"
#include <array>
@@ -83,7 +82,7 @@ uint16_t score_game_phase(const Board &board) {
return total;
}
-int16_t score_position_side(const Board &board, const color::Color side, const uint16_t phase_score) {
+int16_t score_position_side(const Board &board, const Color side, const uint16_t phase_score) {
U64 bitboard;
int16_t total = 0, opening = 0, endgame = 0;
@@ -95,12 +94,12 @@ int16_t score_position_side(const Board &board, const color::Color side, const u
bitboard = board.get_bitboard_piece(PAWN, side);
bitboard_for_each_bit(square_i, bitboard) {
- const auto square = static_cast<square::Square>(square_i);
+ const auto square = static_cast<Square>(square_i);
opening += score::get(PAWN, side, square, OPENING) + score::get(PAWN, OPENING);
endgame += score::get(PAWN, side, square, ENDGAME) + score::get(PAWN, ENDGAME);
// check isolated, doubled and passed pawns
- const uint8_t file = square::file(square), rank = square::rank(square);
+ const uint8_t file = get_file(square), rank = get_rank(square);
if (!(mask_isolated[file] & pawnsS)) {
opening -= score::pawn_isolated_opening;
endgame -= score::pawn_isolated_endgame;
@@ -116,45 +115,45 @@ int16_t score_position_side(const Board &board, const color::Color side, const u
bitboard = board.get_bitboard_piece(KNIGHT, side);
bitboard_for_each_bit(square_i, bitboard) {
- const auto square = static_cast<square::Square>(square_i);
+ const auto square = static_cast<Square>(square_i);
opening += score::get(KNIGHT, side, square, OPENING) + score::get(KNIGHT, OPENING);
endgame += score::get(KNIGHT, side, square, ENDGAME) + score::get(KNIGHT, ENDGAME);
}
bitboard = board.get_bitboard_piece(BISHOP, side);
bitboard_for_each_bit(square_i, bitboard) {
- const auto square = static_cast<square::Square>(square_i);
+ const auto square = static_cast<Square>(square_i);
opening += score::get(BISHOP, side, square, OPENING) + score::get(BISHOP, OPENING);
endgame += score::get(BISHOP, side, square, ENDGAME) + score::get(BISHOP, ENDGAME);
}
bitboard = board.get_bitboard_piece(ROOK, side);
bitboard_for_each_bit(square_i, bitboard) {
- const auto square = static_cast<square::Square>(square_i);
+ const auto square = static_cast<Square>(square_i);
opening += score::get(ROOK, side, square, OPENING) + score::get(ROOK, OPENING);
endgame += score::get(ROOK, side, square, ENDGAME) + score::get(ROOK, ENDGAME);
// rook on open and semi-open files
- const uint8_t file = square::file(square);
+ const uint8_t file = get_file(square);
if (!(pawns & mask_file[file])) total += score::file_open;
if (!(pawnsS & mask_file[file])) total += score::file_open_semi;
}
bitboard = board.get_bitboard_piece(QUEEN, side);
bitboard_for_each_bit(square_i, bitboard) {
- const auto square = static_cast<square::Square>(square_i);
+ const auto square = static_cast<Square>(square_i);
opening += score::get(QUEEN, side, square, OPENING) + score::get(QUEEN, OPENING);
endgame += score::get(QUEEN, side, square, ENDGAME) + score::get(QUEEN, ENDGAME);
}
bitboard = board.get_bitboard_piece(KING, side);
bitboard_for_each_bit(square_i, bitboard) {
- const auto square = static_cast<square::Square>(square_i);
+ const auto square = static_cast<Square>(square_i);
opening += score::get(KING, side, square, OPENING) + score::get(KING, OPENING);
endgame += score::get(KING, side, square, ENDGAME) + score::get(KING, ENDGAME);
// king on open and semi-open files
- const uint8_t file = square::file(square);
+ const uint8_t file = get_file(square);
if (!(pawns & mask_file[file])) total -= score::file_open;
if (!(pawnsS & mask_file[file])) total -= score::file_open_semi;
}
@@ -167,9 +166,9 @@ int16_t score_position_side(const Board &board, const color::Color side, const u
int16_t score_position(const Board &board) {
const uint16_t phase_score = score_game_phase(board);
- const int16_t score = score_position_side(board, color::WHITE, phase_score) -
- score_position_side(board, color::BLACK, phase_score);
- return board.get_side() == color::WHITE ? score : -score;
+ const int16_t score =
+ score_position_side(board, WHITE, phase_score) - score_position_side(board, BLACK, phase_score);
+ return board.get_side() == WHITE ? score : -score;
}
} // namespace evaluate
diff --git a/src/engine/score.hpp b/src/engine/score.hpp
@@ -150,9 +150,8 @@ inline constexpr int16_t get(const piece::Type piece, const Phase phase = OPENIN
return value[phase][piece];
}
-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);
+inline constexpr int16_t get(piece::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/engine/uci.cpp b/src/engine/uci.cpp
@@ -18,8 +18,8 @@ void communicate(const uci::Settings *settings) {
}
inline bool parse_move(const Board &board, Move &move, const std::string &move_string) {
- const square::Square source = square::from_coordinates(move_string.substr(0, 2));
- const square::Square target = square::from_coordinates(move_string.substr(2, 2));
+ const Square source = from_coordinates(move_string.substr(0, 2));
+ const Square target = from_coordinates(move_string.substr(2, 2));
const MoveList list(board);
for (int i = 0; i < list.size(); i++) {
@@ -85,8 +85,7 @@ void loop() {
uint16_t winc = 0, binc = 0, movestogo = 60;
while (iss >> command) {
- if (command == "wtime")
- iss >> wtime;
+ if (command == "wtime") iss >> wtime;
else if (command == "btime")
iss >> btime;
else if (command == "winc")
@@ -116,13 +115,13 @@ void loop() {
}
settings.starttime = timer::get_ms();
- uint64_t time = (board.get_side() == color::WHITE) ? wtime : btime;
+ uint64_t time = (board.get_side() == WHITE) ? wtime : btime;
if (movetime != 0) {
time = movetime;
movestogo = 1;
} else if (time != 0) {
- uint16_t inc = (board.get_side() == color::WHITE) ? winc : binc;
+ uint16_t inc = (board.get_side() == WHITE) ? winc : binc;
time /= movestogo;
time -= 50;
settings.stoptime = settings.starttime + time + inc;
diff --git a/src/engine/uci.hpp b/src/engine/uci.hpp
@@ -6,6 +6,7 @@
#include "movelist.hpp"
#include "score.hpp"
#include "utils.hpp"
+#include "utils_ui.hpp"
namespace uci {
diff --git a/src/move/move.cpp b/src/move/move.cpp
@@ -1,21 +1,21 @@
#include "move.hpp"
#include "utils.hpp"
+#include "utils_ui.hpp"
#include <algorithm>
#include <iomanip>
-void Move::piece_remove(Board &board, piece::Type type, color::Color color, square::Square square) const {
+void Move::piece_remove(Board &board, piece::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 color, square::Square square) const {
+void Move::piece_set(Board &board, piece::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 color, square::Square source,
- square::Square target) const {
+void Move::piece_move(Board &board, piece::Type type, Color color, Square source, Square target) const {
piece_remove(board, type, color, source);
piece_set(board, type, color, target);
}
@@ -37,11 +37,10 @@ bool Move::make(Board &board) const {
// clang-format on
};
- const color::Color color = board.get_side(), colorOther = color::other(color);
- const square::Square source = this->source(), target = this->target();
+ const Color color = board.get_side(), colorOther = other(color);
+ const Square source = this->source(), target = this->target();
- const auto ntarget =
- static_cast<square::Square>(this->target() + (color == color::Color::WHITE ? -8 : +8));
+ const auto ntarget = static_cast<Square>(this->target() + (color == Color::WHITE ? -8 : +8));
const piece::Type piece = board.get_square_piece_type(source);
@@ -67,19 +66,15 @@ bool Move::make(Board &board) const {
}
}
- board.set_enpassant(is_double() ? ntarget : square::Square::no_sq);
+ board.set_enpassant(is_double() ? ntarget : Square::no_sq);
if (is_castle()) {
- if (color == color::Color::WHITE) {
- if (is_castle_king())
- piece_move(board, ROOK, color::Color::WHITE, square::Square::h1, square::Square::f1);
- if (is_castle_queen())
- piece_move(board, ROOK, color::Color::WHITE, square::Square::a1, square::Square::d1);
+ if (color == Color::WHITE) {
+ if (is_castle_king()) piece_move(board, ROOK, Color::WHITE, Square::h1, Square::f1);
+ if (is_castle_queen()) piece_move(board, ROOK, Color::WHITE, Square::a1, Square::d1);
} else {
- if (is_castle_king())
- piece_move(board, ROOK, color::Color::BLACK, square::Square::h8, square::Square::f8);
- if (is_castle_queen())
- piece_move(board, ROOK, color::Color::BLACK, square::Square::a8, square::Square::d8);
+ if (is_castle_king()) piece_move(board, ROOK, Color::BLACK, Square::h8, Square::f8);
+ if (is_castle_queen()) piece_move(board, ROOK, Color::BLACK, Square::a8, Square::d8);
}
}
@@ -93,8 +88,8 @@ bool Move::make(Board &board) const {
}
void Move::print() const {
- std::cout << square::to_coordinates(source()) << " ";
- std::cout << square::to_coordinates(target()) << " ";
+ std::cout << to_coordinates(source()) << " ";
+ std::cout << to_coordinates(target()) << " ";
std::cout << (is_promote() ? piece::get_code(promoted()) : '.') << " ";
std::cout << is_double() << " ";
std::cout << is_enpassant() << " ";
@@ -102,7 +97,7 @@ void Move::print() const {
}
Move::operator std::string() const {
- std::string res = square::to_coordinates(source()) + square::to_coordinates(target());
+ std::string res = to_coordinates(source()) + to_coordinates(target());
if (is_promote()) res += piece::get_code(promoted());
return res;
}
diff --git a/src/move/move.hpp b/src/move/move.hpp
@@ -28,15 +28,14 @@ struct Move {
};
Move() : source_i(0), target_i(0), flags_i(0) {}
- Move(square::Square source, square::Square target, Flag flags)
- : source_i(source), target_i(target), flags_i(flags) {}
+ Move(Square source, Square target, Flag 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;
}
- [[nodiscard]] square::Square source() const { return static_cast<square::Square>(source_i); }
- [[nodiscard]] square::Square target() const { return static_cast<square::Square>(target_i); }
+ [[nodiscard]] Square source() const { return static_cast<Square>(source_i); }
+ [[nodiscard]] Square target() const { return static_cast<Square>(target_i); }
[[nodiscard]] bool is_capture() const { return flags_i != PQUIET && (flags_i & CAPTURE); }
[[nodiscard]] bool is_promote() const { return flags_i & 0x8; }
@@ -60,10 +59,9 @@ struct Move {
void print() const;
private:
- inline void piece_remove(Board &board, piece::Type type, color::Color color, square::Square square) const;
- inline void piece_set(Board &board, piece::Type type, color::Color color, square::Square square) const;
- inline void piece_move(Board &board, piece::Type type, color::Color color, square::Square source,
- square::Square target) const;
+ 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;
unsigned source_i : 6;
unsigned target_i : 6;
diff --git a/src/move/movelist.cpp b/src/move/movelist.cpp
@@ -1,30 +1,29 @@
#include "movelist.hpp"
-#include "color.hpp"
#include "piece.hpp"
#include <iomanip>
#define pawn_canPromote(color, source) \
- ((color == color::WHITE && source >= square::a7 && source <= square::h7) || \
- (color == color::BLACK && source >= square::a2 && source <= square::h2))
+ ((color == WHITE && source >= Square::a7 && source <= Square::h7) || \
+ (color == BLACK && source >= Square::a2 && source <= Square::h2))
#define pawn_onStart(color, source) \
- ((color == color::BLACK && source >= square::a7 && source <= square::h7) || \
- (color == color::WHITE && source >= square::a2 && source <= square::h2))
+ ((color == BLACK && source >= Square::a7 && source <= Square::h7) || \
+ (color == WHITE && source >= Square::a2 && source <= Square::h2))
using piece::Type::PAWN;
void MoveList::generate(const Board &board, bool attacks_only) {
uint8_t src_i = 0, tgt_i = 0;
- const color::Color color = board.get_side(), colorOther = color::other(color);
+ const Color color = board.get_side(), colorOther = other(color);
// pawn moves
- const int add = (color == color::WHITE) ? +8 : -8;
+ const int add = (color == WHITE) ? +8 : -8;
U64 bitboard = board.get_bitboard_piece(PAWN, color);
bitboard_for_each_bit(src_i, bitboard) {
- const auto src = static_cast<square::Square>(src_i);
- const auto tgt = static_cast<square::Square>(tgt_i = src_i + add);
+ const auto src = static_cast<Square>(src_i);
+ const auto tgt = static_cast<Square>(tgt_i = src_i + add);
if (!attacks_only && !board.is_square_occupied(tgt)) {
if (pawn_canPromote(color, src)) {
list.emplace_back(src, tgt, Move::PKNIGHT);
@@ -35,7 +34,7 @@ void MoveList::generate(const Board &board, bool attacks_only) {
list.emplace_back(src, tgt, Move::PQUIET);
// two ahead
- const auto tgt = static_cast<square::Square>(tgt_i + add);
+ const auto tgt = static_cast<Square>(tgt_i + add);
if (pawn_onStart(color, src) && !board.is_square_occupied(tgt))
list.emplace_back(src, tgt, Move::DOUBLE);
}
@@ -45,7 +44,7 @@ void MoveList::generate(const Board &board, bool attacks_only) {
U64 attack =
board.get_bitboard_piece_attacks(PAWN, color, src) & board.get_bitboard_color(colorOther);
bitboard_for_each_bit(tgt_i, attack) {
- const auto tgt = static_cast<square::Square>(tgt_i);
+ const auto tgt = static_cast<Square>(tgt_i);
if (pawn_canPromote(color, src)) {
list.emplace_back(src, tgt, Move::PCKNIGHT);
list.emplace_back(src, tgt, Move::PCBISHOP);
@@ -57,8 +56,8 @@ void MoveList::generate(const Board &board, bool attacks_only) {
}
// en passant
- const square::Square enpassant = board.get_enpassant();
- if (enpassant != square::no_sq && board.is_piece_attack_square(PAWN, color, src, enpassant))
+ const Square enpassant = board.get_enpassant();
+ if (enpassant != Square::no_sq && board.is_piece_attack_square(PAWN, color, src, enpassant))
list.emplace_back(src, enpassant, Move::ENPASSANT);
}
@@ -66,10 +65,10 @@ void MoveList::generate(const Board &board, bool attacks_only) {
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);
+ const auto src = static_cast<Square>(src_i);
U64 attack = board.get_bitboard_piece_moves(type, color, src);
bitboard_for_each_bit(tgt_i, attack) {
- const auto tgt = static_cast<square::Square>(tgt_i);
+ const auto tgt = static_cast<Square>(tgt_i);
if (board.is_square_occupied(tgt)) {
list.emplace_back(src, tgt, Move::CAPTURE);
} else {
@@ -83,34 +82,32 @@ void MoveList::generate(const Board &board, bool attacks_only) {
if (attacks_only) return;
// Castling
- if (color == color::WHITE) {
- if (!board.is_square_attacked(square::e1, color::BLACK)) {
+ if (color == WHITE) {
+ if (!board.is_square_attacked(Square::e1, BLACK)) {
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.is_square_occupied(Square::f1) && !board.is_square_occupied(Square::g1) &&
+ !board.is_square_attacked(Square::f1, BLACK))
+ list.emplace_back(Square::e1, Square::g1, Move::CASTLEK);
}
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) &&
- !board.is_square_attacked(square::c1, color::BLACK))
- list.emplace_back(square::e1, square::c1, Move::CASTLEQ);
+ 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, BLACK) &&
+ !board.is_square_attacked(Square::c1, BLACK))
+ list.emplace_back(Square::e1, Square::c1, Move::CASTLEQ);
}
}
} else {
- if (!board.is_square_attacked(square::e8, color::WHITE)) {
+ if (!board.is_square_attacked(Square::e8, WHITE)) {
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.is_square_occupied(Square::f8) && !board.is_square_occupied(Square::g8) &&
+ !board.is_square_attacked(Square::f8, WHITE))
+ list.emplace_back(Square::e8, Square::g8, Move::CASTLEK);
}
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) &&
- !board.is_square_attacked(square::c8, color::WHITE))
- list.emplace_back(square::e8, square::c8, Move::CASTLEQ);
+ 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, WHITE) &&
+ !board.is_square_attacked(Square::c8, WHITE))
+ list.emplace_back(Square::e8, Square::c8, Move::CASTLEQ);
}
}
}
diff --git a/src/move/movelist.hpp b/src/move/movelist.hpp
@@ -21,7 +21,7 @@ class MoveList {
if (!legal) return;
int size = 0;
- for (const auto& move : list) {
+ for (const auto &move : list) {
Board copy = board;
if (move.make(copy)) list[size++] = move;
}
diff --git a/src/perft/perft.cpp b/src/perft/perft.cpp
@@ -12,7 +12,7 @@
#define tricky_position "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1 "
enum {
-THREAD_MAX = 64
+ THREAD_MAX = 64
};
class Perft {
@@ -68,8 +68,7 @@ class Perft {
Board copy = board;
if (!list[i].make(copy)) continue;
// debug(board, list[i], copy);
- if (depth != 1)
- test(copy, depth - 1);
+ if (depth != 1) test(copy, depth - 1);
else
score(copy, list[i]);
}
diff --git a/src/piece/piece.hpp b/src/piece/piece.hpp
@@ -1,10 +1,10 @@
#ifndef STELLAR_PIECE_H
#define STELLAR_PIECE_H
-#include "color.hpp"
#include "utils.hpp"
#include <cctype>
+#include <exception>
namespace piece {
@@ -23,42 +23,40 @@ ENABLE_INCR_OPERATORS_ON(Type)
struct Piece {
const uint8_t index;
const Type type;
- const color::Color color;
+ const Color color;
const char code;
};
inline constexpr const Piece table[2][6] = {
// clang-format off
{
- { .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 = 0, .type = PAWN, .color = WHITE, .code = 'P' },
+ { .index = 1, .type = KNIGHT, .color = WHITE, .code = 'N' },
+ { .index = 2, .type = BISHOP, .color = WHITE, .code = 'B' },
+ { .index = 3, .type = ROOK, .color = WHITE, .code = 'R' },
+ { .index = 4, .type = QUEEN, .color = WHITE, .code = 'Q' },
+ { .index = 5, .type = KING, .color = WHITE, .code = 'K' },
}, {
- { .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' },
+ { .index = 6, .type = PAWN, .color = BLACK, .code = 'p' },
+ { .index = 7, .type = KNIGHT, .color = BLACK, .code = 'n' },
+ { .index = 8, .type = BISHOP, .color = BLACK, .code = 'b' },
+ { .index = 9, .type = ROOK, .color = BLACK, .code = 'r' },
+ {.index = 10, .type = QUEEN, .color = BLACK, .code = 'q' },
+ {.index = 11, .type = KING, .color = BLACK, .code = 'k' },
},
// clang-format on
};
-inline constexpr const Piece &get(const Type type, const color::Color color) { return table[color][type]; }
+inline constexpr const Piece &get(const Type type, const Color color) { return table[color][type]; }
-inline constexpr const char get_code(const Type type, const color::Color color = color::BLACK) {
+inline constexpr const char get_code(const Type type, const Color color = BLACK) {
return get(type, color).code;
}
-inline constexpr const U64 get_index(const Type type, const color::Color color) {
- return get(type, color).index;
-}
+inline constexpr const U64 get_index(const Type type, const Color color) { return get(type, color).index; }
inline constexpr const Piece &get_from_code(const char code) {
- color::Color color = isupper(code) ? color::WHITE : color::BLACK;
+ Color color = isupper(code) ? WHITE : BLACK;
for (Type type = PAWN; type <= KING; ++type) {
const Piece &piece = get(type, color);
diff --git a/src/utils/color.hpp b/src/utils/color.hpp
@@ -1,20 +0,0 @@
-#ifndef STELLAR_COLOR_H
-#define STELLAR_COLOR_H
-
-#include <string>
-
-namespace color {
-
-enum Color {
- WHITE = 0,
- BLACK
-};
-
-inline constexpr const Color other(const Color color) { return color == WHITE ? BLACK : WHITE; }
-inline constexpr const std::string to_string(const Color color) {
- return std::string(color == WHITE ? "white" : "black");
-}
-
-} // namespace color
-
-#endif
diff --git a/src/utils/repetition.hpp b/src/utils/repetition.hpp
@@ -1,6 +1,11 @@
#ifndef STELLAR_REPETITION_H
#define STELLAR_REPETITION_H
+#include <iostream>
+#include <vector>
+
+#include "utils.hpp"
+
namespace repetition {
class Table {
diff --git a/src/utils/square.hpp b/src/utils/square.hpp
@@ -1,61 +0,0 @@
-#ifndef STELLAR_SQUARE_H
-#define STELLAR_SQUARE_H
-
-#include "utils.hpp"
-#include <string>
-
-namespace square {
-
-enum Square : int {
- // clang-format off
- a1, b1, c1, d1, e1, f1, g1, h1,
- a2, b2, c2, d2, e2, f2, g2, h2,
- a3, b3, c3, d3, e3, f3, g3, h3,
- a4, b4, c4, d4, e4, f4, g4, h4,
- a5, b5, c5, d5, e5, f5, g5, h5,
- a6, b6, c6, d6, e6, f6, g6, h6,
- a7, b7, c7, d7, e7, f7, g7, h7,
- a8, b8, c8, d8, e8, f8, g8, h8, no_sq
- // clang-format on
-};
-
-ENABLE_INCR_OPERATORS_ON(Square)
-
-inline constexpr const Square mirror_array[]{
- // clang-format off
- a8, b8, c8, d8, e8, f8, g8, h8,
- a7, b7, c7, d7, e7, f7, g7, h7,
- a6, b6, c6, d6, e6, f6, g6, h6,
- a5, b5, c5, d5, e5, f5, g5, h5,
- a4, b4, c4, d4, e4, f4, g4, h4,
- a3, b3, c3, d3, e3, f3, g3, h3,
- a2, b2, c2, d2, e2, f2, g2, h2,
- a1, b1, c1, d1, e1, f1, g1, h1, no_sq
- // clang-format on
-};
-
-inline constexpr const char *coordinates_array[] = {
- // clang-format off
- "a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1",
- "a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2",
- "a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3",
- "a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4",
- "a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5",
- "a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6",
- "a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7",
- "a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8", " "
- // clang-format on
-};
-
-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[square]; }
-
-inline const Square from_coordinates(const std::string &cord) {
- return static_cast<Square>((cord[1] - '1') * 8 + (cord[0] - 'a'));
-}
-
-} // namespace square
-
-#endif
diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp
@@ -1,5 +1,5 @@
-#ifndef STELLAR_UTILS_CPP_H
-#define STELLAR_UTILS_CPP_H
+#ifndef STELLAR_UTILS_HPP
+#define STELLAR_UTILS_HPP
#include <cstdint>
@@ -13,4 +13,48 @@ typedef uint32_t U32;
inline T &operator++(T &d) { return d = T(int(d) + 1); } \
inline T &operator--(T &d) { return d = T(int(d) - 1); }
+/* Color */
+
+enum Color {
+ WHITE,
+ BLACK,
+ COLOR_NB = 2
+};
+
+inline constexpr const Color other(const Color color) { return color == WHITE ? BLACK : WHITE; }
+
+/* Square */
+
+enum Square : int {
+ // clang-format off
+ a1, b1, c1, d1, e1, f1, g1, h1,
+ a2, b2, c2, d2, e2, f2, g2, h2,
+ a3, b3, c3, d3, e3, f3, g3, h3,
+ a4, b4, c4, d4, e4, f4, g4, h4,
+ a5, b5, c5, d5, e5, f5, g5, h5,
+ a6, b6, c6, d6, e6, f6, g6, h6,
+ a7, b7, c7, d7, e7, f7, g7, h7,
+ a8, b8, c8, d8, e8, f8, g8, h8, no_sq
+ // clang-format on
+};
+
+ENABLE_INCR_OPERATORS_ON(Square)
+
+constexpr const Square mirror_array[]{
+ // clang-format off
+ a8, b8, c8, d8, e8, f8, g8, h8,
+ a7, b7, c7, d7, e7, f7, g7, h7,
+ a6, b6, c6, d6, e6, f6, g6, h6,
+ a5, b5, c5, d5, e5, f5, g5, h5,
+ a4, b4, c4, d4, e4, f4, g4, h4,
+ a3, b3, c3, d3, e3, f3, g3, h3,
+ a2, b2, c2, d2, e2, f2, g2, h2,
+ a1, b1, c1, d1, e1, f1, g1, h1, no_sq
+ // clang-format on
+};
+
+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]; }
+
#endif
diff --git a/src/utils/utils_ui.hpp b/src/utils/utils_ui.hpp
@@ -0,0 +1,35 @@
+#ifndef STELLAR_UTILS_UI_HPP
+#define STELLAR_UTILS_UI_HPP
+
+#include <string>
+
+#include "utils.hpp"
+
+/* Color */
+
+constexpr const std::string to_string(const Color color) {
+ return std::string(color == WHITE ? "white" : "black");
+}
+
+/* Square */
+
+constexpr const char *coordinates_array[] = {
+ // clang-format off
+ "a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1",
+ "a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2",
+ "a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3",
+ "a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4",
+ "a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5",
+ "a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6",
+ "a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7",
+ "a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8", " "
+ // clang-format on
+};
+
+constexpr const std::string to_coordinates(const Square square) { return coordinates_array[square]; }
+
+constexpr Square from_coordinates(const std::string &cord) {
+ return static_cast<Square>((cord[1] - '1') * 8 + (cord[0] - 'a'));
+}
+
+#endif