Chess Engine
A Chess Engine project written in C++.
Loading...
Searching...
No Matches
uci.hpp
1#pragma once
2
3#include <chrono>
4#include <sstream>
5#include <thread>
6
7#include "app_state.hpp"
8
9class UCI {
10 public:
11 void start(AppState& state) {
12 std::cout.setf(std::ios::unitbuf);
13 m_state = &state;
14 m_thread = std::thread([this] { runLoop(); });
15 }
16
17 void stop() {
18 if (m_thread.joinable()) {
19 m_thread.join();
20 }
21 }
22
23 private:
24 static bool inputAvailable() {
25 fd_set readfds;
26 FD_ZERO(&readfds);
27 FD_SET(STDIN_FILENO, &readfds);
28 timeval timeout = {.tv_sec = 0, .tv_usec = 0};
29 return select(STDIN_FILENO + 1, &readfds, nullptr, nullptr, &timeout) > 0;
30 }
31
32 void runLoop() {
33 std::string line;
34 while (!m_state->shouldQuit()) {
35 if (inputAvailable()) {
36 if (std::getline(std::cin, line)) {
37 if (line == "quit") {
38 m_state->signalQuit();
39 break;
40 }
41 processCommand(line);
42 }
43 } else {
44 std::this_thread::sleep_for(std::chrono::milliseconds(10));
45 }
46 }
47 }
48
49 void processCommand(const std::string& command) {
50 if (command == "uci") {
51 std::cout << "uciok\n";
52 } else if (command.starts_with("position")) {
53 handlePosition(command);
54 } else if (command.starts_with("go perft")) {
55 handlePerft(command);
56 }
57 }
58
59 void handlePosition(const std::string& command) {
60 m_state->applyToAllGames([&](Game& game) {
61 if (command.find("startpos") != std::string::npos) {
62 game.start();
63 } else if (command.find("fen") != std::string::npos) {
64 // to parse fen
65 }
66
67 size_t movesPos = command.find("moves");
68 if (movesPos != std::string::npos) {
69 std::istringstream iss(command.substr(movesPos + 6));
70 std::string move;
71
72 while (iss >> move) {
73 game.doMove(move);
74 }
75 }
76 });
77 }
78
79 void handlePerft(const std::string& /*command*/) {
80 // int depth = std::stoi(command.substr(9));
81 // m_state->applyToCurrentGame([depth](Game& game) { game.perft(depth); });
82 }
83
84 AppState* m_state = nullptr;
85 std::thread m_thread;
86};
87
88/*
89Just a piece of code I have used, I have to find place for it in UCI
90int testPerformance(Game& game, int depth, bool verbose = false) {
91 auto start = std::chrono::high_resolution_clock::now();
92
93 int nodes = Movegen::perft(game.getPosition(), depth, verbose);
94
95 auto end = std::chrono::high_resolution_clock::now();
96 std::chrono::duration<double> elapsed = end - start;
97
98 double seconds = elapsed.count();
99 double nodesPerSec = nodes / seconds;
100 double secPerNode = seconds / nodes;
101
102 std::cout << std::fixed << std::setprecision(6);
103 std::cout << "Perft(" << depth << "): " << nodes << " nodes\n";
104 std::cout << "Time: " << seconds << " sec\n";
105 std::cout << "Speed: " << nodesPerSec << " nodes/sec\n";
106 std::cout << "Efficiency: " << secPerNode << " sec/node\n";
107
108 return nodes;
109}*/
Definition app_state.hpp:13
Definition game.hpp:7
Definition uci.hpp:9