#include <iostream>
#include <sstream>
#include <string>
+#include <vector>
#include "evaluate.h"
#include "misc.h"
// FEN string for the initial position
const string StartPositionFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
+ // Keep track of position keys along the setup moves (from start position to the
+ // position just before to start searching). This is needed by draw detection.
+ std::vector<StateInfo> SetupState;
+
// UCIParser is a class for parsing UCI input. The class
// is actually a string stream built on a given input string.
typedef istringstream UCIParser;
UCIParser up(cmd);
string token;
- up >> token; // operator>>() skips any whitespace
+ up >> skipws >> token;
if (token == "quit")
return false;
void set_position(Position& pos, UCIParser& up) {
+ Move m;
string token, fen;
- up >> token; // operator>>() skips any whitespace
+ up >> token;
if (token == "startpos")
{
else return;
// Parse move list (if any)
- while (up >> token)
- pos.do_setup_move(move_from_uci(pos, token));
+ SetupState.clear();
+
+ while (up >> token && (m = move_from_uci(pos, token)) != MOVE_NONE)
+ {
+ SetupState.push_back(StateInfo());
+ pos.do_setup_move(m, SetupState.back());
+ }
}
void set_option(UCIParser& up) {
- string token, name;
- string value = "true"; // UCI buttons don't have a "value" field
+ string token, name, value;
up >> token; // Consume "name" token
- up >> name; // Read option name
- // Handle names with included spaces
+ // Read option name (can contain spaces)
while (up >> token && token != "value")
- name += " " + token;
-
- up >> value; // Read option value
+ name += string(" ", !name.empty()) + token;
- // Handle values with included spaces
+ // Read option value (can contain spaces)
while (up >> token)
- value += " " + token;
+ value += string(" ", !value.empty()) + token;
if (Options.find(name) != Options.end())
- Options[name].set_value(value);
+ Options[name].set_value(value.empty() ? "true" : value); // UCI buttons don't have "value"
else
cout << "No such option: " << name << endl;
}
string token;
SearchLimits limits;
- Move searchMoves[MAX_MOVES] = { MOVE_NONE };
- Move* cur = searchMoves;
+ Move searchMoves[MAX_MOVES], *cur = searchMoves;
int time[] = { 0, 0 }, inc[] = { 0, 0 };
while (up >> token)
else if (token == "movetime")
up >> limits.maxTime;
else if (token == "searchmoves")
- {
while (up >> token)
*cur++ = move_from_uci(pos, token);
-
- *cur = MOVE_NONE;
- }
}
- assert(pos.is_ok());
-
+ *cur = MOVE_NONE;
limits.time = time[pos.side_to_move()];
limits.increment = inc[pos.side_to_move()];
// perft() is called when engine receives the "perft" command.
// The function calls perft() passing the required search depth
- // then prints counted nodes and elapsed time.
+ // then prints counted leaf nodes and elapsed time.
void perft(Position& pos, UCIParser& up) {