Subversion Repositories Games.Chess Giants

Rev

Rev 96 | Rev 169 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 96 Rev 154
Line 27... Line 27...
27
 
27
 
28
#include "evaluate.h"
28
#include "evaluate.h"
29
#include "misc.h"
29
#include "misc.h"
30
#include "movegen.h"
30
#include "movegen.h"
31
#include "movepick.h"
31
#include "movepick.h"
-
 
32
#include "position.h"
32
#include "search.h"
33
#include "search.h"
33
#include "timeman.h"
34
#include "timeman.h"
34
#include "thread.h"
35
#include "thread.h"
35
#include "tt.h"
36
#include "tt.h"
36
#include "uci.h"
37
#include "uci.h"
Line 38... Line 39...
38
 
39
 
39
namespace Search {
40
namespace Search {
40
 
41
 
41
  SignalsType Signals;
42
  SignalsType Signals;
42
  LimitsType Limits;
43
  LimitsType Limits;
43
  StateStackPtr SetupStates;
-
 
44
}
44
}
45
 
45
 
46
namespace Tablebases {
46
namespace Tablebases {
47
 
47
 
48
  int Cardinality;
48
  int Cardinality;
49
  uint64_t Hits;
-
 
50
  bool RootInTB;
49
  bool RootInTB;
51
  bool UseRule50;
50
  bool UseRule50;
52
  Depth ProbeDepth;
51
  Depth ProbeDepth;
53
  Value Score;
52
  Value Score;
54
}
53
}
Line 64... Line 63...
64
  // Different node types, used as a template parameter
63
  // Different node types, used as a template parameter
65
  enum NodeType { NonPV, PV };
64
  enum NodeType { NonPV, PV };
66
 
65
 
67
  // Razoring and futility margin based on depth
66
  // Razoring and futility margin based on depth
68
  const int razor_margin[4] = { 483, 570, 603, 554 };
67
  const int razor_margin[4] = { 483, 570, 603, 554 };
69
  Value futility_margin(Depth d) { return Value(200 * d); }
68
  Value futility_margin(Depth d) { return Value(150 * d / ONE_PLY); }
70
 
69
 
71
  // Futility and reductions lookup tables, initialized at startup
70
  // Futility and reductions lookup tables, initialized at startup
72
  int FutilityMoveCounts[2][16];  // [improving][depth]
71
  int FutilityMoveCounts[2][16]; // [improving][depth]
73
  Depth Reductions[2][2][64][64]; // [pv][improving][depth][moveNumber]
72
  int Reductions[2][2][64][64];  // [pv][improving][depth][moveNumber]
74
 
73
 
75
  template <bool PvNode> Depth reduction(bool i, Depth d, int mn) {
74
  template <bool PvNode> Depth reduction(bool i, Depth d, int mn) {
76
    return Reductions[PvNode][i][std::min(d, 63 * ONE_PLY)][std::min(mn, 63)];
75
    return Reductions[PvNode][i][std::min(d / ONE_PLY, 63)][std::min(mn, 63)] * ONE_PLY;
77
  }
76
  }
78
 
77
 
79
  // Skill structure is used to implement strength limit
78
  // Skill structure is used to implement strength limit
80
  struct Skill {
79
  struct Skill {
81
    Skill(int l) : level(l) {}
80
    Skill(int l) : level(l) {}
Line 112... Line 111...
112
      if (!std::equal(newPv.begin(), newPv.begin() + 3, pv))
111
      if (!std::equal(newPv.begin(), newPv.begin() + 3, pv))
113
      {
112
      {
114
          std::copy(newPv.begin(), newPv.begin() + 3, pv);
113
          std::copy(newPv.begin(), newPv.begin() + 3, pv);
115
 
114
 
116
          StateInfo st[2];
115
          StateInfo st[2];
117
          pos.do_move(newPv[0], st[0], pos.gives_check(newPv[0], CheckInfo(pos)));
116
          pos.do_move(newPv[0], st[0], pos.gives_check(newPv[0]));
118
          pos.do_move(newPv[1], st[1], pos.gives_check(newPv[1], CheckInfo(pos)));
117
          pos.do_move(newPv[1], st[1], pos.gives_check(newPv[1]));
119
          expectedPosKey = pos.key();
118
          expectedPosKey = pos.key();
120
          pos.undo_move(newPv[1]);
119
          pos.undo_move(newPv[1]);
121
          pos.undo_move(newPv[0]);
120
          pos.undo_move(newPv[0]);
122
      }
121
      }
123
    }
122
    }
Line 156... Line 155...
156
 
155
 
157
  const size_t HalfDensitySize = std::extent<decltype(HalfDensity)>::value;
156
  const size_t HalfDensitySize = std::extent<decltype(HalfDensity)>::value;
158
 
157
 
159
  EasyMoveManager EasyMove;
158
  EasyMoveManager EasyMove;
160
  Value DrawValue[COLOR_NB];
159
  Value DrawValue[COLOR_NB];
161
  CounterMoveHistoryStats CounterMoveHistory;
-
 
162
 
160
 
163
  template <NodeType NT>
161
  template <NodeType NT>
164
  Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode);
162
  Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode);
165
 
163
 
166
  template <NodeType NT, bool InCheck>
164
  template <NodeType NT, bool InCheck>
167
  Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth);
165
  Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth);
168
 
166
 
169
  Value value_to_tt(Value v, int ply);
167
  Value value_to_tt(Value v, int ply);
170
  Value value_from_tt(Value v, int ply);
168
  Value value_from_tt(Value v, int ply);
171
  void update_pv(Move* pv, Move move, Move* childPv);
169
  void update_pv(Move* pv, Move move, Move* childPv);
-
 
170
  void update_cm_stats(Stack* ss, Piece pc, Square s, Value bonus);
172
  void update_stats(const Position& pos, Stack* ss, Move move, Depth depth, Move* quiets, int quietsCnt);
171
  void update_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, Value bonus);
173
  void check_time();
172
  void check_time();
174
 
173
 
175
} // namespace
174
} // namespace
176
 
175
 
177
 
176
 
178
/// Search::init() is called during startup to initialize various lookup tables
177
/// Search::init() is called during startup to initialize various lookup tables
179
 
178
 
180
void Search::init() {
179
void Search::init() {
181
 
180
 
-
 
181
  for (int imp = 0; imp <= 1; ++imp)
-
 
182
      for (int d = 1; d < 64; ++d)
-
 
183
          for (int mc = 1; mc < 64; ++mc)
-
 
184
          {
182
  const double K[][2] = {{ 0.799, 2.281 }, { 0.484, 3.023 }};
185
              double r = log(d) * log(mc) / 2;
-
 
186
              if (r < 0.80)
-
 
187
                continue;
183
 
188
 
184
  for (int pv = 0; pv <= 1; ++pv)
-
 
185
      for (int imp = 0; imp <= 1; ++imp)
-
 
186
          for (int d = 1; d < 64; ++d)
-
 
187
              for (int mc = 1; mc < 64; ++mc)
189
              Reductions[NonPV][imp][d][mc] = int(std::round(r));
188
              {
-
 
189
                  double r = K[pv][0] + log(d) * log(mc) / K[pv][1];
190
              Reductions[PV][imp][d][mc] = std::max(Reductions[NonPV][imp][d][mc] - 1, 0);
190
 
191
 
191
                  if (r >= 1.5)
-
 
192
                      Reductions[pv][imp][d][mc] = int(r) * ONE_PLY;
-
 
193
 
-
 
194
                  // Increase reduction when eval is not improving
192
              // Increase reduction for non-PV nodes when eval is not improving
195
                  if (!pv && !imp && Reductions[pv][imp][d][mc] >= 2 * ONE_PLY)
193
              if (!imp && Reductions[NonPV][imp][d][mc] >= 2)
196
                      Reductions[pv][imp][d][mc] += ONE_PLY;
194
                Reductions[NonPV][imp][d][mc]++;
197
              }
195
          }
198
 
196
 
199
  for (int d = 0; d < 16; ++d)
197
  for (int d = 0; d < 16; ++d)
200
  {
198
  {
201
      FutilityMoveCounts[0][d] = int(2.4 + 0.773 * pow(d + 0.00, 1.8));
199
      FutilityMoveCounts[0][d] = int(2.4 + 0.773 * pow(d + 0.00, 1.8));
202
      FutilityMoveCounts[1][d] = int(2.9 + 1.045 * pow(d + 0.49, 1.8));
200
      FutilityMoveCounts[1][d] = int(2.9 + 1.045 * pow(d + 0.49, 1.8));
Line 207... Line 205...
207
/// Search::clear() resets search state to zero, to obtain reproducible results
205
/// Search::clear() resets search state to zero, to obtain reproducible results
208
 
206
 
209
void Search::clear() {
207
void Search::clear() {
210
 
208
 
211
  TT.clear();
209
  TT.clear();
212
  CounterMoveHistory.clear();
-
 
213
 
210
 
214
  for (Thread* th : Threads)
211
  for (Thread* th : Threads)
215
  {
212
  {
216
      th->history.clear();
213
      th->history.clear();
217
      th->counterMoves.clear();
214
      th->counterMoves.clear();
-
 
215
      th->fromTo.clear();
-
 
216
      th->counterMoveHistory.clear();
218
  }
217
  }
219
 
218
 
220
  Threads.main()->previousScore = VALUE_INFINITE;
219
  Threads.main()->previousScore = VALUE_INFINITE;
221
}
220
}
222
 
221
 
Line 226... Line 225...
226
template<bool Root>
225
template<bool Root>
227
uint64_t Search::perft(Position& pos, Depth depth) {
226
uint64_t Search::perft(Position& pos, Depth depth) {
228
 
227
 
229
  StateInfo st;
228
  StateInfo st;
230
  uint64_t cnt, nodes = 0;
229
  uint64_t cnt, nodes = 0;
231
  CheckInfo ci(pos);
-
 
232
  const bool leaf = (depth == 2 * ONE_PLY);
230
  const bool leaf = (depth == 2 * ONE_PLY);
233
 
231
 
234
  for (const auto& m : MoveList<LEGAL>(pos))
232
  for (const auto& m : MoveList<LEGAL>(pos))
235
  {
233
  {
236
      if (Root && depth <= ONE_PLY)
234
      if (Root && depth <= ONE_PLY)
237
          cnt = 1, nodes++;
235
          cnt = 1, nodes++;
238
      else
236
      else
239
      {
237
      {
240
          pos.do_move(m, st, pos.gives_check(m, ci));
238
          pos.do_move(m, st, pos.gives_check(m));
241
          cnt = leaf ? MoveList<LEGAL>(pos).size() : perft<false>(pos, depth - ONE_PLY);
239
          cnt = leaf ? MoveList<LEGAL>(pos).size() : perft<false>(pos, depth - ONE_PLY);
242
          nodes += cnt;
240
          nodes += cnt;
243
          pos.undo_move(m);
241
          pos.undo_move(m);
244
      }
242
      }
245
      if (Root)
243
      if (Root)
Line 260... Line 258...
260
  Time.init(Limits, us, rootPos.game_ply());
258
  Time.init(Limits, us, rootPos.game_ply());
261
 
259
 
262
  int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
260
  int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
263
  DrawValue[ us] = VALUE_DRAW - Value(contempt);
261
  DrawValue[ us] = VALUE_DRAW - Value(contempt);
264
  DrawValue[~us] = VALUE_DRAW + Value(contempt);
262
  DrawValue[~us] = VALUE_DRAW + Value(contempt);
265
 
-
 
266
  TB::Hits = 0;
-
 
267
  TB::RootInTB = false;
-
 
268
  TB::UseRule50 = Options["Syzygy50MoveRule"];
-
 
269
  TB::ProbeDepth = Options["SyzygyProbeDepth"] * ONE_PLY;
-
 
270
  TB::Cardinality = Options["SyzygyProbeLimit"];
-
 
271
 
-
 
272
  // Skip TB probing when no TB found: !TBLargest -> !TB::Cardinality
-
 
273
  if (TB::Cardinality > TB::MaxCardinality)
-
 
274
  {
-
 
275
      TB::Cardinality = TB::MaxCardinality;
-
 
276
      TB::ProbeDepth = DEPTH_ZERO;
-
 
277
  }
-
 
278
 
263
 
279
  if (rootMoves.empty())
264
  if (rootMoves.empty())
280
  {
265
  {
281
      rootMoves.push_back(RootMove(MOVE_NONE));
266
      rootMoves.push_back(RootMove(MOVE_NONE));
282
      sync_cout << "info depth 0 score "
267
      sync_cout << "info depth 0 score "
283
                << UCI::value(rootPos.checkers() ? -VALUE_MATE : VALUE_DRAW)
268
                << UCI::value(rootPos.checkers() ? -VALUE_MATE : VALUE_DRAW)
284
                << sync_endl;
269
                << sync_endl;
285
  }
270
  }
286
  else
271
  else
287
  {
272
  {
288
      if (    TB::Cardinality >=  rootPos.count<ALL_PIECES>(WHITE)
-
 
289
                                + rootPos.count<ALL_PIECES>(BLACK)
-
 
290
          && !rootPos.can_castle(ANY_CASTLING))
-
 
291
      {
-
 
292
          // If the current root position is in the tablebases, then RootMoves
-
 
293
          // contains only moves that preserve the draw or the win.
-
 
294
          TB::RootInTB = Tablebases::root_probe(rootPos, rootMoves, TB::Score);
-
 
295
 
-
 
296
          if (TB::RootInTB)
-
 
297
              TB::Cardinality = 0; // Do not probe tablebases during the search
-
 
298
 
-
 
299
          else // If DTZ tables are missing, use WDL tables as a fallback
-
 
300
          {
-
 
301
              // Filter out moves that do not preserve the draw or the win.
-
 
302
              TB::RootInTB = Tablebases::root_probe_wdl(rootPos, rootMoves, TB::Score);
-
 
303
 
-
 
304
              // Only probe during search if winning
-
 
305
              if (TB::Score <= VALUE_DRAW)
-
 
306
                  TB::Cardinality = 0;
-
 
307
          }
-
 
308
 
-
 
309
          if (TB::RootInTB)
-
 
310
          {
-
 
311
              TB::Hits = rootMoves.size();
-
 
312
 
-
 
313
              if (!TB::UseRule50)
-
 
314
                  TB::Score =  TB::Score > VALUE_DRAW ?  VALUE_MATE - MAX_PLY - 1
-
 
315
                             : TB::Score < VALUE_DRAW ? -VALUE_MATE + MAX_PLY + 1
-
 
316
                                                      :  VALUE_DRAW;
-
 
317
          }
-
 
318
      }
-
 
319
 
-
 
320
      for (Thread* th : Threads)
273
      for (Thread* th : Threads)
321
      {
-
 
322
          th->maxPly = 0;
-
 
323
          th->rootDepth = DEPTH_ZERO;
-
 
324
          if (th != this)
274
          if (th != this)
325
          {
-
 
326
              th->rootPos = Position(rootPos, th);
-
 
327
              th->rootMoves = rootMoves;
-
 
328
              th->start_searching();
275
              th->start_searching();
329
          }
-
 
330
      }
-
 
331
 
276
 
332
      Thread::search(); // Let's start searching!
277
      Thread::search(); // Let's start searching!
333
  }
278
  }
334
 
279
 
335
  // When playing in 'nodes as time' mode, subtract the searched nodes from
280
  // When playing in 'nodes as time' mode, subtract the searched nodes from
Line 358... Line 303...
358
 
303
 
359
  // Check if there are threads with a better score than main thread
304
  // Check if there are threads with a better score than main thread
360
  Thread* bestThread = this;
305
  Thread* bestThread = this;
361
  if (   !this->easyMovePlayed
306
  if (   !this->easyMovePlayed
362
      &&  Options["MultiPV"] == 1
307
      &&  Options["MultiPV"] == 1
-
 
308
      && !Limits.depth
363
      && !Skill(Options["Skill Level"]).enabled())
309
      && !Skill(Options["Skill Level"]).enabled()
-
 
310
      &&  rootMoves[0].pv[0] != MOVE_NONE)
364
  {
311
  {
365
      for (Thread* th : Threads)
312
      for (Thread* th : Threads)
366
          if (   th->completedDepth > bestThread->completedDepth
313
          if (   th->completedDepth > bestThread->completedDepth
367
              && th->rootMoves[0].score > bestThread->rootMoves[0].score)
314
              && th->rootMoves[0].score > bestThread->rootMoves[0].score)
368
              bestThread = th;
315
              bestThread = th;
Line 387... Line 334...
387
// repeatedly with increasing depth until the allocated thinking time has been
334
// repeatedly with increasing depth until the allocated thinking time has been
388
// consumed, the user stops the search, or the maximum search depth is reached.
335
// consumed, the user stops the search, or the maximum search depth is reached.
389
 
336
 
390
void Thread::search() {
337
void Thread::search() {
391
 
338
 
392
  Stack stack[MAX_PLY+4], *ss = stack+2; // To allow referencing (ss-2) and (ss+2)
339
  Stack stack[MAX_PLY+7], *ss = stack+5; // To allow referencing (ss-5) and (ss+2)
393
  Value bestValue, alpha, beta, delta;
340
  Value bestValue, alpha, beta, delta;
394
  Move easyMove = MOVE_NONE;
341
  Move easyMove = MOVE_NONE;
395
  MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
342
  MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
396
 
343
 
397
  std::memset(ss-2, 0, 5 * sizeof(Stack));
344
  std::memset(ss-5, 0, 8 * sizeof(Stack));
398
 
345
 
399
  bestValue = delta = alpha = -VALUE_INFINITE;
346
  bestValue = delta = alpha = -VALUE_INFINITE;
400
  beta = VALUE_INFINITE;
347
  beta = VALUE_INFINITE;
401
  completedDepth = DEPTH_ZERO;
348
  completedDepth = DEPTH_ZERO;
402
 
349
 
Line 417... Line 364...
417
  if (skill.enabled())
364
  if (skill.enabled())
418
      multiPV = std::max(multiPV, (size_t)4);
365
      multiPV = std::max(multiPV, (size_t)4);
419
 
366
 
420
  multiPV = std::min(multiPV, rootMoves.size());
367
  multiPV = std::min(multiPV, rootMoves.size());
421
 
368
 
422
  // Iterative deepening loop until requested to stop or the target depth is reached.
369
  // Iterative deepening loop until requested to stop or the target depth is reached
-
 
370
  while (   (rootDepth += ONE_PLY) < DEPTH_MAX
-
 
371
         && !Signals.stop
423
  while (++rootDepth < DEPTH_MAX && !Signals.stop && (!Limits.depth || rootDepth <= Limits.depth))
372
         && (!Limits.depth || Threads.main()->rootDepth / ONE_PLY <= Limits.depth))
424
  {
373
  {
425
      // Set up the new depths for the helper threads skipping on average every
374
      // Set up the new depths for the helper threads skipping on average every
426
      // 2nd ply (using a half-density matrix).
375
      // 2nd ply (using a half-density matrix).
427
      if (!mainThread)
376
      if (!mainThread)
428
      {
377
      {
429
          const Row& row = HalfDensity[(idx - 1) % HalfDensitySize];
378
          const Row& row = HalfDensity[(idx - 1) % HalfDensitySize];
430
          if (row[(rootDepth + rootPos.game_ply()) % row.size()])
379
          if (row[(rootDepth / ONE_PLY + rootPos.game_ply()) % row.size()])
431
             continue;
380
             continue;
432
      }
381
      }
433
 
382
 
434
      // Age out PV variability metric
383
      // Age out PV variability metric
435
      if (mainThread)
384
      if (mainThread)
Line 463... Line 412...
463
              // first and eventually the new best one are set to -VALUE_INFINITE
412
              // first and eventually the new best one are set to -VALUE_INFINITE
464
              // and we want to keep the same order for all the moves except the
413
              // and we want to keep the same order for all the moves except the
465
              // new PV that goes to the front. Note that in case of MultiPV
414
              // new PV that goes to the front. Note that in case of MultiPV
466
              // search the already searched PV lines are preserved.
415
              // search the already searched PV lines are preserved.
467
              std::stable_sort(rootMoves.begin() + PVIdx, rootMoves.end());
416
              std::stable_sort(rootMoves.begin() + PVIdx, rootMoves.end());
468
 
-
 
469
              // Write PV back to the transposition table in case the relevant
-
 
470
              // entries have been overwritten during the search.
-
 
471
              for (size_t i = 0; i <= PVIdx; ++i)
-
 
472
                  rootMoves[i].insert_pv_in_tt(rootPos);
-
 
473
 
417
 
474
              // If search has been stopped, break immediately. Sorting and
418
              // If search has been stopped, break immediately. Sorting and
475
              // writing PV back to TT is safe because RootMoves is still
419
              // writing PV back to TT is safe because RootMoves is still
476
              // valid, although it refers to the previous iteration.
420
              // valid, although it refers to the previous iteration.
477
              if (Signals.stop)
421
              if (Signals.stop)
Line 513... Line 457...
513
 
457
 
514
          // Sort the PV lines searched so far and update the GUI
458
          // Sort the PV lines searched so far and update the GUI
515
          std::stable_sort(rootMoves.begin(), rootMoves.begin() + PVIdx + 1);
459
          std::stable_sort(rootMoves.begin(), rootMoves.begin() + PVIdx + 1);
516
 
460
 
517
          if (!mainThread)
461
          if (!mainThread)
518
              break;
462
              continue;
519
 
-
 
520
          if (Signals.stop)
-
 
521
              sync_cout << "info nodes " << Threads.nodes_searched()
-
 
522
                        << " time " << Time.elapsed() << sync_endl;
-
 
523
 
463
 
524
          else if (PVIdx + 1 == multiPV || Time.elapsed() > 3000)
464
          if (Signals.stop || PVIdx + 1 == multiPV || Time.elapsed() > 3000)
525
              sync_cout << UCI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
465
              sync_cout << UCI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
526
      }
466
      }
527
 
467
 
528
      if (!Signals.stop)
468
      if (!Signals.stop)
529
          completedDepth = rootDepth;
469
          completedDepth = rootDepth;
Line 547... Line 487...
547
          if (!Signals.stop && !Signals.stopOnPonderhit)
487
          if (!Signals.stop && !Signals.stopOnPonderhit)
548
          {
488
          {
549
              // Stop the search if only one legal move is available, or if all
489
              // Stop the search if only one legal move is available, or if all
550
              // of the available time has been used, or if we matched an easyMove
490
              // of the available time has been used, or if we matched an easyMove
551
              // from the previous search and just did a fast verification.
491
              // from the previous search and just did a fast verification.
552
              const bool F[] = { !mainThread->failedLow,
492
              const int F[] = { mainThread->failedLow,
553
                                 bestValue >= mainThread->previousScore };
493
                                bestValue - mainThread->previousScore };
554
 
494
 
555
              int improvingFactor = 640 - 160*F[0] - 126*F[1] - 124*F[0]*F[1];
495
              int improvingFactor = std::max(229, std::min(715, 357 + 119 * F[0] - 6 * F[1]));
556
              double unstablePvFactor = 1 + mainThread->bestMoveChanges;
496
              double unstablePvFactor = 1 + mainThread->bestMoveChanges;
557
 
497
 
558
              bool doEasyMove =   rootMoves[0].pv[0] == easyMove
498
              bool doEasyMove =   rootMoves[0].pv[0] == easyMove
559
                               && mainThread->bestMoveChanges < 0.03
499
                               && mainThread->bestMoveChanges < 0.03
560
                               && Time.elapsed() > Time.optimum() * 25 / 204;
500
                               && Time.elapsed() > Time.optimum() * 5 / 42;
561
 
501
 
562
              if (   rootMoves.size() == 1
502
              if (   rootMoves.size() == 1
563
                  || Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 634
503
                  || Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 628
564
                  || (mainThread->easyMovePlayed = doEasyMove))
504
                  || (mainThread->easyMovePlayed = doEasyMove, doEasyMove))
565
              {
505
              {
566
                  // If we are allowed to ponder do not stop the search now but
506
                  // If we are allowed to ponder do not stop the search now but
567
                  // keep pondering until the GUI sends "ponderhit" or "stop".
507
                  // keep pondering until the GUI sends "ponderhit" or "stop".
568
                  if (Limits.ponder)
508
                  if (Limits.ponder)
569
                      Signals.stopOnPonderhit = true;
509
                      Signals.stopOnPonderhit = true;
Line 605... Line 545...
605
    const bool rootNode = PvNode && (ss-1)->ply == 0;
545
    const bool rootNode = PvNode && (ss-1)->ply == 0;
606
 
546
 
607
    assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE);
547
    assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE);
608
    assert(PvNode || (alpha == beta - 1));
548
    assert(PvNode || (alpha == beta - 1));
609
    assert(DEPTH_ZERO < depth && depth < DEPTH_MAX);
549
    assert(DEPTH_ZERO < depth && depth < DEPTH_MAX);
-
 
550
    assert(!(PvNode && cutNode));
-
 
551
    assert(depth / ONE_PLY * ONE_PLY == depth);
610
 
552
 
611
    Move pv[MAX_PLY+1], quietsSearched[64];
553
    Move pv[MAX_PLY+1], quietsSearched[64];
612
    StateInfo st;
554
    StateInfo st;
613
    TTEntry* tte;
555
    TTEntry* tte;
614
    Key posKey;
556
    Key posKey;
615
    Move ttMove, move, excludedMove, bestMove;
557
    Move ttMove, move, excludedMove, bestMove;
616
    Depth extension, newDepth, predictedDepth;
558
    Depth extension, newDepth;
617
    Value bestValue, value, ttValue, eval, nullValue, futilityValue;
559
    Value bestValue, value, ttValue, eval, nullValue;
618
    bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
560
    bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
619
    bool captureOrPromotion, doFullDepthSearch;
561
    bool captureOrPromotion, doFullDepthSearch, moveCountPruning;
-
 
562
    Piece moved_piece;
620
    int moveCount, quietCount;
563
    int moveCount, quietCount;
621
 
564
 
622
    // Step 1. Initialize node
565
    // Step 1. Initialize node
623
    Thread* thisThread = pos.this_thread();
566
    Thread* thisThread = pos.this_thread();
624
    inCheck = pos.checkers();
567
    inCheck = pos.checkers();
625
    moveCount = quietCount =  ss->moveCount = 0;
568
    moveCount = quietCount =  ss->moveCount = 0;
-
 
569
    ss->history = VALUE_ZERO;
626
    bestValue = -VALUE_INFINITE;
570
    bestValue = -VALUE_INFINITE;
627
    ss->ply = (ss-1)->ply + 1;
571
    ss->ply = (ss-1)->ply + 1;
628
 
572
 
629
    // Check for the available remaining time
573
    // Check for the available remaining time
630
    if (thisThread->resetCalls.load(std::memory_order_relaxed))
574
    if (thisThread->resetCalls.load(std::memory_order_relaxed))
Line 664... Line 608...
664
    }
608
    }
665
 
609
 
666
    assert(0 <= ss->ply && ss->ply < MAX_PLY);
610
    assert(0 <= ss->ply && ss->ply < MAX_PLY);
667
 
611
 
668
    ss->currentMove = (ss+1)->excludedMove = bestMove = MOVE_NONE;
612
    ss->currentMove = (ss+1)->excludedMove = bestMove = MOVE_NONE;
-
 
613
    ss->counterMoves = nullptr;
669
    (ss+1)->skipEarlyPruning = false;
614
    (ss+1)->skipEarlyPruning = false;
670
    (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
615
    (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
671
 
616
 
672
    // Step 4. Transposition table lookup. We don't want the score of a partial
617
    // Step 4. Transposition table lookup. We don't want the score of a partial
673
    // search to overwrite a previous full search TT value, so we use a different
618
    // search to overwrite a previous full search TT value, so we use a different
674
    // position key in case of an excluded move.
619
    // position key in case of an excluded move.
675
    excludedMove = ss->excludedMove;
620
    excludedMove = ss->excludedMove;
676
    posKey = excludedMove ? pos.exclusion_key() : pos.key();
621
    posKey = pos.key() ^ Key(excludedMove);
677
    tte = TT.probe(posKey, ttHit);
622
    tte = TT.probe(posKey, ttHit);
678
    ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
623
    ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
679
    ttMove =  rootNode ? thisThread->rootMoves[thisThread->PVIdx].pv[0]
624
    ttMove =  rootNode ? thisThread->rootMoves[thisThread->PVIdx].pv[0]
680
            : ttHit    ? tte->move() : MOVE_NONE;
625
            : ttHit    ? tte->move() : MOVE_NONE;
681
 
626
 
Line 685... Line 630...
685
        && tte->depth() >= depth
630
        && tte->depth() >= depth
686
        && ttValue != VALUE_NONE // Possible in case of TT access race
631
        && ttValue != VALUE_NONE // Possible in case of TT access race
687
        && (ttValue >= beta ? (tte->bound() & BOUND_LOWER)
632
        && (ttValue >= beta ? (tte->bound() & BOUND_LOWER)
688
                            : (tte->bound() & BOUND_UPPER)))
633
                            : (tte->bound() & BOUND_UPPER)))
689
    {
634
    {
690
        ss->currentMove = ttMove; // Can be MOVE_NONE
-
 
691
 
-
 
692
        // If ttMove is quiet, update killers, history, counter move on TT hit
635
        // If ttMove is quiet, update killers, history, counter move on TT hit
693
        if (ttValue >= beta && ttMove && !pos.capture_or_promotion(ttMove))
636
        if (ttValue >= beta && ttMove)
-
 
637
        {
694
            update_stats(pos, ss, ttMove, depth, nullptr, 0);
638
            int d = depth / ONE_PLY;
695
 
639
 
-
 
640
            if (!pos.capture_or_promotion(ttMove))
-
 
641
            {
-
 
642
                Value bonus = Value(d * d + 2 * d - 2);
-
 
643
                update_stats(pos, ss, ttMove, nullptr, 0, bonus);
-
 
644
            }
-
 
645
 
-
 
646
            // Extra penalty for a quiet TT move in previous ply when it gets refuted
-
 
647
            if ((ss-1)->moveCount == 1 && !pos.captured_piece())
-
 
648
            {
-
 
649
                Value penalty = Value(d * d + 4 * d + 1);
-
 
650
                Square prevSq = to_sq((ss-1)->currentMove);
-
 
651
                update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, -penalty);
-
 
652
            }
-
 
653
        }
696
        return ttValue;
654
        return ttValue;
697
    }
655
    }
698
 
656
 
699
    // Step 4a. Tablebase probe
657
    // Step 4a. Tablebase probe
700
    if (!rootNode && TB::Cardinality)
658
    if (!rootNode && TB::Cardinality)
Line 708... Line 666...
708
        {
666
        {
709
            int found, v = Tablebases::probe_wdl(pos, &found);
667
            int found, v = Tablebases::probe_wdl(pos, &found);
710
 
668
 
711
            if (found)
669
            if (found)
712
            {
670
            {
713
                TB::Hits++;
671
                thisThread->tbHits++;
714
 
672
 
715
                int drawScore = TB::UseRule50 ? 1 : 0;
673
                int drawScore = TB::UseRule50 ? 1 : 0;
716
 
674
 
717
                value =  v < -drawScore ? -VALUE_MATE + MAX_PLY + ss->ply
675
                value =  v < -drawScore ? -VALUE_MATE + MAX_PLY + ss->ply
718
                       : v >  drawScore ?  VALUE_MATE - MAX_PLY - ss->ply
676
                       : v >  drawScore ?  VALUE_MATE - MAX_PLY - ss->ply
Line 759... Line 717...
759
        goto moves_loop;
717
        goto moves_loop;
760
 
718
 
761
    // Step 6. Razoring (skipped when in check)
719
    // Step 6. Razoring (skipped when in check)
762
    if (   !PvNode
720
    if (   !PvNode
763
        &&  depth < 4 * ONE_PLY
721
        &&  depth < 4 * ONE_PLY
764
        &&  eval + razor_margin[depth] <= alpha
-
 
765
        &&  ttMove == MOVE_NONE)
722
        &&  ttMove == MOVE_NONE
-
 
723
        &&  eval + razor_margin[depth / ONE_PLY] <= alpha)
766
    {
724
    {
767
        if (   depth <= ONE_PLY
725
        if (depth <= ONE_PLY)
768
            && eval + razor_margin[3 * ONE_PLY] <= alpha)
-
 
769
            return qsearch<NonPV, false>(pos, ss, alpha, beta, DEPTH_ZERO);
726
            return qsearch<NonPV, false>(pos, ss, alpha, beta, DEPTH_ZERO);
770
 
727
 
771
        Value ralpha = alpha - razor_margin[depth];
728
        Value ralpha = alpha - razor_margin[depth / ONE_PLY];
772
        Value v = qsearch<NonPV, false>(pos, ss, ralpha, ralpha+1, DEPTH_ZERO);
729
        Value v = qsearch<NonPV, false>(pos, ss, ralpha, ralpha+1, DEPTH_ZERO);
773
        if (v <= ralpha)
730
        if (v <= ralpha)
774
            return v;
731
            return v;
775
    }
732
    }
776
 
733
 
Line 778... Line 735...
778
    if (   !rootNode
735
    if (   !rootNode
779
        &&  depth < 7 * ONE_PLY
736
        &&  depth < 7 * ONE_PLY
780
        &&  eval - futility_margin(depth) >= beta
737
        &&  eval - futility_margin(depth) >= beta
781
        &&  eval < VALUE_KNOWN_WIN  // Do not return unproven wins
738
        &&  eval < VALUE_KNOWN_WIN  // Do not return unproven wins
782
        &&  pos.non_pawn_material(pos.side_to_move()))
739
        &&  pos.non_pawn_material(pos.side_to_move()))
783
        return eval - futility_margin(depth);
740
        return eval;
784
 
741
 
785
    // Step 8. Null move search with verification search (is omitted in PV nodes)
742
    // Step 8. Null move search with verification search (is omitted in PV nodes)
786
    if (   !PvNode
743
    if (   !PvNode
787
        &&  depth >= 2 * ONE_PLY
-
 
788
        &&  eval >= beta
744
        &&  eval >= beta
-
 
745
        && (ss->staticEval >= beta - 35 * (depth / ONE_PLY - 6) || depth >= 13 * ONE_PLY)
789
        &&  pos.non_pawn_material(pos.side_to_move()))
746
        &&  pos.non_pawn_material(pos.side_to_move()))
790
    {
747
    {
791
        ss->currentMove = MOVE_NULL;
748
        ss->currentMove = MOVE_NULL;
-
 
749
        ss->counterMoves = nullptr;
792
 
750
 
793
        assert(eval - beta >= 0);
751
        assert(eval - beta >= 0);
794
 
752
 
795
        // Null move dynamic reduction based on depth and value
753
        // Null move dynamic reduction based on depth and value
796
        Depth R = ((823 + 67 * depth) / 256 + std::min((eval - beta) / PawnValueMg, 3)) * ONE_PLY;
754
        Depth R = ((823 + 67 * depth / ONE_PLY) / 256 + std::min((eval - beta) / PawnValueMg, 3)) * ONE_PLY;
797
 
755
 
798
        pos.do_null_move(st);
756
        pos.do_null_move(st);
799
        (ss+1)->skipEarlyPruning = true;
757
        (ss+1)->skipEarlyPruning = true;
800
        nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -beta+1, DEPTH_ZERO)
758
        nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -beta+1, DEPTH_ZERO)
801
                                      : - search<NonPV>(pos, ss+1, -beta, -beta+1, depth-R, !cutNode);
759
                                      : - search<NonPV>(pos, ss+1, -beta, -beta+1, depth-R, !cutNode);
Line 821... Line 779...
821
                return nullValue;
779
                return nullValue;
822
        }
780
        }
823
    }
781
    }
824
 
782
 
825
    // Step 9. ProbCut (skipped when in check)
783
    // Step 9. ProbCut (skipped when in check)
826
    // If we have a very good capture (i.e. SEE > seeValues[captured_piece_type])
784
    // If we have a good enough capture and a reduced search returns a value
827
    // and a reduced search returns a value much above beta, we can (almost)
-
 
828
    // safely prune the previous move.
785
    // much above beta, we can (almost) safely prune the previous move.
829
    if (   !PvNode
786
    if (   !PvNode
830
        &&  depth >= 5 * ONE_PLY
787
        &&  depth >= 5 * ONE_PLY
831
        &&  abs(beta) < VALUE_MATE_IN_MAX_PLY)
788
        &&  abs(beta) < VALUE_MATE_IN_MAX_PLY)
832
    {
789
    {
833
        Value rbeta = std::min(beta + 200, VALUE_INFINITE);
790
        Value rbeta = std::min(beta + 200, VALUE_INFINITE);
Line 835... Line 792...
835
 
792
 
836
        assert(rdepth >= ONE_PLY);
793
        assert(rdepth >= ONE_PLY);
837
        assert((ss-1)->currentMove != MOVE_NONE);
794
        assert((ss-1)->currentMove != MOVE_NONE);
838
        assert((ss-1)->currentMove != MOVE_NULL);
795
        assert((ss-1)->currentMove != MOVE_NULL);
839
 
796
 
840
        MovePicker mp(pos, ttMove, thisThread->history, PieceValue[MG][pos.captured_piece_type()]);
797
        MovePicker mp(pos, ttMove, rbeta - ss->staticEval);
841
        CheckInfo ci(pos);
-
 
842
 
798
 
843
        while ((move = mp.next_move()) != MOVE_NONE)
799
        while ((move = mp.next_move()) != MOVE_NONE)
844
            if (pos.legal(move, ci.pinned))
800
            if (pos.legal(move))
845
            {
801
            {
846
                ss->currentMove = move;
802
                ss->currentMove = move;
-
 
803
                ss->counterMoves = &thisThread->counterMoveHistory[pos.moved_piece(move)][to_sq(move)];
847
                pos.do_move(move, st, pos.gives_check(move, ci));
804
                pos.do_move(move, st, pos.gives_check(move));
848
                value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, rdepth, !cutNode);
805
                value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, rdepth, !cutNode);
849
                pos.undo_move(move);
806
                pos.undo_move(move);
850
                if (value >= rbeta)
807
                if (value >= rbeta)
851
                    return value;
808
                    return value;
852
            }
809
            }
853
    }
810
    }
854
 
811
 
855
    // Step 10. Internal iterative deepening (skipped when in check)
812
    // Step 10. Internal iterative deepening (skipped when in check)
856
    if (    depth >= (PvNode ? 5 * ONE_PLY : 8 * ONE_PLY)
813
    if (    depth >= 6 * ONE_PLY
857
        && !ttMove
814
        && !ttMove
858
        && (PvNode || ss->staticEval + 256 >= beta))
815
        && (PvNode || ss->staticEval + 256 >= beta))
859
    {
816
    {
860
        Depth d = depth - 2 * ONE_PLY - (PvNode ? DEPTH_ZERO : depth / 4);
817
        Depth d = (3 * depth / (4 * ONE_PLY) - 2) * ONE_PLY;
861
        ss->skipEarlyPruning = true;
818
        ss->skipEarlyPruning = true;
862
        search<NT>(pos, ss, alpha, beta, d, true);
819
        search<NT>(pos, ss, alpha, beta, d, cutNode);
863
        ss->skipEarlyPruning = false;
820
        ss->skipEarlyPruning = false;
864
 
821
 
865
        tte = TT.probe(posKey, ttHit);
822
        tte = TT.probe(posKey, ttHit);
866
        ttMove = ttHit ? tte->move() : MOVE_NONE;
823
        ttMove = ttHit ? tte->move() : MOVE_NONE;
867
    }
824
    }
868
 
825
 
869
moves_loop: // When in check search starts from here
826
moves_loop: // When in check search starts from here
870
 
827
 
871
    Square prevSq = to_sq((ss-1)->currentMove);
828
    const CounterMoveStats* cmh  = (ss-1)->counterMoves;
872
    Move cm = thisThread->counterMoves[pos.piece_on(prevSq)][prevSq];
829
    const CounterMoveStats* fmh  = (ss-2)->counterMoves;
873
    const CounterMoveStats& cmh = CounterMoveHistory[pos.piece_on(prevSq)][prevSq];
830
    const CounterMoveStats* fmh2 = (ss-4)->counterMoves;
874
 
831
 
875
    MovePicker mp(pos, ttMove, depth, thisThread->history, cmh, cm, ss);
832
    MovePicker mp(pos, ttMove, depth, ss);
876
    CheckInfo ci(pos);
-
 
877
    value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
833
    value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
878
    improving =   ss->staticEval >= (ss-2)->staticEval
834
    improving =   ss->staticEval >= (ss-2)->staticEval
879
               || ss->staticEval == VALUE_NONE
835
            /* || ss->staticEval == VALUE_NONE Already implicit in the previous condition */
880
               ||(ss-2)->staticEval == VALUE_NONE;
836
               ||(ss-2)->staticEval == VALUE_NONE;
881
 
837
 
882
    singularExtensionNode =   !rootNode
838
    singularExtensionNode =   !rootNode
883
                           &&  depth >= 8 * ONE_PLY
839
                           &&  depth >= 8 * ONE_PLY
884
                           &&  ttMove != MOVE_NONE
840
                           &&  ttMove != MOVE_NONE
885
                       /*  &&  ttValue != VALUE_NONE Already implicit in the next condition */
-
 
886
                           &&  abs(ttValue) < VALUE_KNOWN_WIN
841
                           &&  ttValue != VALUE_NONE
887
                           && !excludedMove // Recursive singular search is not allowed
842
                           && !excludedMove // Recursive singular search is not allowed
888
                           && (tte->bound() & BOUND_LOWER)
843
                           && (tte->bound() & BOUND_LOWER)
889
                           &&  tte->depth() >= depth - 3 * ONE_PLY;
844
                           &&  tte->depth() >= depth - 3 * ONE_PLY;
890
 
845
 
891
    // Step 11. Loop through moves
846
    // Step 11. Loop through moves
Line 914... Line 869...
914
      if (PvNode)
869
      if (PvNode)
915
          (ss+1)->pv = nullptr;
870
          (ss+1)->pv = nullptr;
916
 
871
 
917
      extension = DEPTH_ZERO;
872
      extension = DEPTH_ZERO;
918
      captureOrPromotion = pos.capture_or_promotion(move);
873
      captureOrPromotion = pos.capture_or_promotion(move);
-
 
874
      moved_piece = pos.moved_piece(move);
919
 
875
 
920
      givesCheck =  type_of(move) == NORMAL && !ci.dcCandidates
876
      givesCheck =  type_of(move) == NORMAL && !pos.discovered_check_candidates()
921
                  ? ci.checkSquares[type_of(pos.piece_on(from_sq(move)))] & to_sq(move)
877
                  ? pos.check_squares(type_of(pos.piece_on(from_sq(move)))) & to_sq(move)
922
                  : pos.gives_check(move, ci);
878
                  : pos.gives_check(move);
-
 
879
 
-
 
880
      moveCountPruning =   depth < 16 * ONE_PLY
-
 
881
                        && moveCount >= FutilityMoveCounts[improving][depth / ONE_PLY];
923
 
882
 
924
      // Step 12. Extend checks
883
      // Step 12. Extend checks
-
 
884
      if (    givesCheck
-
 
885
          && !moveCountPruning
925
      if (givesCheck && pos.see_sign(move) >= VALUE_ZERO)
886
          &&  pos.see_ge(move, VALUE_ZERO))
926
          extension = ONE_PLY;
887
          extension = ONE_PLY;
927
 
888
 
928
      // Singular extension search. If all moves but one fail low on a search of
889
      // Singular extension search. If all moves but one fail low on a search of
929
      // (alpha-s, beta-s), and just one fails high on (alpha, beta), then that move
890
      // (alpha-s, beta-s), and just one fails high on (alpha, beta), then that move
930
      // is singular and should be extended. To verify this we do a reduced search
891
      // is singular and should be extended. To verify this we do a reduced search
931
      // on all the other moves but the ttMove and if the result is lower than
892
      // on all the other moves but the ttMove and if the result is lower than
932
      // ttValue minus a margin then we extend the ttMove.
893
      // ttValue minus a margin then we extend the ttMove.
933
      if (    singularExtensionNode
894
      if (    singularExtensionNode
934
          &&  move == ttMove
895
          &&  move == ttMove
935
          && !extension
896
          && !extension
936
          &&  pos.legal(move, ci.pinned))
897
          &&  pos.legal(move))
937
      {
898
      {
938
          Value rBeta = ttValue - 2 * depth / ONE_PLY;
899
          Value rBeta = std::max(ttValue - 2 * depth / ONE_PLY, -VALUE_MATE);
-
 
900
          Depth d = (depth / (2 * ONE_PLY)) * ONE_PLY;
939
          ss->excludedMove = move;
901
          ss->excludedMove = move;
940
          ss->skipEarlyPruning = true;
902
          ss->skipEarlyPruning = true;
941
          value = search<NonPV>(pos, ss, rBeta - 1, rBeta, depth / 2, cutNode);
903
          value = search<NonPV>(pos, ss, rBeta - 1, rBeta, d, cutNode);
942
          ss->skipEarlyPruning = false;
904
          ss->skipEarlyPruning = false;
943
          ss->excludedMove = MOVE_NONE;
905
          ss->excludedMove = MOVE_NONE;
944
 
906
 
945
          if (value < rBeta)
907
          if (value < rBeta)
946
              extension = ONE_PLY;
908
              extension = ONE_PLY;
Line 948... Line 910...
948
 
910
 
949
      // Update the current move (this must be done after singular extension search)
911
      // Update the current move (this must be done after singular extension search)
950
      newDepth = depth - ONE_PLY + extension;
912
      newDepth = depth - ONE_PLY + extension;
951
 
913
 
952
      // Step 13. Pruning at shallow depth
914
      // Step 13. Pruning at shallow depth
953
      if (   !rootNode
915
      if (  !rootNode
954
          && !captureOrPromotion
-
 
955
          && !inCheck
-
 
956
          && !givesCheck
-
 
957
          && !pos.advanced_pawn_push(move)
-
 
958
          &&  bestValue > VALUE_MATED_IN_MAX_PLY)
916
          && bestValue > VALUE_MATED_IN_MAX_PLY)
959
      {
917
      {
960
          // Move count based pruning
918
          if (   !captureOrPromotion
961
          if (   depth < 16 * ONE_PLY
919
              && !givesCheck
-
 
920
              && !pos.advanced_pawn_push(move))
-
 
921
          {
962
              && moveCount >= FutilityMoveCounts[improving][depth])
922
              // Move count based pruning
-
 
923
              if (moveCountPruning)
963
              continue;
924
                  continue;
964
 
925
 
965
          // History based pruning
-
 
966
          if (   depth <= 4 * ONE_PLY
926
              // Reduced depth of the next LMR search
967
              && move != ss->killers[0]
-
 
968
              && thisThread->history[pos.moved_piece(move)][to_sq(move)] < VALUE_ZERO
927
              int lmrDepth = std::max(newDepth - reduction<PvNode>(improving, depth, moveCount), DEPTH_ZERO) / ONE_PLY;
969
              && cmh[pos.moved_piece(move)][to_sq(move)] < VALUE_ZERO)
-
 
970
              continue;
-
 
971
 
928
 
-
 
929
              // Countermoves based pruning
-
 
930
              if (   lmrDepth < 3
-
 
931
                  && (!cmh  || (*cmh )[moved_piece][to_sq(move)] < VALUE_ZERO)
972
          predictedDepth = std::max(newDepth - reduction<PvNode>(improving, depth, moveCount), DEPTH_ZERO);
932
                  && (!fmh  || (*fmh )[moved_piece][to_sq(move)] < VALUE_ZERO)
-
 
933
                  && (!fmh2 || (*fmh2)[moved_piece][to_sq(move)] < VALUE_ZERO || (cmh && fmh)))
-
 
934
                  continue;
973
 
935
 
974
          // Futility pruning: parent node
936
              // Futility pruning: parent node
975
          if (predictedDepth < 7 * ONE_PLY)
937
              if (   lmrDepth < 7
976
          {
938
                  && !inCheck
977
              futilityValue = ss->staticEval + futility_margin(predictedDepth) + 256;
939
                  && ss->staticEval + 256 + 200 * lmrDepth <= alpha)
-
 
940
                  continue;
978
 
941
 
979
              if (futilityValue <= alpha)
942
              // Prune moves with negative SEE
980
              {
943
              if (   lmrDepth < 8
981
                  bestValue = std::max(bestValue, futilityValue);
944
                  && !pos.see_ge(move, Value(-35 * lmrDepth * lmrDepth)))
982
                  continue;
945
                  continue;
983
              }
-
 
984
          }
946
          }
985
 
-
 
986
          // Prune moves with negative SEE at low depths
947
          else if (   depth < 7 * ONE_PLY
-
 
948
                   && !extension
987
          if (predictedDepth < 4 * ONE_PLY && pos.see_sign(move) < VALUE_ZERO)
949
                   && !pos.see_ge(move, Value(-35 * depth / ONE_PLY * depth / ONE_PLY)))
988
              continue;
950
                  continue;
989
      }
951
      }
990
 
952
 
991
      // Speculative prefetch as early as possible
953
      // Speculative prefetch as early as possible
992
      prefetch(TT.first_entry(pos.key_after(move)));
954
      prefetch(TT.first_entry(pos.key_after(move)));
993
 
955
 
994
      // Check for legality just before making the move
956
      // Check for legality just before making the move
995
      if (!rootNode && !pos.legal(move, ci.pinned))
957
      if (!rootNode && !pos.legal(move))
996
      {
958
      {
997
          ss->moveCount = --moveCount;
959
          ss->moveCount = --moveCount;
998
          continue;
960
          continue;
999
      }
961
      }
1000
 
962
 
1001
      ss->currentMove = move;
963
      ss->currentMove = move;
-
 
964
      ss->counterMoves = &thisThread->counterMoveHistory[moved_piece][to_sq(move)];
1002
 
965
 
1003
      // Step 14. Make the move
966
      // Step 14. Make the move
1004
      pos.do_move(move, st, givesCheck);
967
      pos.do_move(move, st, givesCheck);
1005
 
968
 
1006
      // Step 15. Reduced depth search (LMR). If the move fails high it will be
969
      // Step 15. Reduced depth search (LMR). If the move fails high it will be
1007
      // re-searched at full depth.
970
      // re-searched at full depth.
1008
      if (    depth >= 3 * ONE_PLY
971
      if (    depth >= 3 * ONE_PLY
1009
          &&  moveCount > 1
972
          &&  moveCount > 1
1010
          && !captureOrPromotion)
973
          && (!captureOrPromotion || moveCountPruning))
1011
      {
974
      {
1012
          Depth r = reduction<PvNode>(improving, depth, moveCount);
975
          Depth r = reduction<PvNode>(improving, depth, moveCount);
1013
 
976
 
1014
          // Increase reduction for cut nodes and moves with a bad history
977
          if (captureOrPromotion)
1015
          if (   (!PvNode && cutNode)
978
              r -= r ? ONE_PLY : DEPTH_ZERO;
-
 
979
          else
-
 
980
          {
1016
              || (   thisThread->history[pos.piece_on(to_sq(move))][to_sq(move)] < VALUE_ZERO
981
              // Increase reduction for cut nodes
1017
                  && cmh[pos.piece_on(to_sq(move))][to_sq(move)] <= VALUE_ZERO))
982
              if (cutNode)
1018
              r += ONE_PLY;
983
                  r += 2 * ONE_PLY;
1019
 
984
 
1020
          // Decrease/increase reduction for moves with a good/bad history
985
              // Decrease reduction for moves that escape a capture. Filter out
-
 
986
              // castling moves, because they are coded as "king captures rook" and
-
 
987
              // hence break make_move(). Also use see() instead of see_sign(),
-
 
988
              // because the destination square is empty.
-
 
989
              else if (   type_of(move) == NORMAL
1021
          int rHist = (  thisThread->history[pos.piece_on(to_sq(move))][to_sq(move)]
990
                       && type_of(pos.piece_on(to_sq(move))) != PAWN
1022
                       + cmh[pos.piece_on(to_sq(move))][to_sq(move)]) / 14980;
991
                       && !pos.see_ge(make_move(to_sq(move), from_sq(move)),  VALUE_ZERO))
1023
          r = std::max(DEPTH_ZERO, r - rHist * ONE_PLY);
992
                  r -= 2 * ONE_PLY;
1024
 
993
 
1025
          // Decrease reduction for moves that escape a capture. Filter out
994
              ss->history = thisThread->history[moved_piece][to_sq(move)]
1026
          // castling moves, because they are coded as "king captures rook" and
995
                           +    (cmh  ? (*cmh )[moved_piece][to_sq(move)] : VALUE_ZERO)
1027
          // hence break make_move(). Also use see() instead of see_sign(),
996
                           +    (fmh  ? (*fmh )[moved_piece][to_sq(move)] : VALUE_ZERO)
-
 
997
                           +    (fmh2 ? (*fmh2)[moved_piece][to_sq(move)] : VALUE_ZERO)
-
 
998
                           +    thisThread->fromTo.get(~pos.side_to_move(), move)
1028
          // because the destination square is empty.
999
                           -    8000; // Correction factor
-
 
1000
 
-
 
1001
              // Decrease/increase reduction by comparing opponent's stat score
-
 
1002
              if (ss->history > VALUE_ZERO && (ss-1)->history < VALUE_ZERO)
1029
          if (   r
1003
                  r -= ONE_PLY;
-
 
1004
 
1030
              && type_of(move) == NORMAL
1005
              else if (ss->history < VALUE_ZERO && (ss-1)->history > VALUE_ZERO)
1031
              && type_of(pos.piece_on(to_sq(move))) != PAWN
1006
                  r += ONE_PLY;
-
 
1007
 
1032
              && pos.see(make_move(to_sq(move), from_sq(move))) < VALUE_ZERO)
1008
              // Decrease/increase reduction for moves with a good/bad history
1033
              r = std::max(DEPTH_ZERO, r - ONE_PLY);
1009
              r = std::max(DEPTH_ZERO, (r / ONE_PLY - ss->history / 20000) * ONE_PLY);
-
 
1010
          }
1034
 
1011
 
1035
          Depth d = std::max(newDepth - r, ONE_PLY);
1012
          Depth d = std::max(newDepth - r, ONE_PLY);
1036
 
1013
 
1037
          value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
1014
          value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
1038
 
1015
 
1039
          doFullDepthSearch = (value > alpha && r != DEPTH_ZERO);
1016
          doFullDepthSearch = (value > alpha && d != newDepth);
1040
      }
1017
      }
1041
      else
1018
      else
1042
          doFullDepthSearch = !PvNode || moveCount > 1;
1019
          doFullDepthSearch = !PvNode || moveCount > 1;
1043
 
1020
 
1044
      // Step 16. Full depth search when LMR is skipped or fails high
1021
      // Step 16. Full depth search when LMR is skipped or fails high
Line 1145... Line 1122...
1145
 
1122
 
1146
    // Step 20. Check for mate and stalemate
1123
    // Step 20. Check for mate and stalemate
1147
    // All legal moves have been searched and if there are no legal moves, it
1124
    // All legal moves have been searched and if there are no legal moves, it
1148
    // must be a mate or a stalemate. If we are in a singular extension search then
1125
    // must be a mate or a stalemate. If we are in a singular extension search then
1149
    // return a fail low score.
1126
    // return a fail low score.
-
 
1127
 
-
 
1128
    assert(moveCount || !inCheck || excludedMove || !MoveList<LEGAL>(pos).size());
-
 
1129
 
1150
    if (!moveCount)
1130
    if (!moveCount)
1151
        bestValue = excludedMove ? alpha
1131
        bestValue = excludedMove ? alpha
1152
                   :     inCheck ? mated_in(ss->ply) : DrawValue[pos.side_to_move()];
1132
                   :     inCheck ? mated_in(ss->ply) : DrawValue[pos.side_to_move()];
-
 
1133
    else if (bestMove)
-
 
1134
    {
-
 
1135
        int d = depth / ONE_PLY;
1153
 
1136
 
1154
    // Quiet best move: update killers, history and countermoves
1137
        // Quiet best move: update killers, history and countermoves
1155
    else if (bestMove && !pos.capture_or_promotion(bestMove))
1138
        if (!pos.capture_or_promotion(bestMove))
-
 
1139
        {
-
 
1140
            Value bonus = Value(d * d + 2 * d - 2);
1156
        update_stats(pos, ss, bestMove, depth, quietsSearched, quietCount);
1141
            update_stats(pos, ss, bestMove, quietsSearched, quietCount, bonus);
-
 
1142
        }
1157
 
1143
 
-
 
1144
        // Extra penalty for a quiet TT move in previous ply when it gets refuted
-
 
1145
        if ((ss-1)->moveCount == 1 && !pos.captured_piece())
-
 
1146
        {
-
 
1147
            Value penalty = Value(d * d + 4 * d + 1);
-
 
1148
            Square prevSq = to_sq((ss-1)->currentMove);
-
 
1149
            update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, -penalty);
-
 
1150
        }
-
 
1151
    }
1158
    // Bonus for prior countermove that caused the fail low
1152
    // Bonus for prior countermove that caused the fail low
1159
    else if (    depth >= 3 * ONE_PLY
1153
    else if (    depth >= 3 * ONE_PLY
1160
             && !bestMove
-
 
1161
             && !inCheck
-
 
1162
             && !pos.captured_piece_type()
1154
             && !pos.captured_piece()
1163
             && is_ok((ss - 1)->currentMove)
-
 
1164
             && is_ok((ss - 2)->currentMove))
1155
             && is_ok((ss-1)->currentMove))
1165
    {
1156
    {
-
 
1157
        int d = depth / ONE_PLY;
1166
        Value bonus = Value((depth / ONE_PLY) * (depth / ONE_PLY) + depth / ONE_PLY - 1);
1158
        Value bonus = Value(d * d + 2 * d - 2);
1167
        Square prevPrevSq = to_sq((ss - 2)->currentMove);
1159
        Square prevSq = to_sq((ss-1)->currentMove);
1168
        CounterMoveStats& prevCmh = CounterMoveHistory[pos.piece_on(prevPrevSq)][prevPrevSq];
-
 
1169
        prevCmh.update(pos.piece_on(prevSq), prevSq, bonus);
1160
        update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, bonus);
1170
    }
1161
    }
1171
 
1162
 
1172
    tte->save(posKey, value_to_tt(bestValue, ss->ply),
1163
    tte->save(posKey, value_to_tt(bestValue, ss->ply),
1173
              bestValue >= beta ? BOUND_LOWER :
1164
              bestValue >= beta ? BOUND_LOWER :
1174
              PvNode && bestMove ? BOUND_EXACT : BOUND_UPPER,
1165
              PvNode && bestMove ? BOUND_EXACT : BOUND_UPPER,
Line 1191... Line 1182...
1191
 
1182
 
1192
    assert(InCheck == !!pos.checkers());
1183
    assert(InCheck == !!pos.checkers());
1193
    assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE);
1184
    assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE);
1194
    assert(PvNode || (alpha == beta - 1));
1185
    assert(PvNode || (alpha == beta - 1));
1195
    assert(depth <= DEPTH_ZERO);
1186
    assert(depth <= DEPTH_ZERO);
-
 
1187
    assert(depth / ONE_PLY * ONE_PLY == depth);
1196
 
1188
 
1197
    Move pv[MAX_PLY+1];
1189
    Move pv[MAX_PLY+1];
1198
    StateInfo st;
1190
    StateInfo st;
1199
    TTEntry* tte;
1191
    TTEntry* tte;
1200
    Key posKey;
1192
    Key posKey;
Line 1236... Line 1228...
1236
        && ttHit
1228
        && ttHit
1237
        && tte->depth() >= ttDepth
1229
        && tte->depth() >= ttDepth
1238
        && ttValue != VALUE_NONE // Only in case of TT access race
1230
        && ttValue != VALUE_NONE // Only in case of TT access race
1239
        && (ttValue >= beta ? (tte->bound() &  BOUND_LOWER)
1231
        && (ttValue >= beta ? (tte->bound() &  BOUND_LOWER)
1240
                            : (tte->bound() &  BOUND_UPPER)))
1232
                            : (tte->bound() &  BOUND_UPPER)))
1241
    {
-
 
1242
        ss->currentMove = ttMove; // Can be MOVE_NONE
-
 
1243
        return ttValue;
1233
        return ttValue;
1244
    }
-
 
1245
 
1234
 
1246
    // Evaluate the position statically
1235
    // Evaluate the position statically
1247
    if (InCheck)
1236
    if (InCheck)
1248
    {
1237
    {
1249
        ss->staticEval = VALUE_NONE;
1238
        ss->staticEval = VALUE_NONE;
Line 1285... Line 1274...
1285
 
1274
 
1286
    // Initialize a MovePicker object for the current position, and prepare
1275
    // Initialize a MovePicker object for the current position, and prepare
1287
    // to search the moves. Because the depth is <= 0 here, only captures,
1276
    // to search the moves. Because the depth is <= 0 here, only captures,
1288
    // queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
1277
    // queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
1289
    // be generated.
1278
    // be generated.
1290
    MovePicker mp(pos, ttMove, depth, pos.this_thread()->history, to_sq((ss-1)->currentMove));
1279
    MovePicker mp(pos, ttMove, depth, to_sq((ss-1)->currentMove));
1291
    CheckInfo ci(pos);
-
 
1292
 
1280
 
1293
    // Loop through the moves until no moves remain or a beta cutoff occurs
1281
    // Loop through the moves until no moves remain or a beta cutoff occurs
1294
    while ((move = mp.next_move()) != MOVE_NONE)
1282
    while ((move = mp.next_move()) != MOVE_NONE)
1295
    {
1283
    {
1296
      assert(is_ok(move));
1284
      assert(is_ok(move));
1297
 
1285
 
1298
      givesCheck =  type_of(move) == NORMAL && !ci.dcCandidates
1286
      givesCheck =  type_of(move) == NORMAL && !pos.discovered_check_candidates()
1299
                  ? ci.checkSquares[type_of(pos.piece_on(from_sq(move)))] & to_sq(move)
1287
                  ? pos.check_squares(type_of(pos.piece_on(from_sq(move)))) & to_sq(move)
1300
                  : pos.gives_check(move, ci);
1288
                  : pos.gives_check(move);
1301
 
1289
 
1302
      // Futility pruning
1290
      // Futility pruning
1303
      if (   !InCheck
1291
      if (   !InCheck
1304
          && !givesCheck
1292
          && !givesCheck
1305
          &&  futilityBase > -VALUE_KNOWN_WIN
1293
          &&  futilityBase > -VALUE_KNOWN_WIN
Line 1313... Line 1301...
1313
          {
1301
          {
1314
              bestValue = std::max(bestValue, futilityValue);
1302
              bestValue = std::max(bestValue, futilityValue);
1315
              continue;
1303
              continue;
1316
          }
1304
          }
1317
 
1305
 
1318
          if (futilityBase <= alpha && pos.see(move) <= VALUE_ZERO)
1306
          if (futilityBase <= alpha && !pos.see_ge(move, VALUE_ZERO + 1))
1319
          {
1307
          {
1320
              bestValue = std::max(bestValue, futilityBase);
1308
              bestValue = std::max(bestValue, futilityBase);
1321
              continue;
1309
              continue;
1322
          }
1310
          }
1323
      }
1311
      }
Line 1328... Line 1316...
1328
                       && !pos.capture(move);
1316
                       && !pos.capture(move);
1329
 
1317
 
1330
      // Don't search moves with negative SEE values
1318
      // Don't search moves with negative SEE values
1331
      if (  (!InCheck || evasionPrunable)
1319
      if (  (!InCheck || evasionPrunable)
1332
          &&  type_of(move) != PROMOTION
1320
          &&  type_of(move) != PROMOTION
1333
          &&  pos.see_sign(move) < VALUE_ZERO)
1321
          &&  !pos.see_ge(move, VALUE_ZERO))
1334
          continue;
1322
          continue;
1335
 
1323
 
1336
      // Speculative prefetch as early as possible
1324
      // Speculative prefetch as early as possible
1337
      prefetch(TT.first_entry(pos.key_after(move)));
1325
      prefetch(TT.first_entry(pos.key_after(move)));
1338
 
1326
 
1339
      // Check for legality just before making the move
1327
      // Check for legality just before making the move
1340
      if (!pos.legal(move, ci.pinned))
1328
      if (!pos.legal(move))
1341
          continue;
1329
          continue;
1342
 
1330
 
1343
      ss->currentMove = move;
1331
      ss->currentMove = move;
1344
 
1332
 
1345
      // Make and search the move
1333
      // Make and search the move
Line 1424... Line 1412...
1424
        *pv++ = *childPv++;
1412
        *pv++ = *childPv++;
1425
    *pv = MOVE_NONE;
1413
    *pv = MOVE_NONE;
1426
  }
1414
  }
1427
 
1415
 
1428
 
1416
 
-
 
1417
  // update_cm_stats() updates countermove and follow-up move history
-
 
1418
 
-
 
1419
  void update_cm_stats(Stack* ss, Piece pc, Square s, Value bonus) {
-
 
1420
 
-
 
1421
    CounterMoveStats* cmh  = (ss-1)->counterMoves;
-
 
1422
    CounterMoveStats* fmh1 = (ss-2)->counterMoves;
-
 
1423
    CounterMoveStats* fmh2 = (ss-4)->counterMoves;
-
 
1424
 
-
 
1425
    if (cmh)
-
 
1426
        cmh->update(pc, s, bonus);
-
 
1427
 
-
 
1428
    if (fmh1)
-
 
1429
        fmh1->update(pc, s, bonus);
-
 
1430
 
-
 
1431
    if (fmh2)
-
 
1432
        fmh2->update(pc, s, bonus);
-
 
1433
  }
-
 
1434
 
-
 
1435
 
1429
  // update_stats() updates killers, history, countermove and countermove
1436
  // update_stats() updates killers, history, countermove and countermove plus
1430
  // history when a new quiet best move is found.
1437
  // follow-up move history when a new quiet best move is found.
1431
 
1438
 
1432
  void update_stats(const Position& pos, Stack* ss, Move move,
1439
  void update_stats(const Position& pos, Stack* ss, Move move,
1433
                    Depth depth, Move* quiets, int quietsCnt) {
1440
                    Move* quiets, int quietsCnt, Value bonus) {
1434
 
1441
 
1435
    if (ss->killers[0] != move)
1442
    if (ss->killers[0] != move)
1436
    {
1443
    {
1437
        ss->killers[1] = ss->killers[0];
1444
        ss->killers[1] = ss->killers[0];
1438
        ss->killers[0] = move;
1445
        ss->killers[0] = move;
1439
    }
1446
    }
1440
 
1447
 
1441
    Value bonus = Value((depth / ONE_PLY) * (depth / ONE_PLY) + depth / ONE_PLY - 1);
-
 
1442
 
-
 
1443
    Square prevSq = to_sq((ss-1)->currentMove);
1448
    Color c = pos.side_to_move();
1444
    CounterMoveStats& cmh = CounterMoveHistory[pos.piece_on(prevSq)][prevSq];
-
 
1445
    Thread* thisThread = pos.this_thread();
1449
    Thread* thisThread = pos.this_thread();
1446
 
-
 
-
 
1450
    thisThread->fromTo.update(c, move, bonus);
1447
    thisThread->history.update(pos.moved_piece(move), to_sq(move), bonus);
1451
    thisThread->history.update(pos.moved_piece(move), to_sq(move), bonus);
-
 
1452
    update_cm_stats(ss, pos.moved_piece(move), to_sq(move), bonus);
1448
 
1453
 
1449
    if (is_ok((ss-1)->currentMove))
1454
    if ((ss-1)->counterMoves)
1450
    {
1455
    {
-
 
1456
        Square prevSq = to_sq((ss-1)->currentMove);
1451
        thisThread->counterMoves.update(pos.piece_on(prevSq), prevSq, move);
1457
        thisThread->counterMoves.update(pos.piece_on(prevSq), prevSq, move);
1452
        cmh.update(pos.moved_piece(move), to_sq(move), bonus);
-
 
1453
    }
1458
    }
1454
 
1459
 
1455
    // Decrease all the other played quiet moves
1460
    // Decrease all the other played quiet moves
1456
    for (int i = 0; i < quietsCnt; ++i)
1461
    for (int i = 0; i < quietsCnt; ++i)
1457
    {
1462
    {
-
 
1463
        thisThread->fromTo.update(c, quiets[i], -bonus);
1458
        thisThread->history.update(pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus);
1464
        thisThread->history.update(pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus);
1459
 
-
 
1460
        if (is_ok((ss-1)->currentMove))
-
 
1461
            cmh.update(pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus);
1465
        update_cm_stats(ss, pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus);
1462
    }
-
 
1463
 
-
 
1464
    // Extra penalty for a quiet TT move in previous ply when it gets refuted
-
 
1465
    if (   (ss-1)->moveCount == 1
-
 
1466
        && !pos.captured_piece_type()
-
 
1467
        && is_ok((ss-2)->currentMove))
-
 
1468
    {
-
 
1469
        Square prevPrevSq = to_sq((ss-2)->currentMove);
-
 
1470
        CounterMoveStats& prevCmh = CounterMoveHistory[pos.piece_on(prevPrevSq)][prevPrevSq];
-
 
1471
        prevCmh.update(pos.piece_on(prevSq), prevSq, -bonus - 2 * (depth + 1) / ONE_PLY);
-
 
1472
    }
1466
    }
1473
  }
1467
  }
1474
 
1468
 
1475
 
1469
 
1476
  // When playing with strength handicap, choose best move among a set of RootMoves
1470
  // When playing with strength handicap, choose best move among a set of RootMoves
1477
  // using a statistical rule dependent on 'level'. Idea by Heinz van Saanen.
1471
  // using a statistical rule dependent on 'level'. Idea by Heinz van Saanen.
1478
 
1472
 
1479
  Move Skill::pick_best(size_t multiPV) {
1473
  Move Skill::pick_best(size_t multiPV) {
1480
 
1474
 
1481
    const Search::RootMoveVector& rootMoves = Threads.main()->rootMoves;
1475
    const RootMoves& rootMoves = Threads.main()->rootMoves;
1482
    static PRNG rng(now()); // PRNG sequence should be non-deterministic
1476
    static PRNG rng(now()); // PRNG sequence should be non-deterministic
1483
 
1477
 
1484
    // RootMoves are already sorted by score in descending order
1478
    // RootMoves are already sorted by score in descending order
1485
    Value topScore = rootMoves[0].score;
1479
    Value topScore = rootMoves[0].score;
1486
    int delta = std::min(topScore - rootMoves[multiPV - 1].score, PawnValueMg);
1480
    int delta = std::min(topScore - rootMoves[multiPV - 1].score, PawnValueMg);
Line 1527... Line 1521...
1527
    if (Limits.ponder)
1521
    if (Limits.ponder)
1528
        return;
1522
        return;
1529
 
1523
 
1530
    if (   (Limits.use_time_management() && elapsed > Time.maximum() - 10)
1524
    if (   (Limits.use_time_management() && elapsed > Time.maximum() - 10)
1531
        || (Limits.movetime && elapsed >= Limits.movetime)
1525
        || (Limits.movetime && elapsed >= Limits.movetime)
1532
        || (Limits.nodes && Threads.nodes_searched() >= Limits.nodes))
1526
        || (Limits.nodes && Threads.nodes_searched() >= (uint64_t)Limits.nodes))
1533
            Signals.stop = true;
1527
            Signals.stop = true;
1534
  }
1528
  }
1535
 
1529
 
1536
} // namespace
1530
} // namespace
1537
 
1531
 
Line 1541... Line 1535...
1541
 
1535
 
1542
string UCI::pv(const Position& pos, Depth depth, Value alpha, Value beta) {
1536
string UCI::pv(const Position& pos, Depth depth, Value alpha, Value beta) {
1543
 
1537
 
1544
  std::stringstream ss;
1538
  std::stringstream ss;
1545
  int elapsed = Time.elapsed() + 1;
1539
  int elapsed = Time.elapsed() + 1;
1546
  const Search::RootMoveVector& rootMoves = pos.this_thread()->rootMoves;
1540
  const RootMoves& rootMoves = pos.this_thread()->rootMoves;
1547
  size_t PVIdx = pos.this_thread()->PVIdx;
1541
  size_t PVIdx = pos.this_thread()->PVIdx;
1548
  size_t multiPV = std::min((size_t)Options["MultiPV"], rootMoves.size());
1542
  size_t multiPV = std::min((size_t)Options["MultiPV"], rootMoves.size());
1549
  uint64_t nodes_searched = Threads.nodes_searched();
1543
  uint64_t nodesSearched = Threads.nodes_searched();
-
 
1544
  uint64_t tbHits = Threads.tb_hits() + (TB::RootInTB ? rootMoves.size() : 0);
1550
 
1545
 
1551
  for (size_t i = 0; i < multiPV; ++i)
1546
  for (size_t i = 0; i < multiPV; ++i)
1552
  {
1547
  {
1553
      bool updated = (i <= PVIdx);
1548
      bool updated = (i <= PVIdx);
1554
 
1549
 
Line 1571... Line 1566...
1571
         << " score "    << UCI::value(v);
1566
         << " score "    << UCI::value(v);
1572
 
1567
 
1573
      if (!tb && i == PVIdx)
1568
      if (!tb && i == PVIdx)
1574
          ss << (v >= beta ? " lowerbound" : v <= alpha ? " upperbound" : "");
1569
          ss << (v >= beta ? " lowerbound" : v <= alpha ? " upperbound" : "");
1575
 
1570
 
1576
      ss << " nodes "    << nodes_searched
1571
      ss << " nodes "    << nodesSearched
1577
         << " nps "      << nodes_searched * 1000 / elapsed;
1572
         << " nps "      << nodesSearched * 1000 / elapsed;
1578
 
1573
 
1579
      if (elapsed > 1000) // Earlier makes little sense
1574
      if (elapsed > 1000) // Earlier makes little sense
1580
          ss << " hashfull " << TT.hashfull();
1575
          ss << " hashfull " << TT.hashfull();
1581
 
1576
 
1582
      ss << " tbhits "   << TB::Hits
1577
      ss << " tbhits "   << tbHits
1583
         << " time "     << elapsed
1578
         << " time "     << elapsed
1584
         << " pv";
1579
         << " pv";
1585
 
1580
 
1586
      for (Move m : rootMoves[i].pv)
1581
      for (Move m : rootMoves[i].pv)
1587
          ss << " " << UCI::move(m, pos.is_chess960());
1582
          ss << " " << UCI::move(m, pos.is_chess960());
1588
  }
1583
  }
1589
 
1584
 
1590
  return ss.str();
1585
  return ss.str();
1591
}
-
 
1592
 
-
 
1593
 
-
 
1594
/// RootMove::insert_pv_in_tt() is called at the end of a search iteration, and
-
 
1595
/// inserts the PV back into the TT. This makes sure the old PV moves are searched
-
 
1596
/// first, even if the old TT entries have been overwritten.
-
 
1597
 
-
 
1598
void RootMove::insert_pv_in_tt(Position& pos) {
-
 
1599
 
-
 
1600
  StateInfo state[MAX_PLY], *st = state;
-
 
1601
  bool ttHit;
-
 
1602
 
-
 
1603
  for (Move m : pv)
-
 
1604
  {
-
 
1605
      assert(MoveList<LEGAL>(pos).contains(m));
-
 
1606
 
-
 
1607
      TTEntry* tte = TT.probe(pos.key(), ttHit);
-
 
1608
 
-
 
1609
      if (!ttHit || tte->move() != m) // Don't overwrite correct entries
-
 
1610
          tte->save(pos.key(), VALUE_NONE, BOUND_NONE, DEPTH_NONE,
-
 
1611
                    m, VALUE_NONE, TT.generation());
-
 
1612
 
-
 
1613
      pos.do_move(m, *st++, pos.gives_check(m, CheckInfo(pos)));
-
 
1614
  }
-
 
1615
 
-
 
1616
  for (size_t i = pv.size(); i > 0; )
-
 
1617
      pos.undo_move(pv[--i]);
-
 
1618
}
1586
}
1619
 
1587
 
1620
 
1588
 
1621
/// RootMove::extract_ponder_from_tt() is called in case we have no ponder move
1589
/// RootMove::extract_ponder_from_tt() is called in case we have no ponder move
1622
/// before exiting the search, for instance, in case we stop the search during a
1590
/// before exiting the search, for instance, in case we stop the search during a
1623
/// fail high at root. We try hard to have a ponder move to return to the GUI,
1591
/// fail high at root. We try hard to have a ponder move to return to the GUI,
1624
/// otherwise in case of 'ponder on' we have nothing to think on.
1592
/// otherwise in case of 'ponder on' we have nothing to think on.
1625
 
1593
 
1626
bool RootMove::extract_ponder_from_tt(Position& pos)
1594
bool RootMove::extract_ponder_from_tt(Position& pos) {
1627
{
1595
 
1628
    StateInfo st;
1596
    StateInfo st;
1629
    bool ttHit;
1597
    bool ttHit;
1630
 
1598
 
1631
    assert(pv.size() == 1);
1599
    assert(pv.size() == 1);
1632
 
1600
 
-
 
1601
    if (!pv[0])
-
 
1602
        return false;
-
 
1603
 
1633
    pos.do_move(pv[0], st, pos.gives_check(pv[0], CheckInfo(pos)));
1604
    pos.do_move(pv[0], st, pos.gives_check(pv[0]));
1634
    TTEntry* tte = TT.probe(pos.key(), ttHit);
1605
    TTEntry* tte = TT.probe(pos.key(), ttHit);
1635
    pos.undo_move(pv[0]);
-
 
1636
 
1606
 
1637
    if (ttHit)
1607
    if (ttHit)
1638
    {
1608
    {
1639
        Move m = tte->move(); // Local copy to be SMP safe
1609
        Move m = tte->move(); // Local copy to be SMP safe
1640
        if (MoveList<LEGAL>(pos).contains(m))
1610
        if (MoveList<LEGAL>(pos).contains(m))
1641
           return pv.push_back(m), true;
1611
            pv.push_back(m);
-
 
1612
    }
-
 
1613
 
-
 
1614
    pos.undo_move(pv[0]);
-
 
1615
    return pv.size() > 1;
-
 
1616
}
-
 
1617
 
-
 
1618
void Tablebases::filter_root_moves(Position& pos, Search::RootMoves& rootMoves) {
-
 
1619
 
-
 
1620
    RootInTB = false;
-
 
1621
    UseRule50 = Options["Syzygy50MoveRule"];
-
 
1622
    ProbeDepth = Options["SyzygyProbeDepth"] * ONE_PLY;
-
 
1623
    Cardinality = Options["SyzygyProbeLimit"];
-
 
1624
 
-
 
1625
    // Skip TB probing when no TB found: !TBLargest -> !TB::Cardinality
-
 
1626
    if (Cardinality > MaxCardinality)
-
 
1627
    {
-
 
1628
        Cardinality = MaxCardinality;
-
 
1629
        ProbeDepth = DEPTH_ZERO;
-
 
1630
    }
-
 
1631
 
-
 
1632
    if (Cardinality < popcount(pos.pieces()) || pos.can_castle(ANY_CASTLING))
-
 
1633
        return;
-
 
1634
 
-
 
1635
    // If the current root position is in the tablebases, then RootMoves
-
 
1636
    // contains only moves that preserve the draw or the win.
-
 
1637
    RootInTB = root_probe(pos, rootMoves, TB::Score);
-
 
1638
 
-
 
1639
    if (RootInTB)
-
 
1640
        Cardinality = 0; // Do not probe tablebases during the search
-
 
1641
 
-
 
1642
    else // If DTZ tables are missing, use WDL tables as a fallback
-
 
1643
    {
-
 
1644
        // Filter out moves that do not preserve the draw or the win.
-
 
1645
        RootInTB = root_probe_wdl(pos, rootMoves, TB::Score);
-
 
1646
 
-
 
1647
        // Only probe during search if winning
-
 
1648
        if (RootInTB && TB::Score <= VALUE_DRAW)
-
 
1649
            Cardinality = 0;
1642
    }
1650
    }
1643
 
1651
 
1644
    return false;
1652
    if (RootInTB && !UseRule50)
-
 
1653
        TB::Score =  TB::Score > VALUE_DRAW ?  VALUE_MATE - MAX_PLY - 1
-
 
1654
                   : TB::Score < VALUE_DRAW ? -VALUE_MATE + MAX_PLY + 1
-
 
1655
                                            :  VALUE_DRAW;
1645
}
1656
}