summaryrefslogtreecommitdiff
path: root/src/UCI.hpp.in
blob: 67cabcf76b59be57b024914fd4c4d60043c04f49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#pragma once

#ifndef @COMPILE_PLATFORM@
#define @COMPILE_PLATFORM@
#endif
#ifdef UNIX
#include "ProcessLinux.hpp"
#define INIT_PROCESS(p)                                                        \
  { p = static_cast<Process *>(new ProcessLinux()); }
#endif
#ifdef WIN32
#include "ProcessWindows.hpp"
#define INIT_PROCESS(p)                                                        \
  { p = static_cast<Process *>(new ProcessWindows()); }
#endif
#include <chrono>
#include <sstream>
#include <thread>
#include <unordered_map>
#include <vector>

#define IS_OPT_PARAM(str)                                                      \
  ((str) == "name" || (str) == "type" | (str) == "default" ||                  \
   (str) == "min" || (str) == "max" || (str) == "var")

namespace uciadapter {

/// @brief Empty string and option if not specified
typedef struct Option {
  std::string name;
  std::string type;
  std::string default_value;
  std::string min;
  std::string max;
  std::string var;
} Option;

/// @brief All long are initiated to -1 if not set
class Info {
public:
  long depth;
  long seldepth;
  long multipv;
  long score_cp;
  long score_mate;
  long score_lowerbound;
  long score_upperbound;
  long cp;
  long nodes;
  long nps;
  long tbhits;
  long time;
  long hashfull;
  long cpuload;
  long currmovenumber;
  std::vector<std::string> pv;
  std::string currmove;
  Info();
};

/// @brief Calling go(Go()) will perform a Command("go"). Just leave unused
/// parameters untouched
class Go {
public:
  std::string searchmoves;
  std::string ponder;
  int wtime, btime, winc, binc, movestogo, depth, nodes, mate, movetime;
  bool infinite;
  Go();
};

class UCI {
  Process *p;
  /// @brief Reset on each call to go()
  std::string buffer;
  /// @brief Reset on each call to go()
  std::string bestmove, ponder;
  /// @brief Setup on engine startup
  std::string name, author;
  /// @brief Setup on engine startup
  std::vector<Option> options;
  /// @brief Setup on engine startup
  bool uciok;
  bool registration_required;
  bool copyprotection_failed;
  bool registered;
  void ParseId(std::string);
  void ParseOption(std::string);
  void ParseInfo(std::string);
  /// @brief Reset on each call to go()
  std::unordered_map<int, Info> lines;
  /// @brief Reset on each call to go()
  std::vector<std::string> infostrings;
  /// @brief Reset on each call to go()
  std::vector<std::string> refutations;
  void Sync();

public:
  UCI(std::string);
  ~UCI();
  std::string GetBuffer();
  std::string GetName();
  std::string GetAuthor();
  std::string GetBestMove();
  std::vector<Option> GetOptions();
  std::unordered_map<int, Info> GetLines();
  std::vector<std::string> GetInfoStrings();
  bool IsRegistrationRequired();
  bool IsRegistered();
  void Command(std::string);
  void SyncAfter(int);

  // UCI API (all in lower case)
  void ucinewgame();
  void stop();
  void position(std::string, std::string);
  void setoption(std::string, std::string);
  void position(std::string);
  void register_now(std::string, std::string);
  void register_later();
  void debug(bool);
  void ponderhit();
  void quit();
  void go(Go);
};

struct EngineError : public std::exception {
  std::string msg;
  EngineError(std::string reason) { msg = "Engine error: " + reason; }
  const char *what() const throw() { return msg.c_str(); }
};

} // namespace uciadapter