stellar

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

commit 08c3d85ee37620b4cc000fb0123305c399af4b4c
parent 853218b1217d154545e1844f4022147d1c6d22e7
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Tue, 26 Mar 2024 21:11:08 +0000

Better time management and small improvements

Diffstat:
MCMakeLists.txt | 2+-
Msrc/arena/match.cpp | 13+++++++++----
Msrc/engine/engine.cpp | 1+
Msrc/engine/uci.cpp | 24+++++++++++++++---------
Msrc/move/movelist.hpp | 5+++--
Msrc/perft/perft.cpp | 1-
Msrc/random/random.hpp | 6++----
7 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) project( Stellar - VERSION 1.3.9 + VERSION 1.3.10 DESCRIPTION "Chess engine written in C++" HOMEPAGE_URL https://git.dimitrijedobrota.com/stellar.git LANGUAGES CXX diff --git a/src/arena/match.cpp b/src/arena/match.cpp @@ -3,6 +3,7 @@ #include "repetition.hpp" #include "timer.hpp" #include "utils_ui.hpp" +#include <algorithm> uint16_t Match::id_t = 0; Match::~Match() { logger::log(std::format("Match {}: destroyed", id), logger::Debug); } @@ -36,13 +37,14 @@ Game Match::play(Settings swhite, Settings sblack, const std::string &fen = Game engine->send(std::format("{} moves {}", position, game.get_moves())); engine->send(get_go(swhite, sblack, turn)); - uint64_t time_start = timer::get_ms(); - std::string response; + + uint64_t time_start = timer::get_ms(); while (true) { response = engine->receive(); if (response.starts_with("bestmove")) break; } + uint64_t time_passed = timer::get_ms() - time_start; std::string move_str = response.substr(9); if ((move = parse_move(list, move_str)) == Move() || !move.make(board)) { @@ -63,8 +65,7 @@ Game Match::play(Settings swhite, Settings sblack, const std::string &fen = Game if (!move.is_repeatable()) rtable.push_null(); game.play(move); - uint64_t time_passed = timer::get_ms() - time_start; - if (turn == WHITE ? swhite.time <= time_passed : sblack.time <= time_passed) { + if ((turn == WHITE ? swhite.time : sblack.time) <= time_passed) { logger::log(std::format("Match {}: {} timeout", id, to_string(turn))); game.set_terminate(Game::Timeout); game.set_winner(other(turn)); @@ -74,6 +75,9 @@ Game Match::play(Settings swhite, Settings sblack, const std::string &fen = Game if (turn == WHITE && !swhite.depth) swhite.time -= time_passed; if (turn == BLACK && !sblack.depth) sblack.time -= time_passed; + logger::log(std::format("Match {}: wtime: {}, btime: {}", id, swhite.time, sblack.time), + logger::Debug); + turn = other(turn); } @@ -104,6 +108,7 @@ std::string Match::get_go(Settings &swhite, Settings &sblack, Color side) { if (sblack.inc) go += " binc " + std::to_string(sblack.inc); if (swhite.movetime) go += " movetime " + std::to_string(sblack.movetime); } + return go; } diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp @@ -277,6 +277,7 @@ int16_t quiescence(int16_t alpha, int16_t beta) { uci::communicate(settings); if (settings->stopped) return 0; } + nodes++; int score = evaluate::score_position(board); diff --git a/src/engine/uci.cpp b/src/engine/uci.cpp @@ -1,3 +1,4 @@ +#include <algorithm> #include <iostream> #include <limits> #include <sstream> @@ -82,7 +83,7 @@ void loop() { } else if (command == "go") { settings.searchMoves.clear(); uint64_t wtime = 0, btime = 0, movetime = 0; - uint16_t winc = 0, binc = 0, movestogo = 60; + uint16_t winc = 0, binc = 0, movestogo = 40; while (iss >> command) { if (command == "wtime") iss >> wtime; @@ -114,20 +115,25 @@ void loop() { } } - settings.starttime = timer::get_ms(); - uint64_t time = (board.get_side() == WHITE) ? wtime : btime; + uint16_t time_left = board.get_side() == WHITE ? wtime : btime; + int64_t time = 0; if (movetime != 0) { time = movetime; movestogo = 1; - } else if (time != 0) { - uint16_t inc = (board.get_side() == WHITE) ? winc : binc; - time /= movestogo; - time -= 50; - settings.stoptime = settings.starttime + time + inc; + } else if (time_left != 0) { + uint16_t inc = board.get_side() == WHITE ? winc : binc; + time = time_left / movestogo + inc / 2; + if (time > time_left) time = time_left - 500; + if (time <= 0) time = 100; + settings.infinite = false; - } else + } else { settings.infinite = true; + } + + settings.starttime = timer::get_ms(); + settings.stoptime = settings.starttime + time; const Move best = engine::search_position(settings); std::cout << "bestmove " << best << '\n'; diff --git a/src/move/movelist.hpp b/src/move/movelist.hpp @@ -15,11 +15,12 @@ class MoveList { public: MoveList() : list(){}; - MoveList(const Board &board, bool attacks_only = false, bool legal = false) : list() { + MoveList(const Board &board, bool attacks_only = false) : list() { list.reserve(256); generate(board, attacks_only); - if (!legal) return; + } + MoveList(const Board &board, bool attacks_only, bool legal) : MoveList(board, attacks_only) { int size = 0; for (const auto &move : list) { Board copy = board; diff --git a/src/perft/perft.cpp b/src/perft/perft.cpp @@ -82,7 +82,6 @@ class Perft { void score(const Board &board, Move move) { local.node++; - std::cout << std::setw(16) << std::hex << board.get_hash() << std::endl; #ifdef USE_FULL_COUNT if (board.is_check()) local.check++; if (move.is_capture()) local.capture++; diff --git a/src/random/random.hpp b/src/random/random.hpp @@ -10,8 +10,6 @@ class Random { constexpr U64 operator()(void) { return get_U64(); } - constexpr void reset(void) { state = seed; } - constexpr U32 get_U32(void) { U32 number = state; @@ -34,8 +32,8 @@ class Random { } private: - static inline constexpr const U32 seed = C32(1804289383); - U32 state = seed; + static const U32 default_seed = C32(1804289383); + U32 state = default_seed; }; #endif