Belofte  version 2.1.5
A promising chess program using the UCI or Winboard interface
usercmd.cpp
Go to the documentation of this file.
1 /*---------------------------------------------------------------------+
2  * File: usercmd.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 
13  std::string const& h)
14  : m_name(s)
15  , m_hint(h)
16 {
17 }
18 
20 {
21 }
22 
23 void engineUserCommand::execute(std::string const& args)
24 {
25  AppEI()->sendError("unimplemented command, not executing",
26  m_name + " <" + args + ">");
27 }
28 
29 //-----------------------------------------------------------------------
30 
32  std::string const& h)
33  : engineUserCommand(s, h)
34 {
35 }
36 
38 {
39 }
40 
42  std::string const& h)
43  : engineUserCommand(s, h)
44 {
45 }
46 
48 {
49 }
50 
52  std::string const& h)
53  : engineUserCommand(s, h)
54 {
55 }
56 
58 {
59 }
60 
62  std::string const& h)
63  : engineUserCommand(s, h)
64 {
65  m_isImplemented = false;
66 }
67 
69 {
70 }
71 
72 //-----------------------------------------------------------------------
73 
75  : m_command("")
76  , m_args("")
77 {
78 }
79 
81 {
82 }
83 
84 //-----------------------------------------------------------------------
85 
86 /**
87  * Send help on command or all commands
88  * @param args --all means all commands, "" or a single command
89  * TODO: implement hidden command flag
90  */
91 void engineInterface::sendHelp(std::string const& args)
92 {
93  App().bout << "Help for " MYNAME " - mode: " << m_name << '\n';
94  if (args == "") {
95  for (auto const& ec : engineInterface::m_engineCommands) {
97  if (m_allowedCommands.find(v->m_name) != m_allowedCommands.end()) {
98  if (v->m_isImplemented)
99  App().bout << std::left << std::setw(10) << v->m_name
100  << " - " << v->m_hint << '\n';
101  }
102  }
103  } else if (args == "--all") {
104  for (auto const& ec : engineInterface::m_engineCommands) {
106  bool bAllowed = m_allowedCommands.find(v->m_name) != m_allowedCommands.end();
107  App().bout << std::left << std::setw(10) << v->m_name
108  << " - " << v->m_hint
109  << (v->m_isImplemented ? "" : " (*)")
110  << (bAllowed ? "" : " (+)")
111  << '\n';
112  }
113  App().bout << "\n*: Unimplemented.\n+: Extra";
114  } else {
115  if (engineInterface::m_engineCommands.find(args)
118  App().bout << std::left << std::setw(10) << v->m_name
119  << " - " << v->m_hint << '\n';
120  if (!v->m_isImplemented)
121  App().bout << "\n** Unimplemented **";
122  } else {
123  App().bout << "Unknown command [" << args << "]";
124  }
125  }
126  App().bout << std::endl;
127 }
128 
129 void engineInterface::sendResponse(std::string const& response)
130 {
131  App().bout << response << std::endl;
132 }
133 
134 void engineInterface::sendError(std::string const& error,
135  std::string const& description)
136 {
137  App().bout << "ERROR: " << error
138  << ((description != "") ? " (" + description + ")" : "")
139  << std::endl;
140 }
141 
142 void engineInterface::sendDebug(int const l, std::string const& info)
143 {
144  if (App().bout.getVerbosity() >= l)
145  App().bout << "# " << info << std::endl;
146 }
147 
148 //-----------------------------------------------------------------------
149 
150 void UCIMode::sendMove(bBoard const& b UNUSED, bMove const& m)
151 {
152  App().sout << "bestmove " << bCoordMove(m) << std::endl;
153 
154  // TODO: retrieve ponder out of board
155  // if (ponder != "") App().sout << " ponder " << ponder;
156 }
157 
158 void UCIMode::sendDebug(int const l, std::string const& info)
159 {
160  if (App().bout.getVerbosity() >= l)
161  App().bout << "info string " << info << std::endl;
162 }
163 
164 void UCIMode::sendInfoDepth(depth_t nDepth, depth_t seldepth,
165  int64_t nodes, int nps)
166 {
167  if (App().sout.getVerbosity() >= nDepth) {
168  App().sout << "info depth " << static_cast<int>(nDepth)
169  << " seldepth " << static_cast<int>(seldepth)
170  << " nodes " << nodes
171  << " nps " << nps << '\n';
172  }
173 }
174 
175 void UCIMode::sendInfoScore(long long timems,
176  bBoard const& b, bScore const sc)
177 {
178  if (App().sout.getVerbosity() >= 0) {
179  App().sout << "info" << UCIMode::uciscorestring(sc);
180  if (timems) {
181  App().sout << " time " << belofte::to_string(timems);
182  }
183  if (b.getVariation().size()) {
185  b.getPreviousMoves(), b.getVariation());
186  }
187  App().sout << std::endl;
188  }
189 }
190 
191 void UCIMode::sendInfoSearching(bBoard const& b, depth_t const nLogDepth,
192  depth_t const nMaxDepth DEVUNUSED, std::string const& comment,
193  bScore const sc, int64_t const timems, int64_t const nodes) const
194 {
195  if (App().sout.getVerbosity() >= nLogDepth) {
196  std::stringstream sOut;
197  sOut << "info"
198  " depth " << static_cast<int>(nLogDepth);
199  if (nLogDepth != nMaxDepth) sOut << " seldepth " << static_cast<int>(nMaxDepth);
200  sOut << " time " << belofte::to_string(timems);
201  if (timems > 10) {
202  sOut << " nodes " << belofte::to_string(nodes)
203  << " nps " << belofte::to_string((nodes * 1000)/ timems);
204  }
205  sOut << UCIMode::uciscorestring(sc);
206  int nVariationDepth = static_cast<int>(b.getVariation().size());
207  if ((nLogDepth == 0) && nVariationDepth) {
208  sOut << bMove::getMoveSequenceStr(" pv",
209  b.getPreviousMoves(), b.getVariation());
210  } else {
211  if (App().getConfig("UCI_ShowCurrLine", 0)
212  && b.getPreviousMoves().size()) {
213  sOut << bMove::getMoveSequenceStr(" currline", b.getPreviousMoves());
214  }
215  if (nVariationDepth) {
216  sOut << bMove::getMoveSequenceStr(" pv",
217  b.getPreviousMoves(), b.getVariation());
218  }
219  }
220  if ((comment != "") && App().getConfig("debug", 0))
221  sOut << " string " << comment;
222  App().sout << sOut.str() << '\n';
223  }
224 }
225 
226 void UCIMode::sendInfoCurrMove(bBoard const& b, depth_t const nLogDepth,
227  depth_t const nMaxDepth DEVUNUSED, std::string const& comment DEVUNUSED,
228  bMove const& mv, movenum_t const moveid, int64_t const nodes) const
229 {
230  if (App().sout.getVerbosity() >= nLogDepth) {
231  std::stringstream sOut;
232  sOut << "info"
233  " depth " << static_cast<int>(nLogDepth);
234  if (nLogDepth != nMaxDepth) sOut << " seldepth " << static_cast<int>(nMaxDepth);
235  sOut << " nodes " << belofte::to_string(nodes)
236  << " currmovenumber " << static_cast<int>(moveid)
237  << " currmove " << mv;
238  int nVariationDepth = static_cast<int>(b.getVariation().size());
239  if (App().getConfig("UCI_ShowCurrLine", 0)
240  && nVariationDepth) {
241  sOut << bMove::getMoveSequenceStr(" currline", b.getPreviousMoves());
242  }
243 #if !defined(_DEBUG)
244  if ((comment != "") && App().getConfig("debug", 0))
245  sOut << " string " << comment;
246 #endif
247  App().sout << sOut.str() << '\n';
248  }
249 }
250 
251 //-----------------------------------------------------------------------
252 
254 {
255  App().bout << MYLCNAME << "> ";
256 }
257 
258 void engineInterface::sendMove(bBoard const& b, bMove const& m)
259 {
260  App().sout << "move " << bPgnMove(b, m) << std::endl;
261 }
262 
264 {
265  if (rs != GR_UNKNOWN) {
266  // end of game, so stop running
267  AppEI()->setRunning(false);
268  App().sout << Game()->getResult(rs);
269  if ((rs >= GR_DRAW_STALEMATE) && (rs <= GR_DRAW_OTHER)) {
270  gameResult_t nrs = Game()->EvalFinalScore(b);
271  if (nrs == GR_DRAW_STALEMATE) {
272  App().sout << " {Stalemate}";
273  } else if (nrs == GR_DRAW_LACKMATERIAL) {
274  App().sout << " {Draw by insufficient material}";
275  } else if (nrs == GR_DRAW_THREEFOLD) {
276  App().sout << " {Draw by repetition}";
277  } else if (nrs == GR_DRAW_50) {
278  App().sout << " {50 move rule}";
279  } else {
280  App().sout << " {Draw}";
281  }
282  } else if ((rs >= GR_WHITEMATES) && (rs <= GR_WHITEWINS_FLAG)) {
283  App().sout << " {White mates}";
284  } else {
285  App().sout << " {Black mates}";
286  }
287  App().sout << std::endl;
288  }
289 }
290 
291 void XboardMode::sendInvalidMove(std::string const& mv,
292  std::string const& reason)
293 {
294  App().bout << "Illegal move: " << mv
295  << ((reason != "") ? " (" + reason + ")" : "")
296  << std::endl;
297 }
298 
299 void XboardMode::sendInfoSearching(bBoard const& b, depth_t const nLogDepth,
300  depth_t const nMaxDepth, std::string const& comment UNUSED,
301  bScore const sc, int64_t const t, int64_t const nodes) const
302 {
303  if (App().sout.getVerbosity() >= nLogDepth) {
304  int nVariationDepth = static_cast<int>(b.getVariation().size());
305  std::stringstream sNew;
306  if (((sc & SCORE_POSITIVE) != SCORE_PUNDEFINED)
307  && (nVariationDepth)) {
308  sNew << bMove::getMoveSequenceStr("",
309  b.getPreviousMoves(), b.getVariation());
310  if (sNew.str().size()) {
311  static std::string& sOld = *new std::string();
312  if (sNew.str() != sOld) {
313  // only post updates
314  sOld = sNew.str();
315  App().sout << " " << std::setw(3) << nVariationDepth
316  << (nVariationDepth == nMaxDepth ? " " : "&")
317  << " " << std::setw(8) << belofte::to_string(sc)
318  << " " << std::setw(6) << (t / 10)
319  << " " << std::setw(8) << nodes
320  << sOld << '\n';
321  }
322  }
323  }
324  }
325 }
326 
327 //-----------------------------------------------------------------------
328 // command implementation
329 
330 void cmd_help::execute(std::string const& args)
331 {
332  AppEI()->sendHelp(args);
333 }
334 
335 void cmd_quit::execute(std::string const& args UNUSED)
336 {
337  App().bout << "Bye" << std::endl;
338  throw quitCommandException();
339 }
340 
341 void cmd_about::execute(std::string const& args UNUSED)
342 {
343  App().bout << App().getConfig("enginename", "") << '\n'
344  << App().getConfig("author", "")
345  << std::endl;
346 }
347 
348 void cmd_usage::execute(std::string const& args)
349 {
350  App().bout << "Usage: " << args << " [options] [[@]script] \n"
351  << "\t--help\tThis help message\n"
352  << "\t--version\tShow version information and exit\n"
353  << "\t--uci\t\tUse UCI interface\n"
354  << "\t--xboard\tUse Xboard/Winboard interface\n"
355  << "\t--bench\t\tRun benchmark and exit\n"
356  << "\t[script]\tcontaining commands to execute."
357  << std::endl;
358 }
359 
360 void cmd_uci::execute(std::string const& args UNUSED)
361 {
362  App().setMode("uci");
363  AppEI()->sendResponse("");
364  AppEI()->sendResponse("id name " MYFULLNAME " (u)");
365  AppEI()->sendResponse("id author " MYAUTHOR);
366  /// @todo specific implementation of option
367  AppEI()->sendResponse("option name alg type combo default " + Game()->setAlgorithm() + " "
368  "var Random var StaticEval var BruteForce "
369  "var SearchIterativeBF var AB var ABFS var ABFH");
370  AppEI()->sendResponse("option name evaltype type combo default " + Game()->setEval() + " "
371  "var PiecesOnly var StaticBoard var PositionalBoard");
372  AppEI()->sendResponse("option name UCI_ShowCurrLine type check default false");
373  AppEI()->sendResponse("option name UCI_EngineAbout type string default "
374  + App().getConfig("about", ""));
375  AppEI()->sendResponse("option name UCI_Opponent type string default <empty>");
376  AppEI()->sendResponse("option name UCI_Variant type combo default normal "
377  "var normal");
378  // TODO: option name UCI_Chess960 type check default false
379  // setoption name UCI_Chess960 value true
380  // setoption name UCI_Variant value fischerandom
381  // TODO: option name UCI_AnalyseMode
382  AppEI()->sendResponse("uciok");
383 }
384 
385 void cmd_xboard::execute(std::string const& args UNUSED)
386 {
387  App().setMode("xboard");
388  App().bout << std::endl;
389 }
390 
391 void cmd_belofte::execute(std::string const& args UNUSED)
392 {
393  App().setMode("belofte");
394 }
395 
396 /** execute command file with @ command
397  * @warning command will do noting but change mode
398  * @see commandReader::runner() for actual parsing
399  */
400 void cmd_execat::execute(std::string const& args)
401 {
402  if (args.substr(0,1) == "@") {
403  App().m_reader.attach(args.substr(1));
404  } else {
405  App().m_reader.attach(args);
406  }
407 }
408 
409 /** execute command file with exec command
410  * @warning command will do noting but change mode
411  * @see commandReader::runner() for actual parsing
412  */
413 void cmd_exec::execute(std::string const& args)
414 {
415  App().m_reader.attach(args);
416 }
417 
418 void cmd_echo::execute(std::string const& args)
419 {
420  AppEI()->sendResponse(args);
421 }
422 
423 /** check if engine still alive, doing delayed constructors
424  */
425 void cmd_isready::execute(std::string const& args UNUSED)
426 {
427  // readyok to be sent only after newgame has finished
428  AppEI()->sendResponse("readyok");
429 }
430 
431 /** check if engine still alive, doing delayed constructors
432  */
433 void cmd_ping::execute(std::string const& args)
434 {
435  AppEI()->sendResponse("pong " + args);
436 }
437 
438 void cmd_ucinewgame::execute(std::string const& args UNUSED)
439 {
440  Game()->newGame();
441 }
442 
443 void cmd_debug::execute(std::string const& args)
444 {
445  App().m_debuginterface.execute(args);
446 }
447 
448 /** Read setoption command
449  * TODO: allow value parameter with space in it
450  */
451 void cmd_setoption::execute(std::string const& args)
452 {
453  belofte::stringList const sOptions = belofte::stringSplit(args, " ");
454  if (sOptions.size() >= 3) {
455  /// @todo get array from initialisation
456  std::string const opt[] = {"alg", "evaltype", "UCI_ShowCurrLine", "UCI_Opponent", "UCI_EngineAbout"};
457  if (std::find(std::begin(opt), std::end(opt), sOptions[1])
458  != std::end(opt)) {
459  /// @todo change to specific setoption function
460  if (sOptions.size() == 3) {
461  AppEI()->execute(sOptions[1], "");
462  } else {
463  std::string sParams = std::accumulate(sOptions.begin() + 3, sOptions.end(), std::string(),
464  [](std::string result, std::string sElem) {
465  return std::move(result) + std::move(sElem) + " ";
466  });
467  AppEI()->execute(sOptions[1], sParams);
468  }
469  } else {
470  AppEI()->sendError("command not understood", args);
471  }
472  } else {
473  AppEI()->sendError("bad command parameters", args);
474  }
475 }
476 
477 /** set start position, alternatives
478  * args = [fen fenstring | startpos ] moves move1 .... movei
479  * attention: should do noting if position set is identical to actual position
480  */
481 void cmd_position::execute(std::string const& args)
482 {
483  std::string startorfen = args.substr(0, args.find(' '));
484  std::size_t iMoves = args.find("moves ");
485  if (startorfen == "startpos" || startorfen == "") {
486  Game()->setFENInitialPos();
487  if (iMoves != std::string::npos) {
488  if (!Game()->playGameMoveSeries(args.substr(static_cast<unsigned long>(iMoves) + 6)))
489  AppEI()->sendInvalidMove(args.substr(static_cast<unsigned long>(iMoves) + 6), "");
490  }
491  } else if (startorfen == "fen") {
492  if (iMoves != std::string::npos) {
493  Game()->setFEN(args.substr(4, static_cast<unsigned long>(iMoves) - 4));
494  if (!Game()->playGameMoveSeries(args.substr(static_cast<unsigned long>(iMoves) + 6)))
495  AppEI()->sendInvalidMove(args.substr(static_cast<unsigned long>(iMoves) + 6), "");
496  } else {
497  Game()->setFEN(args.substr(4));
498  }
499  } else {
500  AppEI()->sendError("invalid parameter for position", args);
501  }
502 }
503 
504 void cmd_bench::execute(std::string const& args)
505 {
506  depth_t nDepth = 5;
507 
508  if (args.size()) {
509  belofte::stringList const goOptions = belofte::stringSplit(args, " ");
510  if (atoi(goOptions[0].c_str()) > 0) nDepth = static_cast<depth_t>(atoi(goOptions[0].c_str()));
511  }
512 
513  { SearchPerft search; bel_debug::run_bench(search, nDepth); }
514  { SearchBruteForce search; bel_debug::run_bench(search, nDepth); }
515  { SearchAlphaBeta search; bel_debug::run_bench(search, nDepth); }
516 
517  Game()->newGame();
518  Game()->setFENInitialPos();
519 }
520 
521 void cmd_perft::execute(std::string const& args)
522 {
523  belofte::stringList const perftOptions = belofte::stringSplit(args, " ");
524 
525  SearchPerft search;
526  int64_t nNodes = Game()->DoPerft(static_cast<depth_t>(atoi(perftOptions[0].c_str())), search);
527  int64_t nNonLeafNodes = search.getNonLeafNodes();
528 
529  std::string sNodes = belofte::to_string(nNodes);
530  std::string sTotalNodes = belofte::to_string(nNodes + nNonLeafNodes);
531  std::string sNPS = "0";
532  if ((nNodes + nNonLeafNodes) > 0LL) {
533  sNPS = belofte::to_string(
534  (nNodes + nNonLeafNodes) * 1000000LL / search.getDurationMicroSec());
535  }
536 
537  if (App().bout.checkExpected(sNodes)) {
538  App().bout << "perft " << args << " -> " << sNodes
539  << " (Total: " << sTotalNodes
540  << ") <- Execution time = " << search.getDuration()
541  << " NPS " << sNPS
542  << std::endl;
543  } else {
544  AppEI()->sendError("Expectation missed",
545  "perft " + args + " -> " + sNodes + " instead of <- "
546  + App().bout.getExpecting());
547  }
548  // clear expect flag
549  App().bout.setExpecting("");
550 }
551 
552 /** Parse epd position or epd file
553  * e.g. epd pos fen-epd fen-params
554  * epd [file] filename
555  */
556 void cmd_epd::execute(std::string const& args)
557 {
559  belofte::stringList sParams = belofte::stringSplit(args, " ");
560 
561  // remove any modifier flags
562  if (std::any_of(sParams.begin(), sParams.end(),
563  [](std::string const& s)
564  { return s == "-perf"; })) {
565  sParams.erase(sParams.begin() + 1);
566  typeOfTest = tEpdTestType::EPD_PERF;
567  }
568 
569  if (std::any_of(sParams.begin(), sParams.end(),
570  [](std::string const& s)
571  { return s == "-sts"; })) {
572  sParams.erase(sParams.begin() + 1);
573  typeOfTest = tEpdTestType::EPD_STS;
574  }
575 
576  if (sParams[0] == "pos") {
577  sParams.erase(sParams.begin());
578  bEpdPos epd(sParams);
579  epd.parse(typeOfTest);
580  } else if (sParams[0] == "file") {
581  sParams.erase(sParams.begin());
582  bEpdFile epd(sParams);
583  epd.parse(typeOfTest);
584  } else {
585  // same as epd file
586  bEpdFile epd(args);
587  epd.parse(typeOfTest);
588  }
589 }
590 
591 /** Parse epd position
592  * e.g. epdpos fen-epd fen-params
593  */
594 void cmd_epdpos::execute(std::string const& args)
595 {
596  bEpdPos epd(args);
597  epd.parse(tEpdTestType::EPD_GENERIC);
598 }
599 
600 void cmd_go::execute(std::string const& args)
601 {
602  belofte::stringList const goOptions = belofte::stringSplit(args, " ");
603  bLevel level;
604  depth_t nDepth, nMate;
605  int nInf, nTime, nInc, nMoves, nMoveTime, nPonder;
606  int64_t nNodes;
607 
608  nDepth = static_cast<depth_t>(belofte::positionParamValue(goOptions, "depth", 1));
609  nInf = belofte::positionParamIndex(goOptions, "infinite");
610 
611  if (Game()->getCurrentPosition().whiteToMove()) {
612  nTime = belofte::positionParamValue(goOptions, "wtime", 1);
613  nInc = belofte::positionParamValue(goOptions, "winc", 1);
614  } else {
615  nTime = belofte::positionParamValue(goOptions, "btime", 1);
616  nInc = belofte::positionParamValue(goOptions, "binc", 1);
617  }
618 
619  nMoves = belofte::positionParamValue(goOptions, "movestogo", 1);
620  nMoveTime = belofte::positionParamValue(goOptions, "movetime", 1);
621 
622  nNodes = belofte::positionParamValue(goOptions, "nodes", 1);
623  nMate = static_cast<depth_t>(belofte::positionParamValue(goOptions, "mate", 1));
624  nPonder = belofte::positionParamIndex(goOptions, "ponder");
625 
626  if (belofte::positionParamIndex(goOptions, "searchmoves") != -1) {
627  // TODO: add searchmoves
628  }
629 
630  if (nInf != -1) {
631  level.setInfinite();
632  } else if (nMoveTime != -1) {
633  level.setMoveTime(nMoveTime);
634  } else if (nTime != -1) {
635  if (nInc != -1) {
636  if (nMoves != -1) level.setMoveTime(nTime, nMoves, nInc);
637  else level.setGameTime(nTime, nInc);
638  } else {
639  if (nMoves != -1) level.setMoveTime(nTime, nMoves);
640  else level.setGameTime(nTime);
641  }
642  } else if (nMate != -1) {
643  level.setMateSearch(nMate);
644  }
645 
646  if (nDepth != -1) level.setDepth(nDepth);
647  if (nNodes != -1) level.setNodes(nNodes);
648  if (nPonder != -1) level.setPondering();
649 
650  if (args != "") {
651  Game()->setLevel(level);
652  } else if ((App().getMode() != "xboard")
653  && (Game()->getLevel().getType() != LevelType::Infinite)
654  && (Game()->getLevel().getType() != LevelType::MateSearch)
655  && (Game()->getLevel().getType() != LevelType::Unset)) {
656  // no arguments passed in uci mode, so we use previously set level
657  // but with cleared nodes and depth limitation, unless required to
658  // abort search
659  Game()->getLevel().setDepth(0);
660  Game()->getLevel().setNodes(0);
661  }
662  AppEI()->setRunning(true);
663  Game()->DoSearch();
664 }
665 
666 void cmd_again::execute(std::string const& args UNUSED)
667 {
668  Game()->revertGameMove();
669  AppEI()->execute("go", "");
670 }
671 
672 void cmd_usermove::execute(std::string const& args)
673 {
674  Game()->playUIsuppliedMove(args);
675 }
676 
677 void cmd_questionmark::execute(std::string const& args UNUSED)
678 {
679  Game()->AbortSearch();
680 }
681 
682 void cmd_stop::execute(std::string const& args UNUSED)
683 {
684  Game()->AbortSearch();
685 }
686 
687 void cmd_save::execute(std::string const& args UNUSED)
688 {
689  /// @todo save to file
690  App().bout << Game()->operator std::string() << '\n';
691 }
692 
693 void cmd_game::execute(std::string const& args UNUSED)
694 {
695  App().bout << Game()->operator std::string() << '\n';
696 }
697 
698 void cmd_bd::execute(std::string const& args UNUSED)
699 {
700  bBoard const& b = Game()->getCurrentPosition();
701  App().bout << b.operator std::string() << '\n';
702 }
703 
704 void cmd_undo::execute(std::string const& args UNUSED)
705 {
706  Game()->revertGameMove();
707 }
708 
709 void cmd_easy::execute(std::string const& args UNUSED)
710 {
712 }
713 
714 void cmd_hard::execute(std::string const& args UNUSED)
715 {
716  Game()->getLevel().setPondering();
717 }
718 
719 void cmd_verbose::execute(std::string const& args)
720 {
721  App().sout.setVerbosity(atoi(args.c_str()));
722 }
723 
724 #if !defined(NODIRENT)
725 void cmd_ls::execute(std::string const& args)
726 {
727  /// @todo does not compile with mingw cross compiler
728  std::string curdir = ".";
729  DIR *hDir;
730  if (args.length()) curdir = args + ".";
731 
732  hDir = opendir(curdir.c_str());
733  if (hDir) {
734  struct dirent *hFile;
735  while ((hFile = readdir(hDir)) != nullptr) {
736  std::string sFile(hFile->d_name);
737  if (sFile[0] == '.') continue;
738  App().bout << sFile << std::endl;
739  }
740  closedir(hDir);
741  }
742 }
743 #endif
744 
745 void cmd_expect::execute(std::string const& args)
746 {
747  App().bout.setExpecting(args);
748 }
749 
750 void cmd_new::execute(std::string const& args UNUSED)
751 {
752  Game()->newGame();
754  Game()->setFENInitialPos();
755  AppEI()->setRunning(true);
756 }
757 
758 void cmd_setboard::execute(std::string const& args)
759 {
760  Game()->setFEN(belofte::alltrim(args));
761 }
762 
763 void cmd_remove::execute(std::string const& args UNUSED)
764 {
765  Game()->revertGameMove();
766  Game()->revertGameMove();
767 }
768 
769 void cmd_protover::execute(std::string const& args UNUSED)
770 {
771  if (App().getMode() != "xboard") {
772  AppEI()->execute("xboard", "");
773  }
774  AppEI()->sendResponse("feature done=0");
775  AppEI()->sendResponse("feature ping=1 setboard=1 playother=1");
776  AppEI()->sendResponse("feature usermove=1 time=1 draw=0");
777  AppEI()->sendResponse("feature variants=\"normal\"");
778 #if defined(BELOFTE_NOSIGNALS)
779  AppEI()->sendResponse("feature sigint=0 sigterm=0");
780 #else
781  AppEI()->sendResponse("feature sigint=1 sigterm=1");
782 #endif
783  AppEI()->sendResponse("feature analyze=0 debug=1 colors=0");
784  AppEI()->sendResponse("feature name=1");
785  AppEI()->sendResponse("feature myname=\"" MYFULLNAME " (wb)\"");
786  AppEI()->sendResponse("feature option=\"alg -combo AB /// Random /// StaticEval /// "
787  "BruteForce /// SearchIterativeBF /// ABFS /// ABFH\"");
788  AppEI()->sendResponse("feature option=\"evaltype -combo "
789  "PositionalBoard /// PiecesOnly /// StaticBoard \"");
790  AppEI()->sendResponse("feature done=1");
791 }
792 
793 void cmd_force::execute(std::string const& args UNUSED)
794 {
795  AppEI()->setRunning(false);
796 }
797 
798 void cmd_playother::execute(std::string const& args UNUSED)
799 {
800  AppEI()->setRunning(true);
801 }
802 
803 void cmd_alg::execute(std::string const& args)
804 {
805  Game()->setAlgorithm(args);
806 }
807 
808 void cmd_evaltype::execute(std::string const& args)
809 {
810  Game()->setEval(args);
811 }
812 
813 void cmd_UCI_ShowCurrLine::execute(std::string const& args)
814 {
815  App().setConfig("UCI_ShowCurrLine", (args == "true") ? 1 : 0);
816 }
817 
818 void cmd_UCI_Opponent::execute(std::string const& args)
819 {
820  App().setConfig("opponent", args);
821  Game()->setPlayerName(args);
822 }
823 
824 void cmd_name::execute(std::string const& args)
825 {
826  App().setConfig("opponent", args);
827  Game()->setPlayerName(args);
828 }
829 
830 void cmd_option::execute(std::string const& args)
831 {
832  belofte::stringList const options = belofte::stringSplit(args, "=");
833  if (options.size() == 2) {
834  /// @todo get array from initialisation
835  std::string const opt[] = {"alg", "evaltype"};
836  if (std::find(std::begin(opt), std::end(opt), options[0])
837  != std::end(opt)) {
838  /// @todo change to specific setoption function
839  AppEI()->execute(options[0], options[1]);
840  } else {
841  AppEI()->sendError("option not understood", args);
842  }
843  } else {
844  AppEI()->sendError("bad option parameters", args);
845  }
846 }
847 
848 void cmd_info::execute(std::string const& args UNUSED)
849 {
851 }
852 
853 void cmd_rejected::execute(std::string const& args)
854 {
855  AppEI()->sendDebug(1, "UI rejected " + args);
856 }
857 
858 void cmd_eval::execute(std::string const& args UNUSED)
859 {
860  std::stringstream ss;
861  bBoard& b = Game()->getCurrentPosition();
862 
863  ss << "# Eval: (" << (b.minimizing() == 1 ? "maximizing) white" : "minimizing) black")
864  << " to move - " << Game()->getEval()->operator std::string();
865  if (Game()->getRandom()) ss << " +-Rnd";
866 
867  if (b.getStage() == bGameStage::ST_OPENING) ss << " - Opening";
868  else if (b.getStage() == bGameStage::ST_ENDGAME) ss << " - Endgame";
869  else if (b.getStage() == bGameStage::ST_MATING) ss << " - Mating";
870  else if (b.getStage() == bGameStage::ST_PAWNENDING) ss << " - Pawnending";
871 
872  bScore sc = Game()->EvalForPlayer(b);
873  ss << "\ninfo" << UCIMode::uciscorestring(sc);
874 
875  if (!Game()->getRandom()) {
876  b.invert();
877  bScore isc = Game()->EvalForPlayer(b);
878  if (isc != sc) {
879  ss << " (inbalanced eval: "
881  << ")";
882  }
883  b.invert();
884  }
885 
886  ss << " material" << UCIMode::uciscorestring(Game()->MaterialEvalForPlayer(b));
887 
888  App().bout << ss.str() << std::endl;
889 }
890 
891 //-----------------------------------------------------------------------
892 // xboard implementation
893 
894 /** limit maximum search depth */
895 void cmd_sd::execute(std::string const& args)
896 {
897  Game()->getLevel().setDepth(static_cast<depth_t>(atoi(args.c_str())));
898 }
899 
900 void cmd_fd::execute(std::string const& args)
901 {
902  Game()->getLevel().setMateSearch(static_cast<depth_t>(atoi(args.c_str())));
903 }
904 
905 void cmd_level::execute(std::string const& args)
906 {
907  belofte::stringList const levelOptions = belofte::stringSplit(args, " ");
908  int nMovesPerPeriod = 0;
909  int nTimePerPeriod = 0;
910  int nIncrement = 0;
912  if (levelOptions.size() == 3) {
913  nMovesPerPeriod = atoi(levelOptions[0].c_str());
914  nIncrement = atoi(levelOptions[2].c_str());
915  belofte::stringList const sPeriods = belofte::stringSplit(levelOptions[1], ":");
916  if (sPeriods.size() == 2) {
917  nTimePerPeriod = atoi(sPeriods[0].c_str()) * 60
918  + atoi(sPeriods[1].c_str());
919  } else {
920  nTimePerPeriod = atoi(levelOptions[1].c_str()) * 60;
921  }
922  }
923  // TODO: keep initial game time so that after move 35, all increment time is
924  // used, currently, it is flapping around 10s left
925  if (nMovesPerPeriod == 0) {
926  if (nIncrement == 0) {
927  Game()->getLevel().setGameTime(nTimePerPeriod * 1000);
928  } else {
929  Game()->getLevel().setGameTime(nTimePerPeriod * 1000,
930  nIncrement * 1000);
931  }
932  } else {
933  if (nIncrement == 0) {
934  Game()->getLevel().setMoveTime(nTimePerPeriod * 1000,
935  nMovesPerPeriod);
936  } else {
937  Game()->getLevel().setMoveTime(nTimePerPeriod * 1000,
938  nMovesPerPeriod, nIncrement * 1000);
939  }
940  }
941 }
942 
943 void cmd_st::execute(std::string const& args)
944 {
945  Game()->getLevel().setMoveTime(atoi(args.c_str())*1000);
946 }
947 
948 void cmd_time::execute(std::string const& args)
949 {
950  // centiseconds to milliseconds conversion
951  Game()->getLevel().setRemainingTime(atoi(args.c_str())*10);
952 }
953 
954 void cmd_random::execute(std::string const& args UNUSED)
955 {
956 #if !defined(BELOFTE_NORANDOM)
957  Game()->setRandom(!Game()->getRandom());
958 #endif
959 }
960 
961 void cmd_post::execute(std::string const& args UNUSED)
962 {
963  App().sout.setVerbosity(1);
964 }
965 
966 void cmd_nopost::execute(std::string const& args UNUSED)
967 {
968  App().sout.setVerbosity(-1);
969 }
970 
971 // eof
appInstance & App()
Definition: belofte.cpp:494
bGameWithTest * Game()
Definition: belofte.cpp:505
engineInterface * AppEI()
Definition: belofte.cpp:500
This is the main include file, needs to be included before any other include.
#define MYAUTHOR
Definition: belofte.h:32
uint_fast16_t movenum_t
moveflags (high order word) & basicmove (low order word)
Definition: belofte.h:103
#define MYLCNAME
Definition: belofte.h:27
#define MYFULLNAME
Definition: belofte.h:43
int_fast16_t bScore
used to return id of move in movelist
Definition: belofte.h:104
#define MYNAME
Definition: belofte.h:26
int_fast8_t depth_t
Definition: belofte.h:105
std::string getDuration() const
Definition: util.cpp:47
long long getDurationMicroSec() const
Definition: util.cpp:61
void sendDebug(int const l, std::string const &info) override
Definition: usercmd.cpp:158
static std::string uciscorestring(bScore const sc)
convert score to uci score string to be returned to uci interface, if value in there,...
Definition: belofte.cpp:375
void sendInfoScore(long long timems, bBoard const &b, bScore const cp) override
Definition: usercmd.cpp:175
void sendInfoSearching(bBoard const &b, depth_t const nLogDepth, depth_t const nMaxDepth, std::string const &comment, bScore const sc, int64_t const timems, int64_t const nodes) const override
Definition: usercmd.cpp:191
void sendInfoDepth(depth_t depth, depth_t seldepth, int64_t nodes, int nps) override
Definition: usercmd.cpp:164
void sendMove(bBoard const &b, bMove const &m) override
Definition: usercmd.cpp:150
void sendInfoCurrMove(bBoard const &b, depth_t const nLogDepth, depth_t const nMaxDepth, std::string const &comment, bMove const &m, movenum_t const moveid, int64_t const nodes) const override
Definition: usercmd.cpp:226
UCIengineCommand(std::string const &s, std::string const &h)
Definition: usercmd.cpp:31
~UCIengineCommand() override
Definition: usercmd.cpp:37
~Xboard1engineCommand() override
Definition: usercmd.cpp:47
Xboard1engineCommand(std::string const &s, std::string const &h)
Definition: usercmd.cpp:41
~Xboard2engineCommand() override
Definition: usercmd.cpp:57
Xboard2engineCommand(std::string const &s, std::string const &h)
Definition: usercmd.cpp:51
void sendInfoSearching(bBoard const &b, depth_t const nLogDepth, depth_t const nMaxDepth, std::string const &comment, bScore const sc, int64_t const timems, int64_t const nodes) const override
Definition: usercmd.cpp:299
void sendInvalidMove(std::string const &info, std::string const &reason) override
Definition: usercmd.cpp:291
outputWriter sout
normal output
Definition: belofte.h:299
bel_debug m_debuginterface
Definition: belofte.h:302
std::string setMode(std::string const &iName)
Definition: belofte.cpp:448
void setConfig(std::string const &s, int64_t v)
Definition: belofte.cpp:470
outputWriter bout
Definition: belofte.h:298
int64_t getConfig(std::string const &s, int64_t v)
Definition: belofte.cpp:475
commandReader m_reader
searching output
Definition: belofte.h:300
board
Definition: board.h:111
bGameStage getStage() const
Definition: board.h:145
movesequence_t getVariation() const
Definition: board.h:158
movesequence_t getPreviousMoves() const
Definition: board.h:155
bScore minimizing() const
Definition: board.h:149
void invert()
invert board position update kingpos, update colour to move, castle rights, ...
Definition: board.cpp:524
std::string setAlgorithm(std::string const &alg="")
std::string setEval(std::string const &e="")
bPositionEvaluation * getEval()
simple coordmove, with 4 characters, or 5 characters in case of promotion mostly used for interface
Definition: san.h:62
bScore EvalForPlayer(bBoard &b)
Definition: game.cpp:124
void revertGameMove()
required for Winboard protocol, not supported in UCI (except debug)
Definition: game.cpp:214
bool playUIsuppliedMove(std::string const &coordmove)
Definition: game.cpp:153
void setPlayerName(std::string const &n)
Definition: game.cpp:62
gameResult_t EvalFinalScore(bBoard &b)
Definition: game.cpp:134
std::string getResult(gameResult_t rs) const
Definition: game.cpp:139
void AbortSearch()
Definition: game.cpp:99
void newGame()
Definition: game.cpp:29
void setRandom(bool const r)
Definition: game.h:51
void DoSearch()
Start search thread and exit.
Definition: game.cpp:80
void setFEN(std::string const &fenstr)
Definition: game.cpp:54
bLevel & getLevel()
Definition: game.h:48
bBoard & getCurrentPosition()
Definition: game.cpp:73
void setLevel(bLevel const &l)
Definition: game.h:47
void setFENInitialPos()
Definition: game.cpp:46
int64_t DoPerft(depth_t const d, bSearchAlgorithm &sa)
do perft search at depth
Definition: game.cpp:283
Definition: level.h:51
void clearPondering()
Definition: level.cpp:270
void setDepth(depth_t const d)
Definition: level.cpp:238
void setGameTime(int const msPerGame)
new level or new game
Definition: level.cpp:40
void setInfinite()
Definition: level.cpp:30
void setRemainingTime(int const msPerGame)
xboard issues time command to update available time
Definition: level.cpp:141
void setNodes(int64_t const n)
Definition: level.cpp:255
void setMoveTime(int const msPerMove)
Definition: level.cpp:72
void setMateSearch(depth_t const d)
set level to search mate in n different from bruteforce search which is non optimised
Definition: level.cpp:129
void setPondering()
Definition: level.cpp:265
void flagLevelChange()
Definition: level.cpp:25
void initDepths(depth_t const d)
Definition: level.cpp:243
Definition: move.h:164
static std::string getMoveSequenceStr(std::string const &sLabel, movesequence_t const &sq1)
static member function to convert movesequence to string
Definition: move.cpp:172
PgnMove is for user-interface only.
Definition: san.h:12
int64_t getNonLeafNodes() const
Definition: search.h:41
void info() const
Definition: bel_debug.cpp:56
static void run_bench(bSearchAlgorithm &search, depth_t const nDepth)
Definition: bel_debug.cpp:101
void execute(std::string const &args)
Definition: bel_debug.cpp:16
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
Definition: usercmd.cpp:341
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
Definition: usercmd.cpp:330
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
Definition: usercmd.cpp:335
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
Definition: usercmd.cpp:348
void execute(std::string const &args) override
void execute(std::string const &args) override
void execute(std::string const &args) override
~cmdParam()
Definition: usercmd.cpp:80
cmdParam()
Definition: usercmd.cpp:74
bool attach(std::string const &ifile)
Definition: belofte.cpp:264
~dummyEngineCommand() override
Definition: usercmd.cpp:68
dummyEngineCommand(std::string const &s, std::string const &h)
Definition: usercmd.cpp:61
virtual void sendMove(bBoard const &b, bMove const &m)
Definition: usercmd.cpp:258
virtual void sendPrompt()
Definition: usercmd.cpp:253
virtual void sendResponse(std::string const &response)
Definition: usercmd.cpp:129
virtual void sendInvalidMove(std::string const &info, std::string const &reason UNUSED)
Definition: belofte.h:188
virtual void sendDebug(int const l, std::string const &info)
Definition: usercmd.cpp:142
static engineCommands_t m_engineCommands
Definition: belofte.h:222
virtual void setRunning(bool const r)
Definition: belofte.h:183
virtual void sendHelp(std::string const &args)
Send help on command or all commands.
Definition: usercmd.cpp:91
void execute(std::string const &command, std::string const &params)
Definition: belofte.cpp:147
virtual void sendResult(bBoard &b, gameResult_t rs) const
Definition: usercmd.cpp:263
virtual void sendError(std::string const &error, std::string const &description)
Definition: usercmd.cpp:134
basic format for single command
Definition: usercmd.h:13
std::string m_hint
Definition: usercmd.h:28
virtual ~engineUserCommand()
Definition: usercmd.cpp:19
virtual void execute(std::string const &args)
Definition: usercmd.cpp:23
std::string m_name
Definition: usercmd.h:27
engineUserCommand(std::string const &s, std::string const &h)
Definition: usercmd.cpp:12
bool m_isImplemented
Definition: usercmd.h:29
void setExpecting(std::string const &s)
Definition: bel_debug.cpp:236
void setVerbosity(int const l)
Definition: bel_debug.h:47
enum tEpdTestType epdTest_t
Definition: epd_testsuite.h:21
@ EPD_STS
Definition: epd_testsuite.h:17
@ EPD_GENERIC
Definition: epd_testsuite.h:16
@ EPD_PERF
Definition: epd_testsuite.h:18
@ GR_DRAW_50
Definition: eval.h:35
@ GR_DRAW_OTHER
Definition: eval.h:36
@ GR_DRAW_STALEMATE
Definition: eval.h:35
@ GR_WHITEWINS_FLAG
Definition: eval.h:37
@ GR_UNKNOWN
Definition: eval.h:34
@ GR_WHITEMATES
Definition: eval.h:37
@ GR_DRAW_LACKMATERIAL
Definition: eval.h:35
@ GR_DRAW_THREEFOLD
Definition: eval.h:35
enum gameResult gameResult_t
Definition: eval.h:41
constexpr bScore SCORE_PUNDEFINED
Definition: eval.h:19
constexpr bScore SCORE_POSITIVE
Definition: eval.h:16
constexpr auto INFINITE_DEPTH
Definition: level.h:11
#define DEVUNUSED
Definition: myplatform.h:124
std::string alltrim(std::string s, std::string const &delim=" ")
trim left and right spaces or delim from string
Definition: util.cpp:177
int positionParamIndex(stringList const &param, std::string const &findstr)
find position in which param has been found
Definition: util.cpp:220
std::vector< std::string > stringList
Definition: util.h:46
int positionParamValue(stringList const &param, std::string const &findstr, unsigned long const nOffSet=0)
Definition: util.cpp:229
std::string to_string(long value)
std::to_string not compatible on Mac OS (Apple LLVM version 5.0) provide generic utility function
Definition: util.cpp:168
stringList stringSplit(std::string src, std::string delim)
Split delimited long string into a vector.
Definition: util.cpp:132