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