BenBot 1.7.5
A chess engine
Loading...
Searching...
No Matches
Engine.hpp
Go to the documentation of this file.
1/*
2 * ======================================================================================
3 *
4 * ░▒▓███████▓▒░░▒▓████████▓▒░▒▓███████▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░▒▓████████▓▒░
5 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
6 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
7 * ░▒▓███████▓▒░░▒▓██████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
8 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
9 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
10 * ░▒▓███████▓▒░░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░
11 *
12 * ======================================================================================
13 */
14
19
20#pragma once
21
22#include <array>
23#include <filesystem>
24#include <functional>
29#include <span>
30#include <string>
31#include <string_view>
32
33namespace chess::uci {
34struct GoCommandOptions;
35} // namespace chess::uci
36
37namespace ben_bot {
38
39namespace uci = chess::uci;
40
41using chess::game::Position;
42using chess::moves::Move;
43using std::string_view;
45
49class [[nodiscard]] Engine final : public uci::EngineBase {
50public:
51 Engine() = default;
52
53 ~Engine() override = default;
54
55 Engine(const Engine&) = delete;
56 Engine& operator=(const Engine&) = delete;
57
58 Engine(Engine&&) = delete;
59 Engine& operator=(Engine&&) = delete;
60
62 void read_config_file(const std::filesystem::path& file);
63
64private:
65 [[nodiscard]] auto get_name() const -> std::string override;
66 [[nodiscard]] auto get_author() const -> string_view override { return "Ben Vining"; }
67
68 void new_game(bool firstCall) override;
69
70 void set_position(const Position& pos) override { searcher.context.set_position(pos); }
71
72 void go(const uci::GoCommandOptions& opts) override;
73
74 void abort_search() override { searcher.context.abort(); }
75
76 void ponder_hit() override { searcher.context.ponder_hit(); }
77
78 void wait() override { searcher.context.wait(); }
79
80 auto is_searching() const noexcept -> bool override { return searcher.context.in_progress(); }
81
82 [[nodiscard]] auto get_custom_uci_options() noexcept -> OptionList override
83 {
84 return options;
85 }
86
87 [[nodiscard]] auto get_custom_uci_commands() const noexcept -> CommandList override
88 {
89 return customCommands;
90 }
91
92 void run_perft(string_view arguments) const;
93
94 void run_bench(string_view arguments) const;
95
96 void make_null_move();
97 void color_flip();
98
99 void print_logo_and_version() const;
100 void print_help(string_view args) const;
101 void print_options();
102 void print_current_position(string_view arguments) const;
103
104 void set_pretty_printing(bool shouldPrettyPrint);
105
106 [[nodiscard]] auto pretty_print_move(Move move) const -> std::string;
107
108 static void print_compiler_info();
109
110 static void start_file_logger(string_view arg);
111
112 void write_config_file(string_view arg) const;
113 void read_config_file(string_view arg);
114
115 [[nodiscard]] static auto create_move_format_option() -> uci::ComboOption;
116
117 void resize_transposition_table(const size_t sizeMB) override
118 {
119 searcher.context.resize_transposition_table(sizeMB);
120 }
121
122 void set_ponder(const bool shouldPonder) override
123 {
124 // the ponder flag is only ever turned on via the go options,
125 // but it can be turned off by disabling this UCI option
126 if (not shouldPonder)
127 searcher.context.set_pondering(false);
128 }
129
130 search::Thread searcher;
131
132 /* ----- UCI options ----- */
133
134 uci::Action clearTT {
135 "Clear Hash",
136 [this] { searcher.context.clear_transposition_table(); },
137 "Press to clear the transposition table."
138 };
139
140 uci::IntOption threads {
141 "Threads", 1, 1, 1,
142 "Number of searcher threads (currently a dummy)."
143 };
144
145 uci::IntOption moveOverhead {
146 "Move Overhead", 0, 5000, 10,
147 "Extra overhead time subtracted from search time (in ms). Increase this if engine loses on time."
148 };
149
150 uci::StringOption logFile {
151 "Debug Log File", "<empty>",
152 "If not empty, engine I/O will be mirrored to this file.",
154 };
155
156 uci::BoolOption prettyPrintMode {
157 "Pretty Print",
158 false,
159 "When on, search output is pretty-printed instead of printed in UCI format.",
160 [this](const bool usePretty) { set_pretty_printing(usePretty); }
161 };
162
163 uci::ComboOption moveFormat { create_move_format_option() };
164
165 uci::BoolOption sanitizePositions {
166 "Sanitize Positions",
167 false,
168 "When on, the engine checks if the position is legal before setting it.",
169 [this](const bool sanitize) { set_sanitize_positions(sanitize); }
170 };
171
172 std::array<uci::Option*, 7uz> options {
173 &clearTT, &threads, &moveOverhead, &logFile, &prettyPrintMode, &moveFormat, &sanitizePositions
174 };
175
176 std::array<EngineCommand, 10uz> customCommands {
177 EngineCommand {
178 .name = "showpos",
179 .action = [this](const string_view args) { print_current_position(args); },
180 .description = "Prints the current position",
181 .argsHelp = "[utf8]" },
182 EngineCommand {
183 .name = "makenull",
184 .action = EngineCommand::void_cb([this] { make_null_move(); }),
185 .description = "Play a null move on the internal board",
186 .argsHelp = { } },
187 EngineCommand {
188 .name = "flip",
189 .action = EngineCommand::void_cb([this] { color_flip(); }),
190 .description = "Color-flip the current position",
191 .argsHelp = { } },
192 EngineCommand {
193 .name = "options",
194 .action = EngineCommand::void_cb([this] { print_options(); }),
195 .description = "Dump current UCI option values",
196 .argsHelp = { } },
197 EngineCommand {
198 .name = "perft",
199 .action = [this](const string_view args) { run_perft(args); },
200 .description = "Computes perft of the current position to the given depth",
201 .argsHelp = "<N> [json]" },
202 EngineCommand {
203 .name = "bench",
204 .action = [this](const string_view args) { run_bench(args); },
205 .description = "Runs a search and reports total nodes and NPS",
206 .argsHelp = "[<depth>] [<epdPath>]" },
207 EngineCommand {
208 .name = "compiler",
209 .action = EngineCommand::void_cb([] { print_compiler_info(); }),
210 .description = "Print compiler info",
211 .argsHelp = { } },
212 EngineCommand {
213 .name = "writeconfig",
214 .action = [this](const string_view args) { write_config_file(args); },
215 .description = "Writes the engine's current state to a configuration file at the given path",
216 .argsHelp = "<path>" },
217 EngineCommand {
218 .name = "readconfig",
219 .action = [this](const string_view args) { read_config_file(args); },
220 .description = "Loads engine state from a configuration file at the given path",
221 .argsHelp = "<path>" },
222 EngineCommand {
223 .name = "help",
224 .action = [this](const string_view args) { print_help(args); },
225 .description = "Display this text",
226 .argsHelp = "[--no-logo]" }
227 };
228};
229
230} // namespace ben_bot
auto get_author() const -> string_view override
Definition Engine.hpp:66
auto get_custom_uci_commands() const noexcept -> CommandList override
Definition Engine.hpp:87
auto is_searching() const noexcept -> bool override
Definition Engine.hpp:80
void wait() override
Definition Engine.hpp:78
void new_game(bool firstCall) override
Engine & operator=(Engine &&)=delete
auto get_name() const -> std::string override
~Engine() override=default
Engine()=default
Engine(const Engine &)=delete
Engine & operator=(const Engine &)=delete
void resize_transposition_table(const size_t sizeMB) override
Definition Engine.hpp:117
void ponder_hit() override
Definition Engine.hpp:76
void set_position(const Position &pos) override
Definition Engine.hpp:70
void abort_search() override
Definition Engine.hpp:74
void read_config_file(const std::filesystem::path &file)
void go(const uci::GoCommandOptions &opts) override
void set_ponder(const bool shouldPonder) override
Definition Engine.hpp:122
auto get_custom_uci_options() noexcept -> OptionList override
Definition Engine.hpp:82
Engine(Engine &&)=delete
auto start_file_logger(const std::filesystem::path &logFile) -> std::expected< void, std::string >
std::span< const EngineCommand > CommandList
std::span< Option * > OptionList