123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- #include "UciParser.h"
- #include <sstream>
- #include <thread>
- #include "ChessGame.h"
- #include "EngineInfo.h"
- using namespace std;
- const map<std::string, UciParser::CommandHandler> UciParser::commandHandlers = {
- { "uci", &UciParser::uci },
- { "debug", &UciParser::debug },
- { "isready", &UciParser::isready },
- { "setoption", &UciParser::setoption },
- { "register", &UciParser::doNothing },
- { "ucinewgame", &UciParser::ucinewgame },
- { "position", &UciParser::position },
- { "go", &UciParser::go },
- { "stop", &UciParser::stop },
- { "quit", &UciParser::quit },
- { "getfen", &UciParser::getfen },
- { "perft", &UciParser::perft },
- };
- #include<fstream>
- int UciParser::parse(istream& in, ostream& out)
- {
- ofstream log{ "log.log" };
- while (!in.eof() && !quitting) {
- string line;
- getline(in, line);
- if (!line.empty()) {
- executeLine(line);
- log << line << endl;
- }
- }
- log.close();
- return 0;
- }
- int UciParser::executeLine(const string& line)
- {
- istringstream s{ line };
- string token;
- string command;
- vector<string> args;
- s >> command;
- while (s >> token) {
- args.push_back(std::move(token));
- }
- return executeCommand(command, args);
- }
- int UciParser::executeCommand(const string& command,
- const vector<string>& args)
- {
- try {
- CommandHandler ch = commandHandlers.at(command);
- (this->*ch)(args);
- return 0;
- }
- catch (out_of_range& oor) {
- // no handler for command -> invalid command
- out << "unknown command: " << command << endl;
- return 1;
- }
- catch (...) {
- out << "unknown error occurred" << endl;
- return 1;
- }
- }
- void UciParser::sendCommand(const std::string& command,
- const std::vector<std::string>& args)
- {
- std::unique_lock<std::mutex> lock { outStreamLock };
- cout << command;
- std::for_each(args.begin(), args.end(), [] (auto& x) { cout << " " << x; });
- cout << endl;
- }
- void UciParser::uci(const std::vector<std::string>& args)
- {
- sendCommand("id", { "name", "Chessy", chessy::info::versionString });
- sendCommand("id", { "author", "N. Winkler" });
- sendCommand("uciok");
- }
- void UciParser::debug(const vector<string>& args)
- {
- // not yet implemented
- }
- void UciParser::isready(const vector<string>& args)
- {
- sendCommand("readyok");
- }
- void UciParser::setoption(const vector<string>& args)
- {
- Option o;
-
- //optionsManager.setOption();
- }
- void UciParser::ucinewgame(const vector<string>& args)
- {
- return;
- }
- void UciParser::position(const vector<string>& args)
- {
- try {
- size_t movesIndex = 0;
- if (args.at(0) == "fen") {
- string fenString = args.at(1) + " " + args.at(2) + " " +
- args.at(3) + " " + args.at(4) + " " + args.at(5) + " " +
- args.at(6);
- cg.loadFromFen(fenString);
- movesIndex = 6;
- }
- else if (args.at(0) == "startpos") {
- cg = chessy::ChessGame();
- movesIndex = 1;
- }
- if (args.size() > movesIndex + 1 && args.at(movesIndex) == "moves") {
- for (size_t i = movesIndex + 1; i < args.size(); i++) {
- using chessy::Move;
- Move move = Move{ args[i] };
- cg.move(move);
- }
- }
- }
- catch(out_of_range& oor) {
- out << "invalid arguments for command 'position'" << endl;
- }
- catch(runtime_error& re) {
- out << "" << endl;
- }
- }
- void UciParser::go(const vector<string>& args)
- {
- stop({});
- chessy::Move bestMove;
- chessy::MoveValue value;
- int depth = 5;
- tie(bestMove, value) = chessy::miniMax(this->cg, depth);
- write("info", "depth", depth, "score", "cp", value);
- sendCommand("bestmove", { bestMove.asString() });
- /*fst = make_unique<FixedSearchTimer>(cg, *this);
- fst->setThinkTime(std::chrono::milliseconds{ 1000 });
- fst->startSearch();*/
- //chessy::Move m = minimax.calculateBest(5);
- // TODO: hack!
- /*string suffix;
- if (cg.getBoard().getAtPosition(m.origin) == chessy::PieceType::PAWN &&
- (m.destination.index < 8 || m.destination.index >= 56)) {
- suffix = "Q";
- }*/
- //sendCommand("bestmove", { m.asString() + suffix });
- }
- void UciParser::stop(const vector<string>& args)
- {
- if (fst) {
- fst->stop();
- fst->join();
- fst = nullptr;
- }
- }
- void UciParser::quit(const vector<string>& args)
- {
- quitting = true;
- }
- void UciParser::getfen(const vector<string>& args)
- {
- out << cg.generateFen() << endl;
- }
- void UciParser::perft(const vector<string>& args)
- {
- using chessy::perft;
- if (!args.empty()) {
- int depth = 0;
- try {
- depth = std::stoi(args[0]);
- } catch(...) {
- out << "invalid argument to perft: " << args[0] << endl;
- return;
- }
- perft(out, cg, depth);
- }
- }
- void UciParser::doNothing(const vector<string>& args)
- {
- // explicitly do nothing
- return;
- }
|