47 std::vector<std::string> supported_values;
62 void dispose_content_internal() {
63 T* view = (T*)content;
67 void dispose_content();
69 void* deep_copy_content()
const;
71 Option() : id_(
"<empty>"), type_(Button), content(nullptr) {};
72 Option(std::string
id) : id_(id), type_(Button), content(nullptr) {};
73 Option(std::string
id,
bool value) : id_(id), type_(Check), content(new bool(value)) {};
74 Option(std::string
id, std::string value) : id_(id), type_(String), content(new std::string(value)) {};
75 Option(std::string
id,
const char* value) : id_(id), type_(String), content(new std::string(value)) {};
76 Option(std::string
id,
const spin_option& content) : id_(id), type_(Spin), content(new spin_option(content)) {};
77 Option(std::string
id,
const combo_option& content) : id_(id), type_(Combo), content(new combo_option(content)) {};
78 Option(
const Option& other) : id_(other.id_), type_(other.type_), content(other.deep_copy_content()) {};
79 Option(Option&& other) noexcept : id_(other.id_), type_(other.type_), content(other.content) { other.content =
nullptr; other.type_ = Button; };
80 ~Option() { dispose_content(); };
82 const OptionType& type()
const {
return type_; };
83 const std::string& id()
const {
return id_; };
85 std::string& str_content() {
return *(std::string*)content; };
86 const std::string& str_content()
const {
return *(std::string*)content; };
88 bool& check_content() {
return *(
bool*)content; };
89 const bool& check_content()
const {
return *(
bool*)content; };
91 spin_option& spin_content() {
return *(spin_option*)content; };
92 const spin_option& spin_content()
const {
return *(spin_option*)content; };
94 combo_option& combo_content() {
return *(combo_option*)content; };
95 const combo_option& combo_content()
const {
return *(combo_option*)content; };
97 Option& operator=(
const Option& other) {
101 content = other.deep_copy_content();
125 UciScore(BoundType _boundType, Unit unit, int32_t value) : _type(_boundType), _unit(unit), _value(value) {};
126 UciScore(
const UciScore& other) : _type(other._type), _unit(other._unit), _value(other._value) {};
128 static UciScore fromCentipawns(int32_t v, BoundType _type = Exact) {
129 return UciScore(_type, Centipawn, v);
132 static UciScore fromMateDistance(int32_t v, BoundType _type = Exact) {
133 return UciScore(_type, Mate, v);
136 const BoundType& getBoundType()
const {
return _type; };
137 const Unit& getUnit()
const {
return _unit; };
138 const int32_t getValue()
const {
return _value; };
142 class RefutationInfo {
144 std::vector<Move> refutationLine;
146 template<
class MoveIterator>
147 RefutationInfo(
const Move& m, MoveIterator ref_begin, MoveIterator ref_end) {
149 MoveIterator it = ref_begin;
150 while (it != ref_end) {
151 refutationLine.push_back(*it);
155 RefutationInfo(
const RefutationInfo& other) : refutedMove(other.refutedMove), refutationLine(other.refutationLine) {};
156 const Move& getRefutedMove()
const {
return refutedMove; };
157 const std::vector<Move>& getRefutationLine()
const {
return refutationLine; };
158 RefutationInfo& operator= (
const RefutationInfo& other) {
159 this->refutedMove = other.refutedMove;
160 this->refutationLine.clear();
161 this->refutationLine.insert(this->refutationLine.begin(), other.refutationLine.begin(), other.refutationLine.end());
164 template <
class Move>
165 class CurrentLineInfo {
167 std::vector<Move> currentLine;
169 template <
class MoveIterator>
170 CurrentLineInfo(
const int32_t& cpunr, MoveIterator line_begin, MoveIterator line_end) : cpunr(cpunr) {
171 MoveIterator it = line_begin;
172 while (it != line_end) {
173 currentLine.push_back(*it);
177 CurrentLineInfo(
const CurrentLineInfo& other) : cpunr(other.cpunr), currentLine(other.currentLine) {};
179 const std::vector<Move>& getCurrentLine()
const {
return currentLine; };
180 const int32_t& getCPUnr()
const {
return cpunr; };
182 CurrentLineInfo& operator= (
const CurrentLineInfo& other) {
183 this->cpunr = other.cpunr;
184 this->currentLine.clear();
185 this->currentLine.insert(this->currentLine.begin(), other.currentLine.begin(), other.currentLine.end());
189 template <
class Move>
198 _ContentType(
const int32_t & v) {
202 _ContentType(
const UciScore & s) {
207 std::string stringContent;
208 std::vector<Move> moveArray;
211 _ContentType content;
214 Info(InfoType tp,
const int32_t & type,
const std::string& value,
const std::vector<Move>& moveArray) : _type(tp), content(type),
215 stringContent(value), moveArray(moveArray) {};
216 Info(InfoType tp,
const UciScore& type,
const std::string& value,
const std::vector<Move>& moveArray) : _type(tp), content(type),
217 stringContent(value), moveArray(moveArray) {
219 Info(
const RefutationInfo<Move>& refInfo) : _type(Refutation), content(0), stringContent(
"") {
220 moveArray.push_back(refInfo.getRefutedMove());
221 auto it = refInfo.getRefutationLine().cbegin();
222 while (it != refInfo.getRefutationLine().cend()) {
223 moveArray.push_back(*it);
227 Info(
const CurrentLineInfo<Move>& currLineInfo) : _type(CurrentLine), content(currLineInfo.getCPUnr()), stringContent(
""), moveArray(currLineInfo.getCurrentLine()) {};
228 Info(
const Info& other) : _type(other._type), content(int32_t(0)), stringContent(other.stringContent), moveArray(other.moveArray) {
229 if (_type == InfoType::Score)
230 content.score = other.content.score;
232 content.integer = other.content.integer;
235 const InfoType getType()
const {
return _type; };
236 const int32_t& getIntegerValue()
const {
return content.integer; };
237 const UciScore getAsScore()
const {
return content.score; };
238 const std::string& getStringValue()
const {
return stringContent; };
239 const std::vector<Move> getMoveArray()
const {
return moveArray; };
240 const Move& getAsCurrentMoveInfo()
const {
return moveArray[0]; };
241 RefutationInfo<Move> getAsRefutationInfo()
const {
242 auto it = moveArray.cbegin();
244 return RefutationInfo<Move>(moveArray[0], it, moveArray.cend()); }
245 CurrentLineInfo<Move> getAsCurrentLineInfo()
const {
return CurrentLineInfo<Move>(getIntegerValue(), moveArray.cbegin(), moveArray.cend()); }
250 #define INTEGER_INFO_FACTORY_METHOD(tp) static Info<Move> make##tp##Info(int32_t value) {return makeIntegerInfo(value, tp);}
251 template <
class Move>
253 static Info<Move> makeIntegerInfo(int32_t value, InfoType type) {
254 return Info<Move>(type, { value },
"", {});
257 INTEGER_INFO_FACTORY_METHOD(Depth);
258 INTEGER_INFO_FACTORY_METHOD(Seldepth);
259 INTEGER_INFO_FACTORY_METHOD(Time);
260 INTEGER_INFO_FACTORY_METHOD(Nodes);
261 INTEGER_INFO_FACTORY_METHOD(MultiPv);
262 INTEGER_INFO_FACTORY_METHOD(CurrentMoveNumber);
263 INTEGER_INFO_FACTORY_METHOD(Hashfull);
264 INTEGER_INFO_FACTORY_METHOD(NodesPerSecond);
265 INTEGER_INFO_FACTORY_METHOD(Tbhiths);
266 INTEGER_INFO_FACTORY_METHOD(Sbhits);
267 INTEGER_INFO_FACTORY_METHOD(CPUload);
269 static Info<Move> makeStringInfo(
const std::string& value) {
270 return Info<Move>(InfoString, { 0 }, value, {});
273 static Info<Move> makePvInfo(
const std::vector<Move>& line) {
274 return Info<Move>(Pv, { 0 },
"", line);
277 static Info<Move> makeRefutationInfo(
const Move& m,
const std::vector<Move>& refutation) {
278 return Info<Move>(RefutationInfo<Move>(m, refutation.begin(), refutation.end()));
281 static Info<Move> makeCurrLineInfo(
const std::vector<Move>& m, int32_t cpunr = 1) {
282 CurrentLineInfo<Move> currL(cpunr, m.begin(), m.end());
283 return Info<Move>(CurrentLineInfo<Move>(currL));
286 static Info<Move> makeCurrentMoveInfo(
const Move& m) {
287 std::vector<Move> vec = { m };
288 return Info<Move>(CurrentMove, { 0 },
"", vec);
291 static Info<Move> makeScoreInfo(
const UciScore& score) {
292 return Info<Move>(Score, score ,
"", {});
296 #undef INTEGER_INFO_FACTORY_METHOD
297 template <
class Move>
298 class AbstractEngineHandler {
300 ~AbstractEngineHandler() {};
302 virtual void onEngineName(
const std::string& name) = 0;
303 virtual void onEngineAuthor(
const std::string& author) = 0;
304 virtual void onUCIOK() = 0;
305 virtual void onReadyOK() = 0;
306 virtual void onBestMove(
const Move& bestMove) = 0;
307 virtual void onBestMove(
const Move& bestMove,
const Move& ponderMove) = 0;
308 virtual void onInfo(
const std::vector<Info<Move>>& infos) = 0;
309 virtual void onCopyProtection(ProcedureStatus status) = 0;
310 virtual void onRegistration(ProcedureStatus status) = 0;
311 virtual void onOption(
const Option& option) = 0;
312 virtual void onError(
const std::string& errorMsg) = 0;
322 std::vector<Move> SearchMoves;
326 unsigned int BlackTime;
327 unsigned int BlackIncrement;
328 unsigned int WhiteTime;
329 unsigned int WhiteIncrement;
330 unsigned int MovesToGo;
334 unsigned int MoveTime;
337 #define SELF GoParamsBuilder<Move>
338 #define WITH_INTEGER_VALUE(member_name) SELF& with##member_name (unsigned int v) {this->result.member_name = v; return *this;}
339 template <
class Move>
340 class GoParamsBuilder {
341 GoParams<Move> result;
345 SELF& withSearchMoves(
const std::vector<Move>& moves) { this->result.SearchMoves = moves;
return *
this; };
346 WITH_INTEGER_VALUE(MoveTime);
347 WITH_INTEGER_VALUE(MovesToGo);
348 WITH_INTEGER_VALUE(Depth);
349 WITH_INTEGER_VALUE(Nodes);
350 WITH_INTEGER_VALUE(Mate);
351 SELF& withWhiteTime(
unsigned int time,
unsigned int inc) { this->result.WhiteTime = time; this->result.WhiteIncrement = inc;
return *
this; }
352 SELF& withBlackTime(
unsigned int time,
unsigned int inc) { this->result.BlackTime = time; this->result.BlackIncrement = inc;
return *
this; }
353 SELF& withPondering(
bool v) { this->result.Ponder = v;
return *
this; }
354 SELF& withInfiniteMode(
bool v) { this->result.Infinite = v;
return *
this; }
355 GoParams<Move> build()
const {
return result; };
357 #undef WITH_INTEGER_VALUE
365 virtual std::string toFen()
const = 0;
366 virtual std::string toPositionString()
const = 0;
369 std::string formatSetOptionCommand(
const Option & option);
372 #define SingleTokenCommand(command) static std::string command() {return std::string(#command) + '\n' ;};
378 static std::string(*MoveFormatter)(
const Move& m);
380 SingleTokenCommand(uci);
381 SingleTokenCommand(isready);
382 SingleTokenCommand(ponderhit);
383 SingleTokenCommand(stop);
384 SingleTokenCommand(quit);
385 static std::string debug(
bool b) {
return b ?
"debug on\n" :
"debug off\n"; }
386 static std::string registerLater() {
return "register later\n"; };
387 static std::string registerEngine(std::string name, std::string code) {
return "register name " + name +
" code " + code +
"\n"; }
388 static std::string position(
const PositionFormatter & pos , std::vector<Move> moves = {});
389 static std::string go(
const GoParams<Move>& params);
390 static std::string setOpion(
const Option& option);
393 #undef SingleTokenCommand
396 inline std::string UciFormatter<Move>::position(
const PositionFormatter& pos, std::vector<Move> moves)
398 std::string result =
"position " + pos.toPositionString();
400 if (!moves.empty()) {
403 for (
const Move& m : moves)
404 result += MoveFormatter(m) +
" ";
413 #define UCI_ADD_IF_NO_ZERO(member_name, uci_name) if(params.member_name) result += std::string(#uci_name) + " " + std::to_string(params.member_name) + " ";
415 inline std::string UciFormatter<Move>::go(
const GoParams<Move>& params)
417 std::string result =
"go ";
419 UCI_ADD_IF_NO_ZERO(WhiteTime, wtime);
420 UCI_ADD_IF_NO_ZERO(WhiteIncrement, winc);
421 UCI_ADD_IF_NO_ZERO(BlackTime, btime);
422 UCI_ADD_IF_NO_ZERO(BlackIncrement, binc);
423 UCI_ADD_IF_NO_ZERO(MovesToGo, movestogo);
424 UCI_ADD_IF_NO_ZERO(Depth, depth);
425 UCI_ADD_IF_NO_ZERO(Nodes, nodes);
426 UCI_ADD_IF_NO_ZERO(Mate, mate);
427 UCI_ADD_IF_NO_ZERO(MoveTime, movetime);
429 if (params.Ponder) result +=
"ponder ";
430 if (params.Infinite) result +=
"infinite ";
432 if (params.SearchMoves.size()) {
433 result +=
"searchmoves ";
434 for (
const Move& m : params.SearchMoves) {
435 result += MoveFormatter(m);
436 result.push_back(
' ');
441 result.push_back(
'\n');
444 #undef UCI_ADD_IF_NO_ZERO
447 inline std::string UciFormatter<Move>::setOpion(
const Option& option)
449 return formatSetOptionCommand(option);
453 inline GoParamsBuilder<Move>::GoParamsBuilder()
455 result.BlackIncrement = result.WhiteIncrement = 0u;
456 result.BlackTime = result.WhiteTime = 0u;
457 result.Depth = result.Mate = result.Nodes = result.MoveTime = result.MovesToGo = 0u;
458 result.Infinite = result.Ponder =
false;