|
3 | 3 | #include "eval.h" |
4 | 4 | #include "search.hpp" |
5 | 5 | #include "tt.hpp" |
6 | | - |
7 | | -#include <atomic> |
8 | | -#include <chrono> |
9 | | -#include <iostream> |
10 | | -#include <limits> |
11 | | -#include <sstream> |
12 | | -#include <string> |
13 | | -#include <thread> |
| 6 | +#include "ucioptions.hpp" // this only handles options |
| 7 | +#include "uci.h" |
14 | 8 |
|
15 | 9 | using namespace std; |
16 | 10 |
|
17 | | -// Constants |
18 | | -#define IS_MATE_SCORE(score) (abs(score) >= MAX_SCORE_CP) |
19 | | -constexpr unsigned INFINITE_TIME = std::numeric_limits<unsigned>::max(); |
20 | | - |
21 | | -// Thread handle |
22 | | -static std::thread search_thread; |
23 | | - |
24 | | -// Search function |
25 | | -void run_search(chess::Position board, int depth, unsigned time_limit_ms, bool infinite) |
26 | | -{ |
27 | | - int prev_score = 0; |
28 | | - search::nodes=0; |
29 | | - search::tt.newSearch(); |
30 | | - search::start_time = std::chrono::high_resolution_clock::now(); |
31 | | - search::time_limit = std::chrono::milliseconds((int)(time_limit_ms * 0.01)); |
32 | | - search::PV stablePV; |
33 | | - |
34 | | - for (int d = 1; (depth == -1 || d <= depth) && !search::stop_requested.load(); ++d) |
35 | | - { |
36 | | - int alpha = prev_score - ASPIRATION_DELTA; |
37 | | - int beta = prev_score + ASPIRATION_DELTA; |
38 | | - |
39 | | - int16_t score = search::alphaBeta(board, alpha, beta, d); |
40 | | - |
41 | | - if (score <= alpha) |
42 | | - { |
43 | | - alpha = -MATE(0); |
44 | | - beta = prev_score + ASPIRATION_DELTA; |
45 | | - score = search::alphaBeta(board, alpha, beta, d); |
46 | | - } |
47 | | - else if (score >= beta) |
48 | | - { |
49 | | - alpha = prev_score - ASPIRATION_DELTA; |
50 | | - beta = MATE(0); |
51 | | - score = search::alphaBeta(board, alpha, beta, d); |
52 | | - } |
53 | | - if (!infinite && search::check_time()) |
54 | | - break; |
55 | | - } |
56 | | - |
57 | | - chess::Move best = search::pv.argmove[0]; |
58 | | - chess::Move ponder = search::pv.argmove[1]; |
59 | | - |
60 | | - if (best != chess::Move()) |
61 | | - { |
62 | | - cout << "bestmove " << best; |
63 | | - if (ponder != chess::Move()) |
64 | | - cout << " ponder " << ponder; |
65 | | - cout << endl; |
66 | | - } |
67 | | - else |
68 | | - { |
69 | | - cout << "bestmove (none)" << endl; |
70 | | - } |
71 | | -} |
72 | 11 |
|
73 | 12 | // Main UCI loop |
74 | 13 | int main() |
75 | 14 | { |
76 | 15 | chess::Position board; |
77 | | - string line; |
78 | | - |
79 | | - while (getline(cin, line)) |
80 | | - { |
81 | | - istringstream iss(line); |
82 | | - string token; |
83 | | - iss >> token; |
84 | | - |
85 | | - if (token == "uci") |
86 | | - { |
87 | | - cout << "id name MyEngine" << endl; |
88 | | - cout << "id author YourNameHere" << endl; |
89 | | - cout << "uciok" << endl; |
90 | | - } |
91 | | - else if (token == "isready") |
92 | | - { |
93 | | - cout << "readyok" << endl; |
94 | | - } |
95 | | - else if (token == "quit") |
96 | | - { |
97 | | - search::stop_requested = true; |
98 | | - if (search_thread.joinable()) |
99 | | - search_thread.join(); |
100 | | - break; |
101 | | - } |
102 | | - else if (token == "stop") |
103 | | - { |
104 | | - search::stop_requested = true; |
105 | | - } |
106 | | - else if (token == "position") |
107 | | - { |
108 | | - string sub; |
109 | | - iss >> sub; |
110 | | - |
111 | | - if (sub == "startpos") |
112 | | - { |
113 | | - board.setFen(chess::constants::STARTPOS); |
114 | | - if (iss >> sub && sub == "moves") |
115 | | - { |
116 | | - while (iss >> sub) |
117 | | - { |
118 | | - board.makeMove(chess::uci::uciToMove(board, sub)); |
119 | | - } |
120 | | - } |
121 | | - } |
122 | | - else if (sub == "fen") |
123 | | - { |
124 | | - string fen, temp; |
125 | | - int fenParts = 6; |
126 | | - while (fenParts-- && iss >> temp) |
127 | | - fen += temp + " "; |
128 | | - board.setFen(fen); |
129 | | - if (iss >> sub && sub == "moves") |
130 | | - { |
131 | | - while (iss >> sub) |
132 | | - board.makeMove(chess::uci::uciToMove(board, sub)); |
133 | | - } |
134 | | - } |
135 | | - |
136 | | - search::tt.clear(); |
137 | | - } |
138 | | - else if (token == "go") |
139 | | - { |
140 | | - int depth = -1; |
141 | | - int movetime = -1; |
142 | | - bool infinite = false; |
143 | | - bool white = (board.sideToMove() == chess::Color::WHITE); |
144 | | - |
145 | | - string sub; |
146 | | - while (iss >> sub) |
147 | | - { |
148 | | - if (sub == "depth") |
149 | | - iss >> depth; |
150 | | - else if (sub == "movetime") |
151 | | - iss >> movetime; |
152 | | - else if (sub == "wtime" && white) |
153 | | - iss >> movetime; |
154 | | - else if (sub == "btime" && !white) |
155 | | - iss >> movetime; |
156 | | - else if (sub == "infinite") |
157 | | - { |
158 | | - infinite = true; |
159 | | - depth = MAX_PLY; |
160 | | - } |
161 | | - } |
162 | | - |
163 | | - if (search_thread.joinable()) |
164 | | - { |
165 | | - search::stop_requested = true; |
166 | | - search_thread.join(); |
167 | | - } |
168 | | - |
169 | | - search::stop_requested = false; |
170 | | - unsigned time_limit_ms = INFINITE_TIME; |
171 | | - if (!infinite && movetime >= 0) |
172 | | - { |
173 | | - time_limit_ms = movetime; |
174 | | - } |
175 | | - chess::Position board_copy = board; |
176 | | - |
177 | | - search_thread = std::thread(run_search, board_copy, depth, time_limit_ms, infinite); |
178 | | - search_thread.detach(); |
179 | | - } |
180 | | - else if (token == "d") |
181 | | - { |
182 | | - cout << board << endl; |
183 | | - } |
184 | | - else if (token == "bench") |
185 | | - { |
186 | | - uint64_t nodes=0; |
187 | | - std::vector<std::string> fen_list = {"r7/pp3kb1/7p/2nr4/4p3/7P/PP1N1PP1/R1B1K2R b KQ - 1 19", |
188 | | - "r1bqk2r/pppp1ppp/2n5/4p3/4P3/2N5/PPPP1PPP/R1BQK2R w KQkq - 0 1", |
189 | | - "rnbqkb1r/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", |
190 | | - "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR b KQkq - 0 1", |
191 | | - "8/pp3k2/7p/2nR4/4p3/7P/Pb3PP1/6K1 b - - 1 25", |
192 | | - "8/p4k2/1p1R3p/2n5/4p3/7P/Pb3PP1/6K1 b - - 1 26", |
193 | | - "8/p4k2/1p1R1b1p/2n5/4p3/7P/P4PP1/5K2 b - - 3 27", |
194 | | - "8/p3k3/1pR2b1p/2n5/4p3/7P/P4PP1/5K2 b - - 5 28", |
195 | | - "1R6/8/1p1knb1p/p7/4p3/7P/P3KPP1/8 b - - 3 32", |
196 | | - "3R4/8/1p1k3p/p7/3bp2P/6Pn/P3KP2/8 b - - 2 35", |
197 | | - "8/4R3/1p6/p5PP/3b4/2n2K2/P2kp3/8 w - - 1 46", |
198 | | - "rnbqkb1r/ppp1pppp/1n6/8/8/2N2N2/PPPP1PPP/R1BQKB1R w KQkq - 2 5", |
199 | | - "r2qr1k1/1ppb1pbp/np4p1/3Pp3/4N3/P2B1N1P/1PP2PP1/2RQR1K1 b - - 6 16"}; |
200 | | - auto start_time = std::chrono::high_resolution_clock::now(); |
201 | | - for (int i=0;i<fen_list.size();i++) |
202 | | - { |
203 | | - string fen = fen_list[i]; |
204 | | - std::cout<<"Position "<<i<<"/"<<fen_list.size()-1<<std::endl; |
205 | | - board.setFen(fen); |
206 | | - run_search(board, 8, INFINITE_TIME, false); |
207 | | - nodes+=search::nodes; |
208 | | - } |
209 | | - auto end_time = std::chrono::high_resolution_clock::now(); |
210 | | - |
211 | | - std::chrono::duration<double> elapsed_seconds = end_time - start_time; |
212 | | - printf("===========================\n"); |
213 | | - printf("Total time (ms) : %d\n", int(elapsed_seconds.count() * 1000)); |
214 | | - printf("Nodes searched : %llu\n", nodes); |
215 | | - printf("Nodes/second : %llu\n", (uint64_t)(nodes/elapsed_seconds.count())); |
216 | | - } |
217 | | - else if (token == "eval") |
218 | | - { |
219 | | - trace(board); |
220 | | - } |
221 | | - } |
222 | | - |
| 16 | + UCIOptions::addSpin("aspiration_window", 30, 0, 500); |
| 17 | + uci_loop(); |
223 | 18 | return 0; |
224 | 19 | } |
0 commit comments