stellarUCI Chess engine written in C++20 |
git clone git://git.dimitrijedobrota.com/stellar.git |
Log | Files | Refs | README | LICENSE |
uci.cpp (4838B)
0 #include <algorithm>
1 #include <iostream>
2 #include <limits>
3 #include <sstream>
4 #include <string>
6 #include "engine.hpp"
7 #include "stellar_version.hpp"
8 #include "timer.hpp"
9 #include "uci.hpp"
11 namespace uci {
13 void communicate(const uci::Settings *settings) {
14 if (!settings->infinite && timer::get_ms() > settings->stoptime) {
15 settings->stopped = true;
16 return;
17 }
18 }
20 inline bool parse_move(const Board &board, Move &move, const std::string &move_string) {
21 const Square source = from_coordinates(move_string.substr(0, 2));
22 const Square target = from_coordinates(move_string.substr(2, 2));
24 const MoveList list(board);
25 for (int i = 0; i < list.size(); i++) {
26 const Move crnt = list[i];
27 if (crnt.source() == source && crnt.target() == target) {
28 if (move_string[4]) {
29 if (tolower(piece::get_code(crnt.promoted())) != move_string[4]) continue;
30 }
31 move = crnt;
32 return true;
33 }
34 }
35 return false;
36 }
38 void loop() {
39 static Settings settings;
40 static std::string line, command;
41 static Move move;
43 Board board;
45 while (true) {
46 std::getline(std::cin, line);
47 std::istringstream iss(line);
48 iss >> command;
49 if (command == "quit") {
50 break;
51 } else if (command == "uci") {
52 std::cout << "id name Stellar " << getStellarVersion() << "\n";
53 std::cout << "id author Dimitrije Dobrota\n";
54 std::cout << "uciok\n";
55 } else if (command == "debug") {
56 iss >> command;
57 settings.debug = (command == "on");
58 } else if (command == "isready") {
59 std::cout << "readyok\n";
60 } else if (command == "ucinewgame") {
61 settings = Settings();
62 settings.board = Board(start_position);
63 } else if (command == "position") {
64 settings.madeMoves.clear();
65 iss >> command;
66 if (command == "startpos") {
67 settings.board = Board(start_position);
68 } else if (command == "fen") {
69 iss >> command;
70 settings.board = Board(line.substr(13));
71 }
73 while (iss >> command)
74 if (command == "moves") break;
76 board = settings.board;
77 while (iss >> command) {
78 if (!parse_move(board, move, command)) break;
79 settings.madeMoves.push(move);
80 move.make(board);
81 }
82 } else if (command == "go") {
83 settings.searchMoves.clear();
84 uint64_t wtime = 0, btime = 0, movetime = 0;
85 uint64_t winc = 0, binc = 0, movestogo = 40;
87 while (iss >> command) {
88 if (command == "wtime") iss >> wtime;
89 else if (command == "btime")
90 iss >> btime;
91 else if (command == "winc")
92 iss >> winc;
93 else if (command == "binc")
94 iss >> binc;
95 else if (command == "depth")
96 iss >> settings.depth;
97 else if (command == "nodes")
98 iss >> settings.nodes;
99 else if (command == "movetime")
100 iss >> movetime;
101 else if (command == "movestogo")
102 iss >> movestogo;
103 else if (command == "ponder")
104 settings.ponder = true;
105 else if (command == "mate")
106 settings.mate = true;
107 else if (command == "infinite")
108 settings.infinite = true;
109 else if (command == "searchmoves") {
110 while (iss >> command) {
111 if (!parse_move(board, move, command)) break;
112 settings.searchMoves.push(move);
113 }
114 }
115 }
117 auto time_left = board.get_side() == WHITE ? wtime : btime;
118 int64_t time = 0;
120 if (movetime != 0) {
121 time = movetime;
122 movestogo = 1;
123 } else if (time_left != 0) {
124 auto inc = board.get_side() == WHITE ? winc : binc;
125 time = time_left / movestogo + inc / 2;
126 if (time > time_left) time = time_left - 500;
127 if (time <= 0) time = 100;
129 settings.infinite = false;
130 } else {
131 settings.infinite = true;
132 }
134 settings.starttime = timer::get_ms();
135 settings.stoptime = settings.starttime + time;
137 const Move best = engine::search_position(settings);
138 std::cout << "bestmove " << best << '\n';
140 settings.newgame = false;
141 }
142 }
143 }
144 } // namespace uci