stellar

UCI 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> 5 6 #include "engine.hpp" 7 #include "stellar_version.hpp" 8 #include "timer.hpp" 9 #include "uci.hpp" 10 11 namespace uci { 12 13 void communicate(const uci::Settings *settings) { 14 if (!settings->infinite && timer::get_ms() > settings->stoptime) { 15 settings->stopped = true; 16 return; 17 } 18 } 19 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)); 23 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 } 37 38 void loop() { 39 static Settings settings; 40 static std::string line, command; 41 static Move move; 42 43 Board board; 44 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 } 72 73 while (iss >> command) 74 if (command == "moves") break; 75 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; 86 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 } 116 117 auto time_left = board.get_side() == WHITE ? wtime : btime; 118 int64_t time = 0; 119 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; 128 129 settings.infinite = false; 130 } else { 131 settings.infinite = true; 132 } 133 134 settings.starttime = timer::get_ms(); 135 settings.stoptime = settings.starttime + time; 136 137 const Move best = engine::search_position(settings); 138 std::cout << "bestmove " << best << '\n'; 139 140 settings.newgame = false; 141 } 142 } 143 } 144 } // namespace uci