@@ -94,17 +94,17 @@ Value Searcher::qsearch(Value alpha, Value beta, int plyRemaining,
94
94
template <NodeType NT>
95
95
Value Searcher::negamax (Value alpha, Value beta, int plyRemaining,
96
96
int plyFromRoot, bool canNullMove) {
97
+ // Check game status
98
+ const auto [gameOver, gameResultValue] = checkGameStatus (pos);
99
+ if (gameOver) {
100
+ return gameResultValue.addPly (plyFromRoot);
101
+ }
97
102
// Check time
98
103
if (checkTime ()) {
99
104
searchAborted = true ;
100
105
return 0 ;
101
106
}
102
107
103
- // Check game status
104
- const auto [gameOver, gameResultValue] = checkGameStatus (pos);
105
- if (gameOver) {
106
- return gameResultValue.addPly (plyFromRoot);
107
- }
108
108
diagnosis.nodes ++;
109
109
110
110
if (plyFromRoot >= diagnosis.seldepth ) {
@@ -137,9 +137,13 @@ Value Searcher::negamax(Value alpha, Value beta, int plyRemaining,
137
137
138
138
// Set up move ordering
139
139
MoveOrderer<OrderMode::DEFAULT> orderer;
140
- Move ttHashMove = entry ? entry->move () : Move::NO_MOVE; // note +11.59 elo
141
- orderer.init (pos, &killerMoves[plyFromRoot],
142
- ttHashMove.isValid () ? &ttHashMove : nullptr );
140
+
141
+ if (entry) { // Hash move from transposition table if available
142
+ Move ttHashMove = entry->move ();
143
+ orderer.init (pos, &killerMoves[plyFromRoot], &ttHashMove);
144
+ } else {
145
+ orderer.init (pos, &killerMoves[plyFromRoot]);
146
+ }
143
147
144
148
Move bestMove (Move::NO_MOVE);
145
149
Move m;
@@ -166,6 +170,7 @@ Value Searcher::negamax(Value alpha, Value beta, int plyRemaining,
166
170
}
167
171
}
168
172
173
+ // Principal Variation Search
169
174
pos.makeMove (m);
170
175
Value eval;
171
176
if (movesSearched == 0 ) {
@@ -189,13 +194,6 @@ Value Searcher::negamax(Value alpha, Value beta, int plyRemaining,
189
194
// Update killer and history heuristics for non-capture moves
190
195
if (!pos.isCapture (m)) {
191
196
this ->killerMoves [plyFromRoot].add (m);
192
-
193
- // // todo always refactor this
194
- // int bonus = std::clamp(plyRemaining * plyRemaining, -500,
195
- // 500); int &ref =
196
- // this->historyHeuristics[(int)pos.sideToMove()]
197
- // [m.from().index()][m.to().index()];
198
- // ref += bonus - ref * std::abs(bonus) / 500;
199
197
}
200
198
return beta;
201
199
}
@@ -264,38 +262,40 @@ std::pair<Move, Value> Searcher::search() {
264
262
265
263
const auto timeBegin = std::chrono::steady_clock::now ();
266
264
startTime = timeBegin;
267
- diagnosis.nodes = 0 ;
268
- diagnosis.qnodes = 0 ;
269
- result = negamax_root (1 , MATE_VALUE, MATED_VALUE);
270
- Value guessValue = result.second ;
271
-
272
- for (int depth = 2 ; depth <= 32 ; ++depth) {
273
- result = negamax_root (depth, MATE_VALUE, MATED_VALUE);
274
- if (searchAborted) {
275
- break ;
276
- }
277
-
278
- pvMoveFromIteration = result.first ;
279
- pvScoreFromIteration = result.second ;
280
- guessValue = pvScoreFromIteration;
281
265
266
+ for (int depth = 1 ; depth <= 32 ; ++depth) {
282
267
const auto timeEnd = std::chrono::steady_clock::now ();
283
268
const uint32_t timeElapsed =
284
269
std::chrono::duration_cast<std::chrono::milliseconds>(timeEnd -
285
270
timeBegin)
286
271
.count ();
287
- // Print uci output
288
- std::cout << " info depth " << depth << " score " << result.second
289
- << " seldepth " << (int )diagnosis.seldepth << " hashfull "
290
- << tt.hashfull () << " time " << timeElapsed << " nodes "
291
- << (int )diagnosis.nodes << " pv "
292
- << chess::uci::moveToUci (pvMoveFromIteration) << std::endl;
293
- // std::cout << "info string non-qs nodes: "
294
- // << (int)(diagnosis.nodes - diagnosis.qnodes) << std::endl;
295
-
296
272
if (timeElapsed > maxThinkingTime) {
297
273
break ;
298
274
}
275
+
276
+ result = negamax_root (depth, MATE_VALUE, MATED_VALUE);
277
+ if (searchAborted) {
278
+ break ;
279
+ }
280
+
281
+ // Print uci output
282
+ if (timeElapsed >= 1 ) {
283
+ uint64_t nps = diagnosis.nodes * 1000 / timeElapsed;
284
+ std::cout << " info depth " << depth << " score " << result.second
285
+ << " seldepth " << (int )diagnosis.seldepth << " hashfull "
286
+ << tt.hashfull () << " time " << timeElapsed << " nodes "
287
+ << (int )diagnosis.nodes << " nps " << nps << " pv "
288
+ << chess::uci::moveToUci (pvMoveFromIteration)
289
+ << std::endl;
290
+ } else {
291
+ std::cout << " info depth " << depth << " score " << result.second
292
+ << " seldepth " << (int )diagnosis.seldepth << " hashfull "
293
+ << tt.hashfull () << " time " << timeElapsed << " nodes "
294
+ << (int )diagnosis.nodes << std::endl;
295
+ }
296
+
297
+ pvMoveFromIteration = result.first ;
298
+ pvScoreFromIteration = result.second ;
299
299
}
300
300
std::cout << std::flush;
301
301
return {pvMoveFromIteration, pvScoreFromIteration};
0 commit comments