commit 478983d07da27cc277fef32f73a65f5de5631f1a
parent c36cee0f9d0031a7c068cab56947327f2a199c1e
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Mon, 28 Aug 2023 21:34:58 +0200
Restructure engine
Diffstat:
8 files changed, 85 insertions(+), 89 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -3,7 +3,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(
Stellar
- VERSION 0.0.23
+ VERSION 0.0.24
DESCRIPTION "Chess engine written in C"
HOMEPAGE_URL https://git.dimitrijedobrota.com/stellar.git
LANGUAGES C CXX
diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt
@@ -1,6 +1,5 @@
add_executable(engine
engine.cpp
- transposition.cpp
uci.cpp
)
@@ -12,6 +11,13 @@ target_link_libraries(engine
PRIVATE utils
)
+stellar_target_precompile_headers(board
+ PRIVATE "board.hpp"
+ PRIVATE "move.hpp"
+ PRIVATE "movelist.hpp"
+ PRIVATE "piece.hpp"
+)
+
set_target_properties(engine PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
@@ -10,7 +10,6 @@
#include "movelist.hpp"
#include "piece.hpp"
#include "score.hpp"
-#include "transposition.hpp"
#include "uci.hpp"
#include "utils.hpp"
@@ -23,8 +22,62 @@
namespace engine {
+struct Hashe {
+ enum class Flag : uint8_t {
+ Exact,
+ Alpha,
+ Beta
+ };
+ U64 key;
+ Move best;
+ uint8_t depth;
+ int16_t score;
+ Flag flag;
+};
+
+class TTable {
+ public:
+ static inline constexpr const uint16_t unknown = 32500;
+
+ TTable() {}
+ TTable(U64 size) : table(size, {0}) {}
+
+ void clear() { table.clear(); };
+ int16_t read(const Board &board, int ply, Move *best, int16_t alpha, int16_t beta, uint8_t depth) const {
+ U64 hash = board.get_hash();
+ const Hashe &phashe = table[hash % table.size()];
+ if (phashe.key == hash) {
+ if (phashe.depth >= depth) {
+ int16_t score = phashe.score;
+
+ if (score < -MATE_SCORE) score += ply;
+ if (score > MATE_SCORE) score -= ply;
+
+ if (phashe.flag == Hashe::Flag::Exact) return score;
+ if ((phashe.flag == Hashe::Flag::Alpha) && (score <= alpha)) return alpha;
+ if ((phashe.flag == Hashe::Flag::Beta) && (score >= beta)) return beta;
+ }
+ *best = phashe.best;
+ }
+ return unknown;
+ }
+
+ void write(const Board &board, int ply, Move best, int16_t score, uint8_t depth, Hashe::Flag flag) {
+ U64 hash = board.get_hash();
+ Hashe &phashe = table[hash % table.size()];
+
+ if (score < -MATE_SCORE) score += ply;
+ if (score > MATE_SCORE) score -= ply;
+
+ phashe = {hash, best, depth, score, flag};
+ }
+
+ private:
+ std::vector<Hashe> table;
+};
+
Board board;
-TTable ttable(C64(0x400000));
+TTable ttable;
Move pv_table[MAX_PLY][MAX_PLY];
Move killer[2][MAX_PLY];
U32 history[12][64];
@@ -130,7 +183,7 @@ void stats_pv_store(Move move) {
pv_length[ply] = pv_length[ply + 1];
}
-int quiescence(int alpha, int beta) {
+int quiescence(int16_t alpha, int16_t beta) {
pv_length[ply] = ply;
nodes++;
@@ -159,9 +212,9 @@ int quiescence(int alpha, int beta) {
return alpha;
}
-int negamax(int alpha, int beta, uint8_t depth, bool null) {
+int negamax(int16_t alpha, int16_t beta, uint8_t depth, bool null) {
int pv_node = (beta - alpha) > 1;
- HasheFlag flag = HasheFlag::Alpha;
+ Hashe::Flag flag = Hashe::Flag::Alpha;
int futility = 0;
Move bestMove;
Board copy;
@@ -169,7 +222,7 @@ int negamax(int alpha, int beta, uint8_t depth, bool null) {
pv_length[ply] = ply;
int score = ttable.read(board, ply, &bestMove, alpha, beta, depth);
- if (ply && score != TTABLE_UNKNOWN && !pv_node) return score;
+ if (ply && score != TTable::unknown && !pv_node) return score;
// && fifty >= 100
if (ply && is_repetition()) return 0;
@@ -280,12 +333,12 @@ int negamax(int alpha, int beta, uint8_t depth, bool null) {
}
alpha = score;
- flag = HasheFlag::Exact;
+ flag = Hashe::Flag::Exact;
bestMove = move;
stats_pv_store(move);
if (score >= beta) {
- ttable.write(board, ply, bestMove, beta, depth, HasheFlag::Beta);
+ ttable.write(board, ply, bestMove, beta, depth, Hashe::Flag::Beta);
if (!move.is_capture()) {
killer[1][ply] = killer[0][ply];
@@ -309,10 +362,20 @@ int negamax(int alpha, int beta, uint8_t depth, bool null) {
}
void search_position(const uci::Settings &setting) {
- int alpha = -SCORE_INFINITY, beta = SCORE_INFINITY;
+ int16_t alpha = -SCORE_INFINITY, beta = SCORE_INFINITY;
+ if (setting.newgame) {
+ ttable = TTable(C64(0x400000));
+ }
+
+ ply = 0;
nodes = 0;
board = setting.board;
+ memset(killer, 0x00, sizeof(killer));
+ memset(history, 0x00, sizeof(history));
+ memset(pv_table, 0x00, sizeof(pv_table));
+ memset(pv_length, 0x00, sizeof(pv_length));
+
for (uint8_t depth_crnt = 1; depth_crnt <= setting.depth;) {
follow_pv = 1;
diff --git a/src/engine/score.hpp b/src/engine/score.hpp
@@ -1,8 +1,8 @@
#ifndef STELLAR_SCORE_H
#define STELLAR_SCORE_H
-#define SCORE_INFINITY 50000
-#define MATE_VALUE 49000
-#define MATE_SCORE 48000
+#define SCORE_INFINITY 32000
+#define MATE_VALUE 31000
+#define MATE_SCORE 30000
#endif
diff --git a/src/engine/transposition.cpp b/src/engine/transposition.cpp
@@ -1,34 +0,0 @@
-#include "transposition.hpp"
-#include "board.hpp"
-#include "score.hpp"
-
-int TTable::read(const Board &board, int ply, Move *best, int alpha, int beta, uint8_t depth) const {
-
- U64 hash = board.get_hash();
- const Hashe &phashe = table[hash % table.size()];
- if (phashe.key == hash) {
- if (phashe.depth >= depth) {
- int score = phashe.score;
-
- if (score < -MATE_SCORE) score += ply;
- if (score > MATE_SCORE) score -= ply;
-
- if (phashe.flag == HasheFlag::Exact) return score;
- if ((phashe.flag == HasheFlag::Alpha) && (score <= alpha)) return alpha;
- if ((phashe.flag == HasheFlag::Beta) && (score >= beta)) return beta;
- }
- *best = phashe.best;
- }
- return TTABLE_UNKNOWN;
-}
-
-void TTable::write(const Board &board, int ply, Move best, int score, uint8_t depth, HasheFlag flag) {
-
- U64 hash = board.get_hash();
- Hashe &phashe = table[hash % table.size()];
-
- if (score < -MATE_SCORE) score += ply;
- if (score > MATE_SCORE) score -= ply;
-
- phashe = {hash, best, depth, score, flag};
-}
diff --git a/src/engine/transposition.hpp b/src/engine/transposition.hpp
@@ -1,41 +0,0 @@
-#ifndef STELLAR_TRANSPOSITION_H
-#define STELLAR_TRANSPOSITION_H
-
-#include "move.hpp"
-#include "utils.hpp"
-
-#include <vector>
-
-#define TTABLE_UNKNOWN 100000
-
-#define T TTable
-
-enum class HasheFlag : uint8_t {
- Exact,
- Alpha,
- Beta
-};
-
-typedef struct Hashe Hashe;
-struct Hashe {
- U64 key;
- Move best;
- uint8_t depth;
- int score;
- HasheFlag flag;
-};
-
-class TTable {
- public:
- TTable(U64 size) : table(size, {0}) {}
-
- void clear() { table.clear(); };
- int read(const Board &board, int ply, Move *best, int alpha, int beta, uint8_t depth) const;
- void write(const Board &board, int ply, Move best, int score, uint8_t depth, HasheFlag flag);
-
- private:
- std::vector<Hashe> table;
-};
-
-#undef T
-#endif
diff --git a/src/engine/uci.cpp b/src/engine/uci.cpp
@@ -101,6 +101,7 @@ void loop(void) {
}
}
engine::search_position(settings);
+ settings.newgame = false;
}
}
}
diff --git a/src/engine/uci.hpp b/src/engine/uci.hpp
@@ -22,6 +22,7 @@ struct Settings {
bool debug = false;
bool mate = false;
bool infinite = false;
+ bool newgame = true;
};
void loop(void);