stellar

Stellar - UCI Chess engine written in C++20
git clone git://git.dimitrijedobrota.com/stellar.git
Log | Files | Refs | README | LICENSE

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