Belofte version 2.2.0
A promising chess program using the UCI or Winboard interface
engineinterface.cpp
Go to the documentation of this file.
1/*---------------------------------------------------------------------+
2 * File: engineinterface.cpp
3 * Project: part of belofte - A Promising Chess Program
4 * Author: yves
5 * SPDX-License-Identifier: GPL-2.0-only
6+----------------------------------------------------------------------*/
7
8#include "belofte.h"
9
10//-----------------------------------------------------------------------
11
12/**
13 * Common commands to all modes
14 * this ctor is called for each iface
15 */
16engineInterface::engineInterface(std::string&& n, std::string&& h)
17 : m_name{std::move(n)}
18 , m_hint{std::move(h)}
19 , m_allowedCommands{}
20{
21}
22
24{
25 m_allowedCommands.clear();
26 engineCommands_t::iterator itr = getEngineCommands().begin();
27 while (itr != getEngineCommands().end()) {
28 delete itr->second;
29 itr = getEngineCommands().erase(itr);
30 }
31 getEngineCommands().clear();
32}
33
34//-----------------------------------------------------------------------
35// global verbs valid in all cases
36//-----------------------------------------------------------------------
37
38void engineInterface::execute(std::string const& command, std::string const& params)
39{
40 if (command != "") {
41 if (getEngineCommands().find(command) != getEngineCommands().end()) {
43 v->execute(params);
44 } else {
45 if (App().getMode() != "xboard"
46 || !Game()->playGameMoveSeries(command)) {
47 /// @note in xboard mode, try to match command with list of possible moves
48 /// before raising unknown command
49 /// normally, accepting usermoves should only be done after
50 /// feature usermove=0 has been issued, this requirement is relaxed
51 sendError("unknown command, not executing",
52 command + (params.size() ? " <" + params + ">" : ""));
53 }
54 }
55 }
56}
57
58void engineInterface::initCommand(std::vector<engineUserCommand *> cmds)
59{
60 for (size_t i = 0; i < cmds.size(); ++i) {
61 if (getEngineCommands().find(cmds[i]->m_name) == getEngineCommands().end()) {
62 // do not initialize twice
63 getEngineCommands().insert(std::make_pair(cmds[i]->m_name, cmds[i]));
64 }
65 }
66}
67
69 bool const published)
70{
71 if (published) {
72 /// @todo fix: if not published, add command to list anyway
73 for (size_t i = 0; i < sCommands.size(); ++i) {
74 m_allowedCommands[sCommands[i]] = published;
75 }
76 }
77}
78
79/**
80 * Send help on command or all commands
81 * @param args --all means all commands, '' or a single command
82 * unsupported means all plus unsupported commands
83 * hidden means all plus hidden commands
84 */
85void engineInterface::sendHelp(std::string const& args)
86{
87 belofte::stringList sParams = belofte::stringSplit(args, " ");
88 bool bUnsupported = std::any_of(sParams.begin(), sParams.end(),
89 [](std::string const& s)
90 { return s == "unsupported"; });
91 bool bUnpublished = std::any_of(sParams.begin(), sParams.end(),
92 [](std::string const& s)
93 { return s == "hidden"; });
94 if (bUnsupported || bUnpublished || args == "") {
95 // trigger all case
96 sParams.emplace_back("all");
97 }
98 if (std::any_of(sParams.begin(), sParams.end(),
99 [](std::string const& s)
100 { return ((s == "all") || (s == "--all")); })) {
101 App().bout << "Help for " MYNAME " - mode: " << m_name << "\n";
102 for (auto const& ec : getEngineCommands()) {
103 engineUserCommand *v = getEngineCommands()[ec.first];
104 bool bAllowed = m_allowedCommands.find(v->m_name) != m_allowedCommands.end();
105 if (bUnsupported && !v->m_isImplemented) {
106 App().bout << std::left << std::setw(10) << v->m_name
107 << " - " << v->m_hint << " (u)\n";
108 } else if ((bUnpublished || bAllowed) && v->m_isImplemented) {
109 App().bout << std::left << std::setw(10) << v->m_name
110 << " - " << v->m_hint << (bAllowed ? "\n" : " (h)\n");
111 }
112 }
113 if (bUnsupported) App().bout << "\nu: Unsupported.";
114 if (bUnpublished) App().bout << "\nh: Hidden";
115 } else {
116 App().bout << "Help for " MYNAME << "\n";
117 if (getEngineCommands().find(args) != getEngineCommands().end()) {
118 engineUserCommand const *v = getEngineCommands()[args];
119 App().bout << std::left << std::setw(10) << v->m_name
120 << " - " << v->m_hint << "\n";
121 if (!v->m_isImplemented)
122 App().bout << "\n** Unsupported **";
123 } else {
124 App().bout << "Unknown command [" << args << "]";
125 }
126 }
127 App().bout.endl();
128}
129
130//-----------------------------------------------------------------------
131
132void engineInterface::sendInfoSearchStart(std::string const& info)
133{
134 sendInfo(info);
135}
136
137void engineInterface::sendResponse(std::string const& response)
138{
139 App().bout << response;
140 App().bout.endl();
141}
142
143void engineInterface::sendError(std::string const& error, std::string const& description)
144{
145 App().bout(-2) << "ERROR: " << error;
146 if (!description.empty()) App().bout << " (" << description << ")";
147 App().bout.endl();
148}
149
151{
152 App().sout(-2) << "move " << bPgnMove(b, m.getBMoveT());
153 App().sout.endl();
154}
155
156void engineInterface::sendResult(bBoard const& b UNUSED, gameResult_t const gr) const
157{
158 if (gr != GR_UNKNOWN) {
159 // end of game, so stop running
160 AppEI()->setRunning(false);
161 App().sout(-2) << Game()->getResult(gr);
162 App().sout.endl();
163 }
164}
165
166//-----------------------------------------------------------------------
167
169{
170 if (score > 0) {
171 if (score > SCORE_ALMOST_NORMAL) {
172 if (score == SCORE_THEORETIC_DRAW) return BE_DRAW;
173 if (score > SCORE_INFINITE) {
174 // mate or mate in n moves
175 if (score >= SCORE_MATE - SCORE_CONVERGE_BYDEPTH) return "mate";
176 else return "M" + belofte::to_string((SCORE_MATE - score) / 2);
177 }
178 if (score == SCORE_UNDEFINED) return BE_UNDEFINED;
179 if (score == SCORE_INFINITE) return BE_INF;
180 }
181 } else if (score < 0) {
182 if (score < -SCORE_ALMOST_NORMAL) {
183 if (score == SCORE_PRACTICAL_DRAW) return BE_DRAW;
184 if (score < -SCORE_INFINITE) {
185 // mate or mate in n moves
186 if (score <= -SCORE_MATE + SCORE_CONVERGE_BYDEPTH) return "mate";
187 else return "-M" + belofte::to_string((SCORE_MATE + score) / 2);
188 }
189 if (score == -SCORE_INFINITE) return "-" BE_INF;
190 if (score == -SCORE_UNDEFINED) return BE_UNDEFINED;
191 }
192 } else {
193 return "0";
194 }
195 return belofte::to_string(score);
196}
197
199{
200 if (gr == GR_UNKNOWN) {
201 return "";
202 } else if (gr == GR_DRAW_STALEMATE) {
203 return "Stalemate";
204 } else if (gr == GR_DRAW_LACKMATERIAL) {
205 return "Draw by insufficient material";
206 } else if (gr == GR_DRAW_THREEFOLD) {
207 return "Draw by repetition";
208 } else if (gr == GR_DRAW_50) {
209 return "50 move rule";
210 } else if (gr >= GR_DRAW_ADJ && gr <= GR_DRAW_OTHER) {
211 return "Draw";
212 } else if (gr == GR_WHITEMATES) {
213 return "White mates";
214 } else if (gr == GR_BLACKMATES) {
215 return "Black mates";
216 }
217 /// @todo add other end of game conditions
218
219 return "";
220}
221
222//-----------------------------------------------------------------------
223
225 : engineInterface("belofte", "Swith to xboard or UCI protocol")
226{
227 initCommand({new cmd_about(), new cmd_again(),
228 new cmd_alg(), new cmd_bd(), new cmd_belofte(),
229 new cmd_bench(), new cmd_computer(),
230 new cmd_debug(), new cmd_dot(),
231 new cmd_echo(), new cmd_epd(), new cmd_epdpos(), new cmd_eval(),
232 new cmd_evaltype(), new cmd_exec(), new cmd_execat(), new cmd_exit(),
233 new cmd_expect(), new cmd_export(), new cmd_fd(),
234 new cmd_force(), new cmd_game(),
235 new cmd_go(), new cmd_help(), new cmd_info(), new cmd_load(),
236 new cmd_playother(), new cmd_level(), new cmd_ls(),
237 new cmd_new(), new cmd_nopost(),
238 new cmd_option(), new cmd_perft(),
239 new cmd_ping(), new cmd_post(),
240 new cmd_questionmark(), new cmd_quit(),
241 new cmd_random(), new cmd_remove(),
242 new cmd_result(), new cmd_save(), new cmd_sd(), new cmd_st(),
243 new cmd_setboard(), new cmd_stop(),
244 new cmd_undo(), new cmd_usage(), new cmd_usermove(),
245 new cmd_name()});
246
247 attachCommand({"belofte"}, false);
248#if defined(BELOFTE_UCIMODE)
249 initCommand({new cmd_uci()});
250 attachCommand({"uci"});
251#elif defined(BELOFTE_XBOARDMODE)
252 initCommand({new cmd_xboard()});
253 attachCommand({"xboard"});
254#else
255 initCommand({new cmd_uci(), new cmd_xboard()});
256 attachCommand({"uci", "xboard"});
257#endif
258
259 attachCommand({"usage", "version", "exec", "ls", "export", "save", "load"}, false);
260 attachCommand({"about", "help", "bench", "perft"});
261}
262
263UCIMode::UCIMode(std::string&& s)
264 : engineInterface(std::move(s))
265{
267 new cmd_setoption(), new cmd_ucinewgame(), new cmd_ponderhit(),
268 new cmd_isready(), new cmd_position()});
269 attachCommand({"UCI_Opponent", "UCI_EngineAbout",
270 "UCI_Variant"}, false);
271 attachCommand({"setoption", "isready", "position", "go",
272 "stop", "ucinewgame", "ponderhit"});
273}
274
276 : engineInterface(std::move(s), "No xboard prompt")
277{
279 new cmd_easy(), new cmd_hard(), new cmd_white(), new cmd_black(),
280 new cmd_time(), new cmd_otim()});
281 attachCommand({"accepted", "black", "option", "otim", "ping",
282 "time", "rejected", "white"}, false);
283 attachCommand({"bd", "undo", "new", "setboard", "usermove", "game",
284 "remove", "force", "level", "post", "nopost", "random",
285 "easy", "hard", "go", "?", "result", "sd", "st", "protover"});
286}
287
288//-----------------------------------------------------------------------
289
291{
292 App().bout << MYLCNAME << "> ";
293}
294
295//-----------------------------------------------------------------------
296
297void UCIMode::sendMove(bBoard& b UNUSED, bMove const& m)
298{
299 App().sout(-2) << "bestmove " << bCoordMove(m);
300 //// @todo: retrieve ponder out of board
301 /// if (ponder != "") App().sout(-2) << " ponder " << ponder;
302 App().sout.endl();
303}
304
305void UCIMode::sendResult(bBoard const& b UNUSED, gameResult_t const gr UNUSED) const
306{
307 /*
308 if (gr != GR_UNKNOWN) {
309 App().sout(-2) << "bestmove 0000";
310 App().sout.endl();
311 }
312 */
313}
314
315void UCIMode::sendInfo(std::string const& info)
316{
317 if (App().getConfig("UCIdebug", 0)) {
318 App().sout << "info string " << info;
319 App().sout.endl();
320 }
321}
322
323void UCIMode::sendDebug(int const l, std::string const& info)
324{
325 App().bout(l) << "info string " << info;
326 App().bout.endl();
327}
328
329void UCIMode::sendInfoDepth(int depth, int seldepth, int64_t nodes, int nps)
330{
331 if (depth <= App().sout.getLevel()) {
332 App().sout << "info depth " << belofte::to_string(depth)
333 << " seldepth " << belofte::to_string(seldepth)
334 << " nodes " << belofte::to_string(nodes)
335#if !defined(NO_NPS_LOG)
336 << " nps " << nps
337#endif
338 ;
339 App().sout.endl();
340 }
341}
342
343void UCIMode::sendInfoSearching(bBoard const& b, int const nLogDepth,
344 depth_t const nMaxDepth,
345 bScore const sc, int64_t const timems,
346 int64_t const nodes) const
347{
348 int nVariationDepth = static_cast<int>(b.getVariation().size());
349 App().sout << "info depth " << belofte::to_string(nLogDepth);
350 if (nMaxDepth > nLogDepth)
351 App().sout << " seldepth " << belofte::to_string(static_cast<int16_t>(nMaxDepth));
352#if !defined(NO_NPS_LOG)
353 App().sout << " time " << belofte::to_string(timems);
354#endif
355 if (timems > 10) {
356 App().sout << " nodes " << belofte::to_string(nodes)
357#if !defined(NO_NPS_LOG)
358 << " nps " << belofte::to_string((nodes * 1000)/ timems)
359#endif
360 ;
361 }
362 App().sout << scoreString(sc);
363 if (!bSearchScore::isUndefinedScore(sc)) printPV(b, nLogDepth, nVariationDepth);
364 App().sout.endl();
365}
366
367/**
368 * Called from root search, can also be called with comments
369 * from other depths
370 */
371void UCIMode::sendInfoSearching(bBoard const& b, int const nLogDepth,
372 depth_t const nMaxDepth, std::string const& comment,
373 bScore const sc, int64_t const timems,
374 int64_t const nodes) const
375{
376 int nVariationDepth = static_cast<int>(b.getVariation().size());
377 if (nLogDepth) {
378 // not called from root
379 App().sout << "info depth " << belofte::to_string(nLogDepth);
380 if (nMaxDepth > nLogDepth)
381 App().sout << " seldepth " << belofte::to_string(static_cast<int16_t>(nMaxDepth));
382 } else if (nVariationDepth) {
383 // called from root, UCI requires us to send a depth
384 App().sout << "info depth " << belofte::to_string(nVariationDepth);
385 if (nMaxDepth > nVariationDepth)
386 App().sout << " seldepth " << belofte::to_string(static_cast<int16_t>(nMaxDepth));
387 } else {
388 // other cases
389 App().sout << "info";
390 }
391#if !defined(NO_NPS_LOG)
392 App().sout << " time " << belofte::to_string(timems);
393 if (nodes && (timems > 10))
394 App().sout << " nodes " << belofte::to_string(nodes)
395 << " nps " << belofte::to_string((nodes * 1000)/ timems);
396#else
397 if (nodes)
398 App().sout << " nodes " << belofte::to_string(nodes);
399#endif
400 App().sout << scoreString(sc);
401 printPV(b, nLogDepth, nVariationDepth);
402 if (comment != "") App().sout << " string " << comment;
403 App().sout.endl();
404}
405
406/**
407 * @static Class static function
408 * Print pv and currline
409 */
410void UCIMode::printPV(bBoard const& b,
411 int const nLogDepth,
412 int const nVariationDepth)
413{
414 if ((nLogDepth == 0) && nVariationDepth) {
415 App().sout << " pv";
416 for (std::string const& m : b.getPreviousMoves()) App().sout << " " << m;
417 for (std::string const& m : b.getVariation()) App().sout << " " << m;
418 } else {
419 if (b.getPreviousMoves().size()) {
420 /// @todo only print currline in case requested by UI
421 App().sout << " currline";
422 for (std::string const& m : b.getPreviousMoves()) App().sout << " " << m;
423 }
424 if (nVariationDepth) {
425 App().sout << " pv";
426 for (std::string const& m : b.getPreviousMoves()) App().sout << " " << m;
427 for (std::string const& m : b.getVariation()) App().sout << " " << m;
428 }
429 }
430}
431
433 depth_t const nCurDepth,
434 bMove const& mv, movenum_t const moveid, int64_t const nodes) const
435{
436 int nVariationDepth = static_cast<int>(b.getVariation().size());
437 App().sout << "info depth " << belofte::to_string(nCurDepth);
438 if (nVariationDepth > nCurDepth)
439 App().sout << " seldepth " << belofte::to_string(nVariationDepth);
440 App().sout << " nodes " << belofte::to_string(nodes)
441 << " currmovenumber " << belofte::to_string(moveid)
442 << " currmove " << mv;
443 App().sout.endl();
444}
445
446std::string UCIMode::scoreString(bScore const score) const
447{
448 if (bSearchScore::isDrawScore(score)) {
449 return " score 0";
450 } else if (score > SCORE_INFINITE) {
451 return " score mate " + belofte::to_string((SCORE_MATE - score) / 2);
452 } else if (score < -SCORE_INFINITE) {
453 return " score mate -" + belofte::to_string((SCORE_MATE + score) / 2);
454 } else if (bSearchScore::isUndefinedScore(score)) {
455 // skip output
456 } else if (score == -SCORE_INFINITE) {
457 return " score lowerbound";
458 } else if (score == SCORE_INFINITE) {
459 return " score upperbound";
460 } else {
461 return " score cp " + belofte::to_string(score);
462 }
463 return "";
464}
465
466//-----------------------------------------------------------------------
467
468void XboardMode::sendInfo(std::string const& info)
469{
470 App().sout << "# " << info;
471 App().sout.endl();
472}
473
474void XboardMode::sendDebug(int const l, std::string const& info)
475{
476 App().bout(l) << "# " << info;
477 App().bout.endl();
478}
479
480void XboardMode::sendInvalidMove(std::string const& mv, std::string const& reason)
481{
482 App().bout(-2) << "Illegal move: " << mv;
483 if (reason != "") App().bout << " (" << reason << ")";
484 App().bout.endl();
485}
486
487#if defined(__GNUC__)
488#pragma GCC diagnostic push
489#pragma GCC diagnostic ignored "-Wunused-parameter"
490#endif
491
492void XboardMode::sendInfoSearching(bBoard const& b, int const nLogDepth,
493 depth_t const nMaxDepth,
494 bScore const sc, int64_t const t, int64_t const nodes) const
495{
496 int nVariationDepth = static_cast<int>(b.getVariation().size());
497 if (!bSearchScore::isUndefinedScore(sc) && nVariationDepth) {
498 std::stringstream sNew;
499 for (std::string const& m : b.getPreviousMoves()) sNew << " " << m;
500 for (std::string const& m : b.getVariation()) sNew << " " << m;
501 if (sNew.str().size()) {
502 static std::string& sOld = *new std::string();
503 if (sNew.str() != sOld) {
504 // only post updates
505 sOld = sNew.str();
506 App().sout << " " << std::setw(3) << nVariationDepth
507 << (nVariationDepth == nMaxDepth ? " " : "&")
508 << " " << std::setw(8) << scoreString(sc)
509 << " " << std::setw(6) << (t / 10)
510 << " " << std::setw(8) << nodes
511 << sOld;
512 App().sout.endl();
513 }
514 }
515 }
516}
517
518#if defined(__GNUC__)
519#pragma GCC diagnostic pop
520#endif
521
522void XboardMode::sendResult(bBoard const& b, gameResult_t const gr) const
523{
524 gameResult_t ngr = gr;
525 if (ngr != GR_UNKNOWN) {
526 // end of game, so stop running
527 AppEI()->setRunning(false);
528 App().sout(-2) << Game()->getResult(ngr);
531 }
533 App().sout.endl();
534 }
535}
536
537std::string XboardMode::scoreString(bScore const score) const
538{
539 int localscore = score;
540
541 if (bSearchScore::isDrawScore(score)) {
542 return "0";
543 } else if (localscore > SCORE_INFINITE) {
544 localscore = (-localscore + SCORE_MATE) + 100000;
545 } else if (localscore < -SCORE_INFINITE) {
546 localscore = (-localscore - SCORE_MATE) - 100000;
547 }
548 return belofte::to_string(localscore);
549}
550
552{
553 std::string sResult = engineInterface::engineGameResultString(gr);
554 if (sResult != "") return " {" + sResult + "}";
555 return sResult;
556}
557
558//-----------------------------------------------------------------------
559
560// eof
appInstance & App()
Definition belofte.cpp:242
engineInterface * AppEI()
Definition belofte.cpp:248
bGame * Game()
Definition belofte.cpp:253
This is the main include file, needs to be included before any other include.
#define MYLCNAME
Definition belofte.h:33
uint_fast8_t movenum_t
Definition belofte.h:103
#define MYNAME
Definition belofte.h:32
int_fast8_t depth_t
Definition belofte.h:106
void sendPrompt() override
void sendDebug(int const l, std::string const &info) override
void sendResult(bBoard const &b, gameResult_t const gr) const override
void sendInfoCurrMove(bBoard const &b, depth_t const nCurDepth, bMove const &m, movenum_t const moveid, int64_t const nodes) const override
void sendInfoDepth(int depth, int seldepth, int64_t nodes, int nps) override
void sendMove(bBoard &b, bMove const &m) override
void sendInfoSearching(bBoard const &b, int const nLogDepth, depth_t const nMaxDepth, bScore const sc, int64_t const t, int64_t const nodes) const override
UCIMode(std::string &&s="uci")
std::string scoreString(bScore const score) const override
void sendInfo(std::string const &info) override
std::string engineGameResultString(gameResult_t const gr) const override
void sendDebug(int const l, std::string const &info) override
XboardMode(std::string &&s="xboard")
void sendInvalidMove(std::string const &mv, std::string const &reason) override
void sendResult(bBoard const &b, gameResult_t const gr) const override
void sendInfoSearching(bBoard const &b, int const nLogDepth, depth_t const nMaxDepth, bScore const sc, int64_t const t, int64_t const nodes) const override
std::string scoreString(bScore const score) const override
void sendInfo(std::string const &info) override
outputWriter sout
normal output
Definition belofte.h:179
outputWriter bout
Definition belofte.h:178
constexpr bmove_t getBMoveT() const
Definition basicmove.h:72
board
Definition board.h:45
movesequence_t const & getPreviousMoves() const
Definition board.h:94
movesequence_t const & getVariation() const
Definition board.h:98
simple coordmove, with 4 characters, or 5 characters in case of promotion mostly used for interface
Definition coordmove.h:15
static std::string getResult(gameResult_t gr)
Definition game.cpp:179
Definition move.h:13
PgnMove is for user-interface only.
Definition pgnmove.h:14
static gameResult_t gameEndedResult(bBoard const &b)
Class static function See if board is in finite state, meaning game is ended.
Definition eval.cpp:42
static bool isDrawResult(gameResult_t const gr)
Definition eval.h:67
static constexpr bool isDrawScore(bScore const score)
constexpr bool isUndefinedScore() const
Definition searchscore.h:70
Parse epd position.
Definition usercmd.h:256
implementation of single command
Definition usercmd.h:128
Definition usercmd.h:472
virtual void sendResult(bBoard const &b, gameResult_t const gr) const
virtual ~engineInterface()
void attachCommand(belofte::stringList const &sCommands, bool const published=true)
virtual void sendResponse(std::string const &response)
static engineCommands_t & getEngineCommands()
virtual void setRunning(bool const r)
virtual void sendMove(bBoard &b, bMove const &m)
virtual void sendHelp(std::string const &args)
Send help on command or all commands.
virtual std::string engineGameResultString(gameResult_t const gr) const
static void initCommand(std::vector< engineUserCommand * > cmds)
void execute(std::string const &command, std::string const &params)
virtual void sendInfo(std::string const &info)
virtual void sendInfoSearchStart(std::string const &info)
engineInterface(std::string &&n, std::string &&h="")
Common commands to all modes this ctor is called for each iface.
virtual void sendError(std::string const &error, std::string const &description)
static std::string scoreAsString(bScore const score)
basic format for single command
Definition usercmd.h:14
std::string m_hint
Definition usercmd.h:33
virtual void execute(std::string const &args)
Definition usercmd.cpp:12
std::string m_name
Definition usercmd.h:32
bool m_isImplemented
Definition usercmd.h:34
outputWriter & endl()
constexpr bScore SCORE_ALMOST_NORMAL
Definition eval.h:22
@ GR_DRAW_50
Definition eval.h:34
@ GR_DRAW_OTHER
Definition eval.h:35
@ GR_DRAW_STALEMATE
Definition eval.h:34
@ GR_UNKNOWN
Definition eval.h:33
@ GR_WHITEMATES
Definition eval.h:36
@ GR_BLACKMATES
Definition eval.h:37
@ GR_DRAW_LACKMATERIAL
Definition eval.h:34
@ GR_DRAW_THREEFOLD
Definition eval.h:34
@ GR_DRAW_ADJ
Definition eval.h:35
constexpr bScore SCORE_MATE
Definition eval.h:19
enum gameResult gameResult_t
Definition eval.h:40
int16_t bScore
Definition eval.h:11
constexpr bScore SCORE_PRACTICAL_DRAW
Definition eval.h:17
constexpr bScore SCORE_CONVERGE_BYDEPTH
Definition eval.h:27
constexpr bScore SCORE_UNDEFINED
Definition eval.h:21
constexpr bScore SCORE_THEORETIC_DRAW
Definition eval.h:16
constexpr bScore SCORE_INFINITE
Definition eval.h:20
std::string to_string(int16_t value)
std::to_string not compatible on Mac OS (Apple LLVM version 5.0) provide generic utility function
Definition util.cpp:186
stringList const stringSplit(std::string src, std::string const &delim)
Split delimited long string into a vector.
Definition util.cpp:148
std::vector< std::string > stringList
Definition util.h:48
#define BE_DRAW
Definition search.h:76
#define BE_UNDEFINED
Definition search.h:86
#define BE_INF
Definition search.h:75