+
+ // position() is called when engine receives the "position" UCI command.
+ // The function sets up the position described in the given FEN string ("fen")
+ // or the starting position ("startpos") and then makes the moves given in the
+ // following move list ("moves").
+
+ void position(Position& pos, istringstream& is) {
+
+ Move m;
+ string token, fen;
+
+ is >> token;
+
+ if (token == "startpos")
+ {
+ fen = StartFEN;
+ is >> token; // Consume "moves" token if any
+ }
+ else if (token == "fen")
+ while (is >> token && token != "moves")
+ fen += token + " ";
+ else
+ return;
+
+ pos.set(fen, Options["UCI_Chess960"], Threads.main());
+ SetupStates = Search::StateStackPtr(new std::stack<StateInfo>());
+
+ // Parse move list (if any)
+ while (is >> token && (m = UCI::to_move(pos, token)) != MOVE_NONE)
+ {
+ SetupStates->push(StateInfo());
+ pos.do_move(m, SetupStates->top());
+ }
+ }
+
+
+ // setoption() is called when engine receives the "setoption" UCI command. The
+ // function updates the UCI option ("name") to the given value ("value").
+
+ void setoption(istringstream& is) {
+
+ string token, name, value;
+
+ is >> token; // Consume "name" token
+
+ // Read option name (can contain spaces)
+ while (is >> token && token != "value")
+ name += string(" ", !name.empty()) + token;
+
+ // Read option value (can contain spaces)
+ while (is >> token)
+ value += string(" ", !value.empty()) + token;
+
+ if (Options.count(name))
+ Options[name] = value;
+ else
+ sync_cout << "No such option: " << name << sync_endl;
+ }
+
+
+ // go() is called when engine receives the "go" UCI command. The function sets
+ // the thinking time and other parameters from the input string, and starts
+ // the search.
+
+ void go(const Position& pos, istringstream& is) {
+
+ Search::LimitsType limits;
+ string token;
+
+ while (is >> token)
+ {
+ if (token == "searchmoves")
+ while (is >> token)
+ limits.searchmoves.push_back(UCI::to_move(pos, token));
+
+ else if (token == "wtime") is >> limits.time[WHITE];
+ else if (token == "btime") is >> limits.time[BLACK];
+ else if (token == "winc") is >> limits.inc[WHITE];
+ else if (token == "binc") is >> limits.inc[BLACK];
+ else if (token == "movestogo") is >> limits.movestogo;
+ else if (token == "depth") is >> limits.depth;
+ else if (token == "nodes") is >> limits.nodes;
+ else if (token == "movetime") is >> limits.movetime;
+ else if (token == "mate") is >> limits.mate;
+ else if (token == "infinite") limits.infinite = true;
+ else if (token == "ponder") limits.ponder = true;
+ }
+
+ Threads.start_thinking(pos, limits, SetupStates);
+ }
+
+} // namespace