Repository navigation
Expand file tree
/
Copy pathuci.cpp
More file actions
157 lines (140 loc) · 4.47 KB
/
Copy pathuci.cpp
File metadata and controls
157 lines (140 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//
// Created by Ashish Kumar Nanda on 8/9/26.
//
#include "uci.h"
#include <iostream>
#include "board.h"
#include <sstream>
#include <chrono>
#include "movegen.h"
#include "nnue.h"
#include "search.h"
#include "transposition.h"
Move parse_move(const Board& board, const std::string &token) {
MoveList moves;
generate_moves(board, moves);
for (int i = 0; i < moves.count; i++) {
const Move m = moves.moves[i];
if (move_to_string(m) != token) {
continue;
}
Board temp = board;
Undo u;
temp.make_move(m, u);
if (temp.last_move_was_legal()) {
return m;
}
}
return NO_MOVE;
}
void handle_position(Board& board, std::istringstream& ss) {
std::string token;
ss >> token;
if (token == "startpos") {
board.set_from_fen(START_FEN);
ss >> token;
}
else if (token == "fen") {
std::string fen;
while (ss >> token && token != "moves") {
fen += token + " ";
}
if (!fen.empty()) fen.pop_back();
board.set_from_fen(fen);
}
history_reset(board.hash);
while (ss >> token) {
const Move m = parse_move(board, token);
if (m == NO_MOVE) {
std::cout << "bad move: " << token << "\n"; break;
}
Undo u;
board.make_move(m, u);
history_push(board.hash);
}
}
void handle_go(const Board& board, std::istringstream& ss) {
GoLimits limits;
std::string token;
while (ss >> token) {
if (token == "depth") {
ss >> limits.depth;
}
else if (token == "movetime") {
ss >> limits.movetime;
}
else if (token == "wtime") {
ss >> limits.wtime;
}
else if (token == "btime") {
ss >> limits.btime;
}
else if (token == "winc") {
ss >> limits.winc;
}
else if (token == "binc") {
ss >> limits.binc;
}
else if (token == "nodes") {
ss >> limits.nodes;
}
else if (token == "infinite") {
limits.infinite = true;
}
}
const Move m = search(board, limits);
// UCI null move: no legal reply (mate or stalemate)
std::cout << "bestmove " << (m == NO_MOVE ? "0000" : move_to_string(m)) << std::endl;
}
// Fixed suite + fixed depth = a reproducible node count. The node total must be
// identical across runs; anything else means the search depends on wall-clock or
// on state that survives between positions.
static constexpr const char* BENCH_FENS[] = {
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1",
"8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 1",
"r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1",
"rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8",
"r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10",
"4k3/8/8/8/8/8/8/4K2R w K - 0 1",
"8/8/8/4k3/8/8/4P3/4K3 w - - 0 1",
};
void handle_setoption(std::istringstream& ss) {
std::string token, name, value;
ss >> token;
while (ss >> token && token != "value") {
if (!name.empty()) name += " ";
name += token;
}
while (ss >> token) {
if (!value.empty()) value += " ";
value += token;
}
if (name == "EvalFile") {
std::cout << (nnue_load(value.c_str()) ? "info string loaded " : "info string failed to load ")
<< value << std::endl;
}
}
void handle_bench(const int depth) {
uint64_t total_nodes = 0;
const auto start = std::chrono::steady_clock::now();
for (const char* fen : BENCH_FENS) {
Board board{};
board.set_from_fen(fen);
// Clear the table between positions so each one is independent.
tt_clear();
history_reset(board.hash);
GoLimits limits;
limits.depth = depth;
search(board, limits);
total_nodes += nodes_searched();
}
const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start).count();
std::cout << "\n==========================="
<< "\nBench depth : " << depth
<< "\nTotal nodes : " << total_nodes
<< "\nTime : " << ms << " ms"
<< "\nNPS : " << (ms > 0 ? total_nodes * 1000 / ms : 0)
<< "\n===========================" << std::endl;
}