Subversion Repositories Games.Chess Giants

Rev

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

Rev 154 Rev 169
Line 4... Line 4...
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
5
  Copyright (C) 2015-2016 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
5
  Copyright (C) 2015-2018 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
6
 
6
 
7
  Stockfish is free software: you can redistribute it and/or modify
7
  Stockfish is free software: you can redistribute it and/or modify
8
  it under the terms of the GNU General Public License as published by
8
  it under the terms of the GNU General Public License as published by
9
  the Free Software Foundation, either version 3 of the License, or
9
  the Free Software Foundation, either version 3 of the License, or
10
  (at your option) any later version.
10
  (at your option) any later version.
Line 37... Line 37...
37
#include "uci.h"
37
#include "uci.h"
38
#include "syzygy/tbprobe.h"
38
#include "syzygy/tbprobe.h"
39
 
39
 
40
namespace Search {
40
namespace Search {
41
 
41
 
42
  SignalsType Signals;
-
 
43
  LimitsType Limits;
42
  LimitsType Limits;
44
}
43
}
45
 
44
 
46
namespace Tablebases {
45
namespace Tablebases {
47
 
46
 
Line 60... Line 59...
60
 
59
 
61
namespace {
60
namespace {
62
 
61
 
63
  // Different node types, used as a template parameter
62
  // Different node types, used as a template parameter
64
  enum NodeType { NonPV, PV };
63
  enum NodeType { NonPV, PV };
-
 
64
 
-
 
65
  // Sizes and phases of the skip-blocks, used for distributing search depths across the threads
-
 
66
  const int skipSize[]  = { 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
-
 
67
  const int skipPhase[] = { 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7 };
65
 
68
 
66
  // Razoring and futility margin based on depth
69
  // Razoring and futility margin based on depth
67
  const int razor_margin[4] = { 483, 570, 603, 554 };
70
  const int razor_margin = 600;
68
  Value futility_margin(Depth d) { return Value(150 * d / ONE_PLY); }
71
  Value futility_margin(Depth d) { return Value(150 * d / ONE_PLY); }
69
 
72
 
70
  // Futility and reductions lookup tables, initialized at startup
73
  // Futility and reductions lookup tables, initialized at startup
71
  int FutilityMoveCounts[2][16]; // [improving][depth]
74
  int FutilityMoveCounts[2][16]; // [improving][depth]
72
  int Reductions[2][2][64][64];  // [pv][improving][depth][moveNumber]
75
  int Reductions[2][2][64][64];  // [pv][improving][depth][moveNumber]
73
 
76
 
74
  template <bool PvNode> Depth reduction(bool i, Depth d, int mn) {
77
  template <bool PvNode> Depth reduction(bool i, Depth d, int mn) {
75
    return Reductions[PvNode][i][std::min(d / ONE_PLY, 63)][std::min(mn, 63)] * ONE_PLY;
78
    return Reductions[PvNode][i][std::min(d / ONE_PLY, 63)][std::min(mn, 63)] * ONE_PLY;
-
 
79
  }
-
 
80
 
-
 
81
  // History and stats update bonus, based on depth
-
 
82
  int stat_bonus(Depth depth) {
-
 
83
    int d = depth / ONE_PLY;
-
 
84
    return d > 17 ? 0 : d * d + 2 * d - 2;
76
  }
85
  }
77
 
86
 
78
  // Skill structure is used to implement strength limit
87
  // Skill structure is used to implement strength limit
79
  struct Skill {
88
  struct Skill {
80
    Skill(int l) : level(l) {}
89
    explicit Skill(int l) : level(l) {}
81
    bool enabled() const { return level < 20; }
90
    bool enabled() const { return level < 20; }
82
    bool time_to_pick(Depth depth) const { return depth / ONE_PLY == 1 + level; }
91
    bool time_to_pick(Depth depth) const { return depth / ONE_PLY == 1 + level; }
83
    Move best_move(size_t multiPV) { return best ? best : pick_best(multiPV); }
-
 
84
    Move pick_best(size_t multiPV);
92
    Move pick_best(size_t multiPV);
85
 
93
 
86
    int level;
94
    int level;
87
    Move best = MOVE_NONE;
95
    Move best = MOVE_NONE;
88
  };
96
  };
89
 
-
 
90
  // EasyMoveManager structure is used to detect an 'easy move'. When the PV is
-
 
91
  // stable across multiple search iterations, we can quickly return the best move.
-
 
92
  struct EasyMoveManager {
-
 
93
 
-
 
94
    void clear() {
-
 
95
      stableCnt = 0;
-
 
96
      expectedPosKey = 0;
-
 
97
      pv[0] = pv[1] = pv[2] = MOVE_NONE;
-
 
98
    }
-
 
99
 
-
 
100
    Move get(Key key) const {
-
 
101
      return expectedPosKey == key ? pv[2] : MOVE_NONE;
-
 
102
    }
-
 
103
 
-
 
104
    void update(Position& pos, const std::vector<Move>& newPv) {
-
 
105
 
-
 
106
      assert(newPv.size() >= 3);
-
 
107
 
-
 
108
      // Keep track of how many times in a row the 3rd ply remains stable
-
 
109
      stableCnt = (newPv[2] == pv[2]) ? stableCnt + 1 : 0;
-
 
110
 
-
 
111
      if (!std::equal(newPv.begin(), newPv.begin() + 3, pv))
-
 
112
      {
-
 
113
          std::copy(newPv.begin(), newPv.begin() + 3, pv);
-
 
114
 
-
 
115
          StateInfo st[2];
-
 
116
          pos.do_move(newPv[0], st[0], pos.gives_check(newPv[0]));
-
 
117
          pos.do_move(newPv[1], st[1], pos.gives_check(newPv[1]));
-
 
118
          expectedPosKey = pos.key();
-
 
119
          pos.undo_move(newPv[1]);
-
 
120
          pos.undo_move(newPv[0]);
-
 
121
      }
-
 
122
    }
-
 
123
 
-
 
124
    int stableCnt;
-
 
125
    Key expectedPosKey;
-
 
126
    Move pv[3];
-
 
127
  };
-
 
128
 
-
 
129
  // Set of rows with half bits set to 1 and half to 0. It is used to allocate
-
 
130
  // the search depths across the threads.
-
 
131
  typedef std::vector<int> Row;
-
 
132
 
-
 
133
  const Row HalfDensity[] = {
-
 
134
    {0, 1},
-
 
135
    {1, 0},
-
 
136
    {0, 0, 1, 1},
-
 
137
    {0, 1, 1, 0},
-
 
138
    {1, 1, 0, 0},
-
 
139
    {1, 0, 0, 1},
-
 
140
    {0, 0, 0, 1, 1, 1},
-
 
141
    {0, 0, 1, 1, 1, 0},
-
 
142
    {0, 1, 1, 1, 0, 0},
-
 
143
    {1, 1, 1, 0, 0, 0},
-
 
144
    {1, 1, 0, 0, 0, 1},
-
 
145
    {1, 0, 0, 0, 1, 1},
-
 
146
    {0, 0, 0, 0, 1, 1, 1, 1},
-
 
147
    {0, 0, 0, 1, 1, 1, 1, 0},
-
 
148
    {0, 0, 1, 1, 1, 1, 0 ,0},
-
 
149
    {0, 1, 1, 1, 1, 0, 0 ,0},
-
 
150
    {1, 1, 1, 1, 0, 0, 0 ,0},
-
 
151
    {1, 1, 1, 0, 0, 0, 0 ,1},
-
 
152
    {1, 1, 0, 0, 0, 0, 1 ,1},
-
 
153
    {1, 0, 0, 0, 0, 1, 1 ,1},
-
 
154
  };
-
 
155
 
-
 
156
  const size_t HalfDensitySize = std::extent<decltype(HalfDensity)>::value;
-
 
157
 
-
 
158
  EasyMoveManager EasyMove;
-
 
159
  Value DrawValue[COLOR_NB];
-
 
160
 
97
 
161
  template <NodeType NT>
98
  template <NodeType NT>
162
  Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode);
99
  Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode, bool skipEarlyPruning);
163
 
100
 
164
  template <NodeType NT, bool InCheck>
101
  template <NodeType NT, bool InCheck>
165
  Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth);
102
  Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth = DEPTH_ZERO);
166
 
103
 
167
  Value value_to_tt(Value v, int ply);
104
  Value value_to_tt(Value v, int ply);
168
  Value value_from_tt(Value v, int ply);
105
  Value value_from_tt(Value v, int ply);
169
  void update_pv(Move* pv, Move move, Move* childPv);
106
  void update_pv(Move* pv, Move move, Move* childPv);
170
  void update_cm_stats(Stack* ss, Piece pc, Square s, Value bonus);
107
  void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus);
171
  void update_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, Value bonus);
108
  void update_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, int bonus);
-
 
109
  void update_capture_stats(const Position& pos, Move move, Move* captures, int captureCnt, int bonus);
-
 
110
  bool pv_is_draw(Position& pos);
-
 
111
 
-
 
112
  // perft() is our utility to verify move generation. All the leaf nodes up
-
 
113
  // to the given depth are generated and counted, and the sum is returned.
-
 
114
  template<bool Root>
-
 
115
  uint64_t perft(Position& pos, Depth depth) {
-
 
116
 
-
 
117
    StateInfo st;
-
 
118
    uint64_t cnt, nodes = 0;
-
 
119
    const bool leaf = (depth == 2 * ONE_PLY);
-
 
120
 
-
 
121
    for (const auto& m : MoveList<LEGAL>(pos))
-
 
122
    {
-
 
123
        if (Root && depth <= ONE_PLY)
-
 
124
            cnt = 1, nodes++;
-
 
125
        else
-
 
126
        {
-
 
127
            pos.do_move(m, st);
-
 
128
            cnt = leaf ? MoveList<LEGAL>(pos).size() : perft<false>(pos, depth - ONE_PLY);
-
 
129
            nodes += cnt;
-
 
130
            pos.undo_move(m);
-
 
131
        }
-
 
132
        if (Root)
-
 
133
            sync_cout << UCI::move(m, pos.is_chess960()) << ": " << cnt << sync_endl;
-
 
134
    }
172
  void check_time();
135
    return nodes;
-
 
136
  }
173
 
137
 
174
} // namespace
138
} // namespace
175
 
139
 
176
 
140
 
177
/// Search::init() is called during startup to initialize various lookup tables
141
/// Search::init() is called during startup to initialize various lookup tables
Line 180... Line 144...
180
 
144
 
181
  for (int imp = 0; imp <= 1; ++imp)
145
  for (int imp = 0; imp <= 1; ++imp)
182
      for (int d = 1; d < 64; ++d)
146
      for (int d = 1; d < 64; ++d)
183
          for (int mc = 1; mc < 64; ++mc)
147
          for (int mc = 1; mc < 64; ++mc)
184
          {
148
          {
185
              double r = log(d) * log(mc) / 2;
149
              double r = log(d) * log(mc) / 1.95;
186
              if (r < 0.80)
-
 
187
                continue;
-
 
188
 
150
 
189
              Reductions[NonPV][imp][d][mc] = int(std::round(r));
151
              Reductions[NonPV][imp][d][mc] = int(std::round(r));
190
              Reductions[PV][imp][d][mc] = std::max(Reductions[NonPV][imp][d][mc] - 1, 0);
152
              Reductions[PV][imp][d][mc] = std::max(Reductions[NonPV][imp][d][mc] - 1, 0);
191
 
153
 
192
              // Increase reduction for non-PV nodes when eval is not improving
154
              // Increase reduction for non-PV nodes when eval is not improving
Line 194... Line 156...
194
                Reductions[NonPV][imp][d][mc]++;
156
                Reductions[NonPV][imp][d][mc]++;
195
          }
157
          }
196
 
158
 
197
  for (int d = 0; d < 16; ++d)
159
  for (int d = 0; d < 16; ++d)
198
  {
160
  {
199
      FutilityMoveCounts[0][d] = int(2.4 + 0.773 * pow(d + 0.00, 1.8));
161
      FutilityMoveCounts[0][d] = int(2.4 + 0.74 * pow(d, 1.78));
200
      FutilityMoveCounts[1][d] = int(2.9 + 1.045 * pow(d + 0.49, 1.8));
162
      FutilityMoveCounts[1][d] = int(5.0 + 1.00 * pow(d, 2.00));
201
  }
163
  }
202
}
164
}
203
 
165
 
204
 
166
 
205
/// Search::clear() resets search state to zero, to obtain reproducible results
167
/// Search::clear() resets search state to its initial value
206
 
168
 
207
void Search::clear() {
169
void Search::clear() {
208
 
170
 
-
 
171
  Threads.main()->wait_for_search_finished();
-
 
172
 
-
 
173
  Time.availableNodes = 0;
209
  TT.clear();
174
  TT.clear();
210
 
-
 
211
  for (Thread* th : Threads)
-
 
212
  {
-
 
213
      th->history.clear();
-
 
214
      th->counterMoves.clear();
-
 
215
      th->fromTo.clear();
175
  Threads.clear();
216
      th->counterMoveHistory.clear();
-
 
217
  }
-
 
218
 
-
 
219
  Threads.main()->previousScore = VALUE_INFINITE;
-
 
220
}
176
}
221
 
177
 
222
 
178
 
223
/// Search::perft() is our utility to verify move generation. All the leaf nodes
179
/// MainThread::search() is called by the main thread when the program receives
224
/// up to the given depth are generated and counted, and the sum is returned.
180
/// the UCI 'go' command. It searches from the root position and outputs the "bestmove".
225
template<bool Root>
-
 
226
uint64_t Search::perft(Position& pos, Depth depth) {
-
 
227
 
181
 
228
  StateInfo st;
-
 
229
  uint64_t cnt, nodes = 0;
182
void MainThread::search() {
230
  const bool leaf = (depth == 2 * ONE_PLY);
-
 
231
 
183
 
232
  for (const auto& m : MoveList<LEGAL>(pos))
184
  if (Limits.perft)
233
  {
185
  {
234
      if (Root && depth <= ONE_PLY)
186
      nodes = perft<true>(rootPos, Limits.perft * ONE_PLY);
235
          cnt = 1, nodes++;
-
 
236
      else
-
 
237
      {
-
 
238
          pos.do_move(m, st, pos.gives_check(m));
-
 
239
          cnt = leaf ? MoveList<LEGAL>(pos).size() : perft<false>(pos, depth - ONE_PLY);
187
      sync_cout << "\nNodes searched: " << nodes << "\n" << sync_endl;
240
          nodes += cnt;
-
 
241
          pos.undo_move(m);
-
 
242
      }
-
 
243
      if (Root)
188
      return;
244
          sync_cout << UCI::move(m, pos.is_chess960()) << ": " << cnt << sync_endl;
-
 
245
  }
189
  }
246
  return nodes;
-
 
247
}
-
 
248
 
-
 
249
template uint64_t Search::perft<true>(Position&, Depth);
-
 
250
 
-
 
251
 
-
 
252
/// MainThread::search() is called by the main thread when the program receives
-
 
253
/// the UCI 'go' command. It searches from the root position and outputs the "bestmove".
-
 
254
 
-
 
255
void MainThread::search() {
-
 
256
 
190
 
257
  Color us = rootPos.side_to_move();
191
  Color us = rootPos.side_to_move();
258
  Time.init(Limits, us, rootPos.game_ply());
192
  Time.init(Limits, us, rootPos.game_ply());
-
 
193
  TT.new_search();
259
 
194
 
260
  int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
195
  int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
-
 
196
 
261
  DrawValue[ us] = VALUE_DRAW - Value(contempt);
197
  Eval::Contempt = (us == WHITE ?  make_score(contempt, contempt / 2)
262
  DrawValue[~us] = VALUE_DRAW + Value(contempt);
198
                                : -make_score(contempt, contempt / 2));
263
 
199
 
264
  if (rootMoves.empty())
200
  if (rootMoves.empty())
265
  {
201
  {
266
      rootMoves.push_back(RootMove(MOVE_NONE));
202
      rootMoves.emplace_back(MOVE_NONE);
267
      sync_cout << "info depth 0 score "
203
      sync_cout << "info depth 0 score "
268
                << UCI::value(rootPos.checkers() ? -VALUE_MATE : VALUE_DRAW)
204
                << UCI::value(rootPos.checkers() ? -VALUE_MATE : VALUE_DRAW)
269
                << sync_endl;
205
                << sync_endl;
270
  }
206
  }
271
  else
207
  else
Line 274... Line 210...
274
          if (th != this)
210
          if (th != this)
275
              th->start_searching();
211
              th->start_searching();
276
 
212
 
277
      Thread::search(); // Let's start searching!
213
      Thread::search(); // Let's start searching!
278
  }
214
  }
279
 
-
 
280
  // When playing in 'nodes as time' mode, subtract the searched nodes from
-
 
281
  // the available ones before exiting.
-
 
282
  if (Limits.npmsec)
-
 
283
      Time.availableNodes += Limits.inc[us] - Threads.nodes_searched();
-
 
284
 
215
 
285
  // When we reach the maximum depth, we can arrive here without a raise of
216
  // When we reach the maximum depth, we can arrive here without a raise of
286
  // Signals.stop. However, if we are pondering or in an infinite search,
217
  // Threads.stop. However, if we are pondering or in an infinite search,
287
  // the UCI protocol states that we shouldn't print the best move before the
218
  // the UCI protocol states that we shouldn't print the best move before the
288
  // GUI sends a "stop" or "ponderhit" command. We therefore simply wait here
219
  // GUI sends a "stop" or "ponderhit" command. We therefore simply wait here
289
  // until the GUI sends one of those commands (which also raises Signals.stop).
220
  // until the GUI sends one of those commands (which also raises Threads.stop).
290
  if (!Signals.stop && (Limits.ponder || Limits.infinite))
221
  Threads.stopOnPonderhit = true;
291
  {
222
 
292
      Signals.stopOnPonderhit = true;
223
  while (!Threads.stop && (Threads.ponder || Limits.infinite))
293
      wait(Signals.stop);
224
  {} // Busy wait for a stop or a ponder reset
294
  }
-
 
295
 
225
 
296
  // Stop the threads if not already stopped
226
  // Stop the threads if not already stopped (also raise the stop if
-
 
227
  // "ponderhit" just reset Threads.ponder).
297
  Signals.stop = true;
228
  Threads.stop = true;
298
 
229
 
299
  // Wait until all threads have finished
230
  // Wait until all threads have finished
300
  for (Thread* th : Threads)
231
  for (Thread* th : Threads)
301
      if (th != this)
232
      if (th != this)
302
          th->wait_for_search_finished();
233
          th->wait_for_search_finished();
-
 
234
 
-
 
235
  // When playing in 'nodes as time' mode, subtract the searched nodes from
-
 
236
  // the available ones before exiting.
-
 
237
  if (Limits.npmsec)
-
 
238
      Time.availableNodes += Limits.inc[us] - Threads.nodes_searched();
303
 
239
 
304
  // Check if there are threads with a better score than main thread
240
  // Check if there are threads with a better score than main thread
305
  Thread* bestThread = this;
241
  Thread* bestThread = this;
306
  if (   !this->easyMovePlayed
-
 
307
      &&  Options["MultiPV"] == 1
242
  if (    Options["MultiPV"] == 1
308
      && !Limits.depth
243
      && !Limits.depth
309
      && !Skill(Options["Skill Level"]).enabled()
244
      && !Skill(Options["Skill Level"]).enabled()
310
      &&  rootMoves[0].pv[0] != MOVE_NONE)
245
      &&  rootMoves[0].pv[0] != MOVE_NONE)
311
  {
246
  {
312
      for (Thread* th : Threads)
247
      for (Thread* th : Threads)
-
 
248
      {
313
          if (   th->completedDepth > bestThread->completedDepth
249
          Depth depthDiff = th->completedDepth - bestThread->completedDepth;
314
              && th->rootMoves[0].score > bestThread->rootMoves[0].score)
250
          Value scoreDiff = th->rootMoves[0].score - bestThread->rootMoves[0].score;
-
 
251
 
-
 
252
          // Select the thread with the best score, always if it is a mate
-
 
253
          if (    scoreDiff > 0
-
 
254
              && (depthDiff >= 0 || th->rootMoves[0].score >= VALUE_MATE_IN_MAX_PLY))
315
              bestThread = th;
255
              bestThread = th;
-
 
256
      }
316
  }
257
  }
317
 
258
 
318
  previousScore = bestThread->rootMoves[0].score;
259
  previousScore = bestThread->rootMoves[0].score;
319
 
260
 
320
  // Send new PV when needed
261
  // Send new PV when needed
Line 328... Line 269...
328
 
269
 
329
  std::cout << sync_endl;
270
  std::cout << sync_endl;
330
}
271
}
331
 
272
 
332
 
273
 
333
// Thread::search() is the main iterative deepening loop. It calls search()
274
/// Thread::search() is the main iterative deepening loop. It calls search()
334
// repeatedly with increasing depth until the allocated thinking time has been
275
/// repeatedly with increasing depth until the allocated thinking time has been
335
// consumed, the user stops the search, or the maximum search depth is reached.
276
/// consumed, the user stops the search, or the maximum search depth is reached.
336
 
277
 
337
void Thread::search() {
278
void Thread::search() {
338
 
279
 
339
  Stack stack[MAX_PLY+7], *ss = stack+5; // To allow referencing (ss-5) and (ss+2)
280
  Stack stack[MAX_PLY+7], *ss = stack+4; // To reference from (ss-4) to (ss+2)
340
  Value bestValue, alpha, beta, delta;
281
  Value bestValue, alpha, beta, delta;
341
  Move easyMove = MOVE_NONE;
282
  Move  lastBestMove = MOVE_NONE;
-
 
283
  Depth lastBestMoveDepth = DEPTH_ZERO;
342
  MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
284
  MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
-
 
285
  double timeReduction = 1.0;
343
 
286
 
344
  std::memset(ss-5, 0, 8 * sizeof(Stack));
287
  std::memset(ss-4, 0, 7 * sizeof(Stack));
-
 
288
  for (int i = 4; i > 0; i--)
-
 
289
     (ss-i)->contHistory = &this->contHistory[NO_PIECE][0]; // Use as sentinel
345
 
290
 
346
  bestValue = delta = alpha = -VALUE_INFINITE;
291
  bestValue = delta = alpha = -VALUE_INFINITE;
347
  beta = VALUE_INFINITE;
292
  beta = VALUE_INFINITE;
348
  completedDepth = DEPTH_ZERO;
-
 
349
 
293
 
350
  if (mainThread)
294
  if (mainThread)
351
  {
295
  {
352
      easyMove = EasyMove.get(rootPos.key());
-
 
353
      EasyMove.clear();
-
 
354
      mainThread->easyMovePlayed = mainThread->failedLow = false;
296
      mainThread->failedLow = false;
355
      mainThread->bestMoveChanges = 0;
297
      mainThread->bestMoveChanges = 0;
356
      TT.new_search();
-
 
357
  }
298
  }
358
 
299
 
359
  size_t multiPV = Options["MultiPV"];
300
  size_t multiPV = Options["MultiPV"];
360
  Skill skill(Options["Skill Level"]);
301
  Skill skill(Options["Skill Level"]);
361
 
302
 
Line 366... Line 307...
366
 
307
 
367
  multiPV = std::min(multiPV, rootMoves.size());
308
  multiPV = std::min(multiPV, rootMoves.size());
368
 
309
 
369
  // Iterative deepening loop until requested to stop or the target depth is reached
310
  // Iterative deepening loop until requested to stop or the target depth is reached
370
  while (   (rootDepth += ONE_PLY) < DEPTH_MAX
311
  while (   (rootDepth += ONE_PLY) < DEPTH_MAX
371
         && !Signals.stop
312
         && !Threads.stop
372
         && (!Limits.depth || Threads.main()->rootDepth / ONE_PLY <= Limits.depth))
313
         && !(Limits.depth && mainThread && rootDepth / ONE_PLY > Limits.depth))
373
  {
314
  {
374
      // Set up the new depths for the helper threads skipping on average every
-
 
375
      // 2nd ply (using a half-density matrix).
315
      // Distribute search depths across the threads
376
      if (!mainThread)
316
      if (idx)
377
      {
317
      {
378
          const Row& row = HalfDensity[(idx - 1) % HalfDensitySize];
318
          int i = (idx - 1) % 20;
379
          if (row[(rootDepth / ONE_PLY + rootPos.game_ply()) % row.size()])
319
          if (((rootDepth / ONE_PLY + rootPos.game_ply() + skipPhase[i]) / skipSize[i]) % 2)
380
             continue;
320
              continue;
381
      }
321
      }
382
 
322
 
383
      // Age out PV variability metric
323
      // Age out PV variability metric
384
      if (mainThread)
324
      if (mainThread)
385
          mainThread->bestMoveChanges *= 0.505, mainThread->failedLow = false;
325
          mainThread->bestMoveChanges *= 0.505, mainThread->failedLow = false;
Line 388... Line 328...
388
      // all the move scores except the (new) PV are set to -VALUE_INFINITE.
328
      // all the move scores except the (new) PV are set to -VALUE_INFINITE.
389
      for (RootMove& rm : rootMoves)
329
      for (RootMove& rm : rootMoves)
390
          rm.previousScore = rm.score;
330
          rm.previousScore = rm.score;
391
 
331
 
392
      // MultiPV loop. We perform a full root search for each PV line
332
      // MultiPV loop. We perform a full root search for each PV line
393
      for (PVIdx = 0; PVIdx < multiPV && !Signals.stop; ++PVIdx)
333
      for (PVIdx = 0; PVIdx < multiPV && !Threads.stop; ++PVIdx)
394
      {
334
      {
-
 
335
          // Reset UCI info selDepth for each depth and each PV line
-
 
336
          selDepth = 0;
-
 
337
 
395
          // Reset aspiration window starting size
338
          // Reset aspiration window starting size
396
          if (rootDepth >= 5 * ONE_PLY)
339
          if (rootDepth >= 5 * ONE_PLY)
397
          {
340
          {
398
              delta = Value(18);
341
              delta = Value(18);
399
              alpha = std::max(rootMoves[PVIdx].previousScore - delta,-VALUE_INFINITE);
342
              alpha = std::max(rootMoves[PVIdx].previousScore - delta,-VALUE_INFINITE);
Line 403... Line 346...
403
          // Start with a small aspiration window and, in the case of a fail
346
          // Start with a small aspiration window and, in the case of a fail
404
          // high/low, re-search with a bigger window until we're not failing
347
          // high/low, re-search with a bigger window until we're not failing
405
          // high/low anymore.
348
          // high/low anymore.
406
          while (true)
349
          while (true)
407
          {
350
          {
408
              bestValue = ::search<PV>(rootPos, ss, alpha, beta, rootDepth, false);
351
              bestValue = ::search<PV>(rootPos, ss, alpha, beta, rootDepth, false, false);
409
 
352
 
410
              // Bring the best move to the front. It is critical that sorting
353
              // Bring the best move to the front. It is critical that sorting
411
              // is done with a stable algorithm because all the values but the
354
              // is done with a stable algorithm because all the values but the
412
              // first and eventually the new best one are set to -VALUE_INFINITE
355
              // first and eventually the new best one are set to -VALUE_INFINITE
413
              // and we want to keep the same order for all the moves except the
356
              // and we want to keep the same order for all the moves except the
414
              // new PV that goes to the front. Note that in case of MultiPV
357
              // new PV that goes to the front. Note that in case of MultiPV
415
              // search the already searched PV lines are preserved.
358
              // search the already searched PV lines are preserved.
416
              std::stable_sort(rootMoves.begin() + PVIdx, rootMoves.end());
359
              std::stable_sort(rootMoves.begin() + PVIdx, rootMoves.end());
417
 
360
 
418
              // If search has been stopped, break immediately. Sorting and
361
              // If search has been stopped, we break immediately. Sorting and
419
              // writing PV back to TT is safe because RootMoves is still
362
              // writing PV back to TT is safe because RootMoves is still
420
              // valid, although it refers to the previous iteration.
363
              // valid, although it refers to the previous iteration.
421
              if (Signals.stop)
364
              if (Threads.stop)
422
                  break;
365
                  break;
423
 
366
 
424
              // When failing high/low give some update (without cluttering
367
              // When failing high/low give some update (without cluttering
425
              // the UI) before a re-search.
368
              // the UI) before a re-search.
426
              if (   mainThread
369
              if (   mainThread
Line 437... Line 380...
437
                  alpha = std::max(bestValue - delta, -VALUE_INFINITE);
380
                  alpha = std::max(bestValue - delta, -VALUE_INFINITE);
438
 
381
 
439
                  if (mainThread)
382
                  if (mainThread)
440
                  {
383
                  {
441
                      mainThread->failedLow = true;
384
                      mainThread->failedLow = true;
442
                      Signals.stopOnPonderhit = false;
385
                      Threads.stopOnPonderhit = false;
443
                  }
386
                  }
444
              }
387
              }
445
              else if (bestValue >= beta)
388
              else if (bestValue >= beta)
446
              {
-
 
447
                  alpha = (alpha + beta) / 2;
-
 
448
                  beta = std::min(bestValue + delta, VALUE_INFINITE);
389
                  beta = std::min(bestValue + delta, VALUE_INFINITE);
449
              }
-
 
450
              else
390
              else
451
                  break;
391
                  break;
452
 
392
 
453
              delta += delta / 4 + 5;
393
              delta += delta / 4 + 5;
454
 
394
 
Line 456... Line 396...
456
          }
396
          }
457
 
397
 
458
          // Sort the PV lines searched so far and update the GUI
398
          // Sort the PV lines searched so far and update the GUI
459
          std::stable_sort(rootMoves.begin(), rootMoves.begin() + PVIdx + 1);
399
          std::stable_sort(rootMoves.begin(), rootMoves.begin() + PVIdx + 1);
460
 
400
 
461
          if (!mainThread)
401
          if (    mainThread
462
              continue;
-
 
463
 
-
 
464
          if (Signals.stop || PVIdx + 1 == multiPV || Time.elapsed() > 3000)
402
              && (Threads.stop || PVIdx + 1 == multiPV || Time.elapsed() > 3000))
465
              sync_cout << UCI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
403
              sync_cout << UCI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
466
      }
404
      }
467
 
405
 
468
      if (!Signals.stop)
406
      if (!Threads.stop)
469
          completedDepth = rootDepth;
407
          completedDepth = rootDepth;
-
 
408
 
-
 
409
      if (rootMoves[0].pv[0] != lastBestMove) {
-
 
410
         lastBestMove = rootMoves[0].pv[0];
-
 
411
         lastBestMoveDepth = rootDepth;
-
 
412
      }
-
 
413
 
-
 
414
      // Have we found a "mate in x"?
-
 
415
      if (   Limits.mate
-
 
416
          && bestValue >= VALUE_MATE_IN_MAX_PLY
-
 
417
          && VALUE_MATE - bestValue <= 2 * Limits.mate)
-
 
418
          Threads.stop = true;
470
 
419
 
471
      if (!mainThread)
420
      if (!mainThread)
472
          continue;
421
          continue;
473
 
422
 
474
      // If skill level is enabled and time is up, pick a sub-optimal best move
423
      // If skill level is enabled and time is up, pick a sub-optimal best move
475
      if (skill.enabled() && skill.time_to_pick(rootDepth))
424
      if (skill.enabled() && skill.time_to_pick(rootDepth))
476
          skill.pick_best(multiPV);
425
          skill.pick_best(multiPV);
477
 
-
 
478
      // Have we found a "mate in x"?
-
 
479
      if (   Limits.mate
-
 
480
          && bestValue >= VALUE_MATE_IN_MAX_PLY
-
 
481
          && VALUE_MATE - bestValue <= 2 * Limits.mate)
-
 
482
          Signals.stop = true;
-
 
483
 
426
 
484
      // Do we have time for the next iteration? Can we stop searching now?
427
      // Do we have time for the next iteration? Can we stop searching now?
485
      if (Limits.use_time_management())
428
      if (Limits.use_time_management())
486
      {
429
      {
487
          if (!Signals.stop && !Signals.stopOnPonderhit)
430
          if (!Threads.stop && !Threads.stopOnPonderhit)
488
          {
431
          {
489
              // Stop the search if only one legal move is available, or if all
432
              // Stop the search if only one legal move is available, or if all
490
              // of the available time has been used, or if we matched an easyMove
433
              // of the available time has been used
491
              // from the previous search and just did a fast verification.
-
 
492
              const int F[] = { mainThread->failedLow,
434
              const int F[] = { mainThread->failedLow,
493
                                bestValue - mainThread->previousScore };
435
                                bestValue - mainThread->previousScore };
494
 
-
 
495
              int improvingFactor = std::max(229, std::min(715, 357 + 119 * F[0] - 6 * F[1]));
436
              int improvingFactor = std::max(229, std::min(715, 357 + 119 * F[0] - 6 * F[1]));
496
              double unstablePvFactor = 1 + mainThread->bestMoveChanges;
-
 
497
 
437
 
-
 
438
              Color us = rootPos.side_to_move();
498
              bool doEasyMove =   rootMoves[0].pv[0] == easyMove
439
              bool thinkHard =    bestValue == VALUE_DRAW
499
                               && mainThread->bestMoveChanges < 0.03
440
                               && Limits.time[us] - Time.elapsed() > Limits.time[~us]
500
                               && Time.elapsed() > Time.optimum() * 5 / 42;
441
                               && ::pv_is_draw(rootPos);
-
 
442
 
-
 
443
              double unstablePvFactor = 1 + mainThread->bestMoveChanges + thinkHard;
-
 
444
 
-
 
445
              // if the bestMove is stable over several iterations, reduce time for this move,
-
 
446
              // the longer the move has been stable, the more.
-
 
447
              // Use part of the gained time from a previous stable move for the current move.
-
 
448
              timeReduction = 1;
-
 
449
              for (int i : {3, 4, 5})
-
 
450
                  if (lastBestMoveDepth * i < completedDepth && !thinkHard)
-
 
451
                     timeReduction *= 1.3;
-
 
452
              unstablePvFactor *=  std::pow(mainThread->previousTimeReduction, 0.51) / timeReduction;
501
 
453
 
502
              if (   rootMoves.size() == 1
454
              if (   rootMoves.size() == 1
503
                  || Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 628
455
                  || Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 628)
504
                  || (mainThread->easyMovePlayed = doEasyMove, doEasyMove))
-
 
505
              {
456
              {
506
                  // If we are allowed to ponder do not stop the search now but
457
                  // If we are allowed to ponder do not stop the search now but
507
                  // keep pondering until the GUI sends "ponderhit" or "stop".
458
                  // keep pondering until the GUI sends "ponderhit" or "stop".
508
                  if (Limits.ponder)
459
                  if (Threads.ponder)
509
                      Signals.stopOnPonderhit = true;
460
                      Threads.stopOnPonderhit = true;
510
                  else
461
                  else
511
                      Signals.stop = true;
462
                      Threads.stop = true;
512
              }
463
              }
513
          }
464
          }
514
 
-
 
515
          if (rootMoves[0].pv.size() >= 3)
-
 
516
              EasyMove.update(rootPos, rootMoves[0].pv);
-
 
517
          else
-
 
518
              EasyMove.clear();
-
 
519
      }
465
      }
520
  }
466
  }
521
 
467
 
522
  if (!mainThread)
468
  if (!mainThread)
523
      return;
469
      return;
524
 
470
 
525
  // Clear any candidate easy move that wasn't stable for the last search
-
 
526
  // iterations; the second condition prevents consecutive fast moves.
471
  mainThread->previousTimeReduction = timeReduction;
527
  if (EasyMove.stableCnt < 6 || mainThread->easyMovePlayed)
-
 
528
      EasyMove.clear();
-
 
529
 
472
 
530
  // If skill level is enabled, swap best PV line with the sub-optimal one
473
  // If skill level is enabled, swap best PV line with the sub-optimal one
531
  if (skill.enabled())
474
  if (skill.enabled())
532
      std::swap(rootMoves[0], *std::find(rootMoves.begin(),
475
      std::swap(rootMoves[0], *std::find(rootMoves.begin(), rootMoves.end(),
533
                rootMoves.end(), skill.best_move(multiPV)));
476
                skill.best ? skill.best : skill.pick_best(multiPV)));
534
}
477
}
535
 
478
 
536
 
479
 
537
namespace {
480
namespace {
538
 
481
 
539
  // search<>() is the main search function for both PV and non-PV nodes
482
  // search<>() is the main search function for both PV and non-PV nodes
540
 
483
 
541
  template <NodeType NT>
484
  template <NodeType NT>
542
  Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode) {
485
  Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode, bool skipEarlyPruning) {
543
 
486
 
544
    const bool PvNode = NT == PV;
487
    const bool PvNode = NT == PV;
545
    const bool rootNode = PvNode && (ss-1)->ply == 0;
488
    const bool rootNode = PvNode && ss->ply == 0;
546
 
489
 
547
    assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE);
490
    assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE);
548
    assert(PvNode || (alpha == beta - 1));
491
    assert(PvNode || (alpha == beta - 1));
549
    assert(DEPTH_ZERO < depth && depth < DEPTH_MAX);
492
    assert(DEPTH_ZERO < depth && depth < DEPTH_MAX);
550
    assert(!(PvNode && cutNode));
493
    assert(!(PvNode && cutNode));
551
    assert(depth / ONE_PLY * ONE_PLY == depth);
494
    assert(depth / ONE_PLY * ONE_PLY == depth);
552
 
495
 
553
    Move pv[MAX_PLY+1], quietsSearched[64];
496
    Move pv[MAX_PLY+1], capturesSearched[32], quietsSearched[64];
554
    StateInfo st;
497
    StateInfo st;
555
    TTEntry* tte;
498
    TTEntry* tte;
556
    Key posKey;
499
    Key posKey;
557
    Move ttMove, move, excludedMove, bestMove;
500
    Move ttMove, move, excludedMove, bestMove;
558
    Depth extension, newDepth;
501
    Depth extension, newDepth;
559
    Value bestValue, value, ttValue, eval, nullValue;
502
    Value bestValue, value, ttValue, eval, maxValue;
560
    bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
503
    bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
561
    bool captureOrPromotion, doFullDepthSearch, moveCountPruning;
504
    bool captureOrPromotion, doFullDepthSearch, moveCountPruning, skipQuiets, ttCapture, pvExact;
562
    Piece moved_piece;
505
    Piece movedPiece;
563
    int moveCount, quietCount;
506
    int moveCount, captureCount, quietCount;
564
 
507
 
565
    // Step 1. Initialize node
508
    // Step 1. Initialize node
566
    Thread* thisThread = pos.this_thread();
509
    Thread* thisThread = pos.this_thread();
567
    inCheck = pos.checkers();
510
    inCheck = pos.checkers();
568
    moveCount = quietCount =  ss->moveCount = 0;
511
    moveCount = captureCount = quietCount = ss->moveCount = 0;
569
    ss->history = VALUE_ZERO;
512
    ss->statScore = 0;
570
    bestValue = -VALUE_INFINITE;
513
    bestValue = -VALUE_INFINITE;
571
    ss->ply = (ss-1)->ply + 1;
514
    maxValue = VALUE_INFINITE;
572
 
515
 
573
    // Check for the available remaining time
516
    // Check for the available remaining time
574
    if (thisThread->resetCalls.load(std::memory_order_relaxed))
-
 
575
    {
-
 
576
        thisThread->resetCalls = false;
-
 
577
        thisThread->callsCnt = 0;
-
 
578
    }
-
 
579
    if (++thisThread->callsCnt > 4096)
517
    if (thisThread == Threads.main())
580
    {
-
 
581
        for (Thread* th : Threads)
518
        static_cast<MainThread*>(thisThread)->check_time();
582
            th->resetCalls = true;
-
 
583
 
-
 
584
        check_time();
-
 
585
    }
-
 
586
 
519
 
587
    // Used to send selDepth info to GUI
520
    // Used to send selDepth info to GUI (selDepth counts from 1, ply from 0)
588
    if (PvNode && thisThread->maxPly < ss->ply)
521
    if (PvNode && thisThread->selDepth < ss->ply + 1)
589
        thisThread->maxPly = ss->ply;
522
        thisThread->selDepth = ss->ply + 1;
590
 
523
 
591
    if (!rootNode)
524
    if (!rootNode)
592
    {
525
    {
593
        // Step 2. Check for aborted search and immediate draw
526
        // Step 2. Check for aborted search and immediate draw
594
        if (Signals.stop.load(std::memory_order_relaxed) || pos.is_draw() || ss->ply >= MAX_PLY)
527
        if (Threads.stop.load(std::memory_order_relaxed) || pos.is_draw(ss->ply) || ss->ply >= MAX_PLY)
595
            return ss->ply >= MAX_PLY && !inCheck ? evaluate(pos)
528
            return ss->ply >= MAX_PLY && !inCheck ? evaluate(pos) : VALUE_DRAW;
596
                                                  : DrawValue[pos.side_to_move()];
-
 
597
 
529
 
598
        // Step 3. Mate distance pruning. Even if we mate at the next move our score
530
        // Step 3. Mate distance pruning. Even if we mate at the next move our score
599
        // would be at best mate_in(ss->ply+1), but if alpha is already bigger because
531
        // would be at best mate_in(ss->ply+1), but if alpha is already bigger because
600
        // a shorter mate was found upward in the tree then there is no need to search
532
        // a shorter mate was found upward in the tree then there is no need to search
601
        // because we will never beat the current alpha. Same logic but with reversed
533
        // because we will never beat the current alpha. Same logic but with reversed
Line 607... Line 539...
607
            return alpha;
539
            return alpha;
608
    }
540
    }
609
 
541
 
610
    assert(0 <= ss->ply && ss->ply < MAX_PLY);
542
    assert(0 <= ss->ply && ss->ply < MAX_PLY);
611
 
543
 
-
 
544
    (ss+1)->ply = ss->ply + 1;
612
    ss->currentMove = (ss+1)->excludedMove = bestMove = MOVE_NONE;
545
    ss->currentMove = (ss+1)->excludedMove = bestMove = MOVE_NONE;
613
    ss->counterMoves = nullptr;
546
    ss->contHistory = &thisThread->contHistory[NO_PIECE][0];
614
    (ss+1)->skipEarlyPruning = false;
-
 
615
    (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
547
    (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
-
 
548
    Square prevSq = to_sq((ss-1)->currentMove);
616
 
549
 
617
    // Step 4. Transposition table lookup. We don't want the score of a partial
550
    // Step 4. Transposition table lookup. We don't want the score of a partial
618
    // search to overwrite a previous full search TT value, so we use a different
551
    // search to overwrite a previous full search TT value, so we use a different
619
    // position key in case of an excluded move.
552
    // position key in case of an excluded move.
620
    excludedMove = ss->excludedMove;
553
    excludedMove = ss->excludedMove;
621
    posKey = pos.key() ^ Key(excludedMove);
554
    posKey = pos.key() ^ Key(excludedMove << 16); // isn't a very good hash
622
    tte = TT.probe(posKey, ttHit);
555
    tte = TT.probe(posKey, ttHit);
623
    ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
556
    ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
624
    ttMove =  rootNode ? thisThread->rootMoves[thisThread->PVIdx].pv[0]
557
    ttMove =  rootNode ? thisThread->rootMoves[thisThread->PVIdx].pv[0]
625
            : ttHit    ? tte->move() : MOVE_NONE;
558
            : ttHit    ? tte->move() : MOVE_NONE;
626
 
559
 
Line 630... Line 563...
630
        && tte->depth() >= depth
563
        && tte->depth() >= depth
631
        && ttValue != VALUE_NONE // Possible in case of TT access race
564
        && ttValue != VALUE_NONE // Possible in case of TT access race
632
        && (ttValue >= beta ? (tte->bound() & BOUND_LOWER)
565
        && (ttValue >= beta ? (tte->bound() & BOUND_LOWER)
633
                            : (tte->bound() & BOUND_UPPER)))
566
                            : (tte->bound() & BOUND_UPPER)))
634
    {
567
    {
635
        // If ttMove is quiet, update killers, history, counter move on TT hit
568
        // If ttMove is quiet, update move sorting heuristics on TT hit
636
        if (ttValue >= beta && ttMove)
569
        if (ttMove)
637
        {
570
        {
638
            int d = depth / ONE_PLY;
571
            if (ttValue >= beta)
-
 
572
            {
-
 
573
                if (!pos.capture_or_promotion(ttMove))
-
 
574
                    update_stats(pos, ss, ttMove, nullptr, 0, stat_bonus(depth));
639
 
575
 
640
            if (!pos.capture_or_promotion(ttMove))
576
                // Extra penalty for a quiet TT move in previous ply when it gets refuted
641
            {
-
 
642
                Value bonus = Value(d * d + 2 * d - 2);
577
                if ((ss-1)->moveCount == 1 && !pos.captured_piece())
643
                update_stats(pos, ss, ttMove, nullptr, 0, bonus);
578
                    update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY));
644
            }
579
            }
645
 
-
 
646
            // Extra penalty for a quiet TT move in previous ply when it gets refuted
580
            // Penalty for a quiet ttMove that fails low
647
            if ((ss-1)->moveCount == 1 && !pos.captured_piece())
581
            else if (!pos.capture_or_promotion(ttMove))
648
            {
582
            {
649
                Value penalty = Value(d * d + 4 * d + 1);
583
                int penalty = -stat_bonus(depth);
650
                Square prevSq = to_sq((ss-1)->currentMove);
584
                thisThread->mainHistory.update(pos.side_to_move(), ttMove, penalty);
651
                update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, -penalty);
585
                update_continuation_histories(ss, pos.moved_piece(ttMove), to_sq(ttMove), penalty);
652
            }
586
            }
653
        }
587
        }
654
        return ttValue;
588
        return ttValue;
655
    }
589
    }
656
 
590
 
657
    // Step 4a. Tablebase probe
591
    // Step 4a. Tablebase probe
658
    if (!rootNode && TB::Cardinality)
592
    if (!rootNode && TB::Cardinality)
659
    {
593
    {
660
        int piecesCnt = pos.count<ALL_PIECES>(WHITE) + pos.count<ALL_PIECES>(BLACK);
594
        int piecesCount = pos.count<ALL_PIECES>();
661
 
595
 
662
        if (    piecesCnt <= TB::Cardinality
596
        if (    piecesCount <= TB::Cardinality
663
            && (piecesCnt <  TB::Cardinality || depth >= TB::ProbeDepth)
597
            && (piecesCount <  TB::Cardinality || depth >= TB::ProbeDepth)
664
            &&  pos.rule50_count() == 0
598
            &&  pos.rule50_count() == 0
665
            && !pos.can_castle(ANY_CASTLING))
599
            && !pos.can_castle(ANY_CASTLING))
666
        {
600
        {
-
 
601
            TB::ProbeState err;
667
            int found, v = Tablebases::probe_wdl(pos, &found);
602
            TB::WDLScore wdl = Tablebases::probe_wdl(pos, &err);
668
 
603
 
669
            if (found)
604
            if (err != TB::ProbeState::FAIL)
670
            {
605
            {
671
                thisThread->tbHits++;
606
                thisThread->tbHits.fetch_add(1, std::memory_order_relaxed);
672
 
607
 
673
                int drawScore = TB::UseRule50 ? 1 : 0;
608
                int drawScore = TB::UseRule50 ? 1 : 0;
674
 
609
 
675
                value =  v < -drawScore ? -VALUE_MATE + MAX_PLY + ss->ply
610
                value =  wdl < -drawScore ? -VALUE_MATE + MAX_PLY + ss->ply + 1
676
                       : v >  drawScore ?  VALUE_MATE - MAX_PLY - ss->ply
611
                       : wdl >  drawScore ?  VALUE_MATE - MAX_PLY - ss->ply - 1
677
                                        :  VALUE_DRAW + 2 * v * drawScore;
612
                                          :  VALUE_DRAW + 2 * wdl * drawScore;
678
 
613
 
-
 
614
                Bound b =  wdl < -drawScore ? BOUND_UPPER
-
 
615
                         : wdl >  drawScore ? BOUND_LOWER : BOUND_EXACT;
-
 
616
 
-
 
617
                if (    b == BOUND_EXACT
-
 
618
                    || (b == BOUND_LOWER ? value >= beta : value <= alpha))
-
 
619
                {
679
                tte->save(posKey, value_to_tt(value, ss->ply), BOUND_EXACT,
620
                    tte->save(posKey, value_to_tt(value, ss->ply), b,
680
                          std::min(DEPTH_MAX - ONE_PLY, depth + 6 * ONE_PLY),
621
                              std::min(DEPTH_MAX - ONE_PLY, depth + 6 * ONE_PLY),
681
                          MOVE_NONE, VALUE_NONE, TT.generation());
622
                              MOVE_NONE, VALUE_NONE, TT.generation());
-
 
623
 
-
 
624
                    return value;
-
 
625
                }
682
 
626
 
-
 
627
                if (PvNode)
-
 
628
                {
-
 
629
                    if (b == BOUND_LOWER)
-
 
630
                        bestValue = value, alpha = std::max(alpha, bestValue);
683
                return value;
631
                    else
-
 
632
                        maxValue = value;
-
 
633
                }
684
            }
634
            }
685
        }
635
        }
686
    }
636
    }
687
 
637
 
688
    // Step 5. Evaluate the position statically
638
    // Step 5. Evaluate the position statically
Line 697... Line 647...
697
        // Never assume anything on values stored in TT
647
        // Never assume anything on values stored in TT
698
        if ((ss->staticEval = eval = tte->eval()) == VALUE_NONE)
648
        if ((ss->staticEval = eval = tte->eval()) == VALUE_NONE)
699
            eval = ss->staticEval = evaluate(pos);
649
            eval = ss->staticEval = evaluate(pos);
700
 
650
 
701
        // Can ttValue be used as a better position evaluation?
651
        // Can ttValue be used as a better position evaluation?
702
        if (ttValue != VALUE_NONE)
652
        if (   ttValue != VALUE_NONE
703
            if (tte->bound() & (ttValue > eval ? BOUND_LOWER : BOUND_UPPER))
653
            && (tte->bound() & (ttValue > eval ? BOUND_LOWER : BOUND_UPPER)))
704
                eval = ttValue;
654
            eval = ttValue;
705
    }
655
    }
706
    else
656
    else
707
    {
657
    {
708
        eval = ss->staticEval =
658
        eval = ss->staticEval =
709
        (ss-1)->currentMove != MOVE_NULL ? evaluate(pos)
659
        (ss-1)->currentMove != MOVE_NULL ? evaluate(pos)
Line 711... Line 661...
711
 
661
 
712
        tte->save(posKey, VALUE_NONE, BOUND_NONE, DEPTH_NONE, MOVE_NONE,
662
        tte->save(posKey, VALUE_NONE, BOUND_NONE, DEPTH_NONE, MOVE_NONE,
713
                  ss->staticEval, TT.generation());
663
                  ss->staticEval, TT.generation());
714
    }
664
    }
715
 
665
 
716
    if (ss->skipEarlyPruning)
666
    if (skipEarlyPruning || !pos.non_pawn_material(pos.side_to_move()))
717
        goto moves_loop;
667
        goto moves_loop;
718
 
668
 
719
    // Step 6. Razoring (skipped when in check)
669
    // Step 6. Razoring (skipped when in check)
720
    if (   !PvNode
670
    if (   !PvNode
721
        &&  depth < 4 * ONE_PLY
671
        &&  depth < 4 * ONE_PLY
722
        &&  ttMove == MOVE_NONE
-
 
723
        &&  eval + razor_margin[depth / ONE_PLY] <= alpha)
672
        &&  eval + razor_margin <= alpha)
724
    {
673
    {
725
        if (depth <= ONE_PLY)
674
        if (depth <= ONE_PLY)
726
            return qsearch<NonPV, false>(pos, ss, alpha, beta, DEPTH_ZERO);
675
            return qsearch<NonPV, false>(pos, ss, alpha, alpha+1);
727
 
676
 
728
        Value ralpha = alpha - razor_margin[depth / ONE_PLY];
677
        Value ralpha = alpha - razor_margin;
729
        Value v = qsearch<NonPV, false>(pos, ss, ralpha, ralpha+1, DEPTH_ZERO);
678
        Value v = qsearch<NonPV, false>(pos, ss, ralpha, ralpha+1);
730
        if (v <= ralpha)
679
        if (v <= ralpha)
731
            return v;
680
            return v;
732
    }
681
    }
733
 
682
 
734
    // Step 7. Futility pruning: child node (skipped when in check)
683
    // Step 7. Futility pruning: child node (skipped when in check)
735
    if (   !rootNode
684
    if (   !rootNode
736
        &&  depth < 7 * ONE_PLY
685
        &&  depth < 7 * ONE_PLY
737
        &&  eval - futility_margin(depth) >= beta
686
        &&  eval - futility_margin(depth) >= beta
738
        &&  eval < VALUE_KNOWN_WIN  // Do not return unproven wins
687
        &&  eval < VALUE_KNOWN_WIN)  // Do not return unproven wins
739
        &&  pos.non_pawn_material(pos.side_to_move()))
-
 
740
        return eval;
688
        return eval;
741
 
689
 
742
    // Step 8. Null move search with verification search (is omitted in PV nodes)
690
    // Step 8. Null move search with verification search (is omitted in PV nodes)
743
    if (   !PvNode
691
    if (   !PvNode
744
        &&  eval >= beta
692
        &&  eval >= beta
745
        && (ss->staticEval >= beta - 35 * (depth / ONE_PLY - 6) || depth >= 13 * ONE_PLY)
693
        &&  ss->staticEval >= beta - 36 * depth / ONE_PLY + 225
746
        &&  pos.non_pawn_material(pos.side_to_move()))
694
        && (ss->ply >= thisThread->nmp_ply || ss->ply % 2 != thisThread->nmp_odd))
747
    {
695
    {
748
        ss->currentMove = MOVE_NULL;
-
 
749
        ss->counterMoves = nullptr;
-
 
750
 
696
 
751
        assert(eval - beta >= 0);
697
        assert(eval - beta >= 0);
752
 
698
 
753
        // Null move dynamic reduction based on depth and value
699
        // Null move dynamic reduction based on depth and value
754
        Depth R = ((823 + 67 * depth / ONE_PLY) / 256 + std::min((eval - beta) / PawnValueMg, 3)) * ONE_PLY;
700
        Depth R = ((823 + 67 * depth / ONE_PLY) / 256 + std::min((eval - beta) / PawnValueMg, 3)) * ONE_PLY;
-
 
701
 
-
 
702
        ss->currentMove = MOVE_NULL;
-
 
703
        ss->contHistory = &thisThread->contHistory[NO_PIECE][0];
755
 
704
 
756
        pos.do_null_move(st);
705
        pos.do_null_move(st);
757
        (ss+1)->skipEarlyPruning = true;
-
 
758
        nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -beta+1, DEPTH_ZERO)
706
        Value nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -beta+1)
759
                                      : - search<NonPV>(pos, ss+1, -beta, -beta+1, depth-R, !cutNode);
707
                                            : - search<NonPV>(pos, ss+1, -beta, -beta+1, depth-R, !cutNode, true);
760
        (ss+1)->skipEarlyPruning = false;
-
 
761
        pos.undo_null_move();
708
        pos.undo_null_move();
762
 
709
 
763
        if (nullValue >= beta)
710
        if (nullValue >= beta)
764
        {
711
        {
765
            // Do not return unproven mate scores
712
            // Do not return unproven mate scores
766
            if (nullValue >= VALUE_MATE_IN_MAX_PLY)
713
            if (nullValue >= VALUE_MATE_IN_MAX_PLY)
767
                nullValue = beta;
714
                nullValue = beta;
768
 
715
 
769
            if (depth < 12 * ONE_PLY && abs(beta) < VALUE_KNOWN_WIN)
716
            if (abs(beta) < VALUE_KNOWN_WIN && (depth < 12 * ONE_PLY || thisThread->nmp_ply))
770
                return nullValue;
717
                return nullValue;
771
 
718
 
772
            // Do verification search at high depths
719
            // Do verification search at high depths
-
 
720
            // disable null move pruning for side to move for the first part of the remaining search tree
-
 
721
            thisThread->nmp_ply = ss->ply + 3 * (depth-R) / 4;
773
            ss->skipEarlyPruning = true;
722
            thisThread->nmp_odd = ss->ply % 2;
-
 
723
 
774
            Value v = depth-R < ONE_PLY ? qsearch<NonPV, false>(pos, ss, beta-1, beta, DEPTH_ZERO)
724
            Value v = depth-R < ONE_PLY ? qsearch<NonPV, false>(pos, ss, beta-1, beta)
775
                                        :  search<NonPV>(pos, ss, beta-1, beta, depth-R, false);
725
                                        :  search<NonPV>(pos, ss, beta-1, beta, depth-R, false, true);
-
 
726
 
776
            ss->skipEarlyPruning = false;
727
            thisThread->nmp_odd = thisThread->nmp_ply = 0;
777
 
728
 
778
            if (v >= beta)
729
            if (v >= beta)
779
                return nullValue;
730
                return nullValue;
780
        }
731
        }
781
    }
732
    }
Line 786... Line 737...
786
    if (   !PvNode
737
    if (   !PvNode
787
        &&  depth >= 5 * ONE_PLY
738
        &&  depth >= 5 * ONE_PLY
788
        &&  abs(beta) < VALUE_MATE_IN_MAX_PLY)
739
        &&  abs(beta) < VALUE_MATE_IN_MAX_PLY)
789
    {
740
    {
790
        Value rbeta = std::min(beta + 200, VALUE_INFINITE);
741
        Value rbeta = std::min(beta + 200, VALUE_INFINITE);
791
        Depth rdepth = depth - 4 * ONE_PLY;
-
 
792
 
742
 
793
        assert(rdepth >= ONE_PLY);
-
 
794
        assert((ss-1)->currentMove != MOVE_NONE);
-
 
795
        assert((ss-1)->currentMove != MOVE_NULL);
743
        assert(is_ok((ss-1)->currentMove));
796
 
744
 
797
        MovePicker mp(pos, ttMove, rbeta - ss->staticEval);
745
        MovePicker mp(pos, ttMove, rbeta - ss->staticEval, &thisThread->captureHistory);
798
 
746
 
799
        while ((move = mp.next_move()) != MOVE_NONE)
747
        while ((move = mp.next_move()) != MOVE_NONE)
800
            if (pos.legal(move))
748
            if (pos.legal(move))
801
            {
749
            {
802
                ss->currentMove = move;
750
                ss->currentMove = move;
803
                ss->counterMoves = &thisThread->counterMoveHistory[pos.moved_piece(move)][to_sq(move)];
751
                ss->contHistory = &thisThread->contHistory[pos.moved_piece(move)][to_sq(move)];
-
 
752
 
-
 
753
                assert(depth >= 5 * ONE_PLY);
804
                pos.do_move(move, st, pos.gives_check(move));
754
                pos.do_move(move, st);
805
                value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, rdepth, !cutNode);
755
                value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, depth - 4 * ONE_PLY, !cutNode, false);
806
                pos.undo_move(move);
756
                pos.undo_move(move);
807
                if (value >= rbeta)
757
                if (value >= rbeta)
808
                    return value;
758
                    return value;
809
            }
759
            }
810
    }
760
    }
Line 813... Line 763...
813
    if (    depth >= 6 * ONE_PLY
763
    if (    depth >= 6 * ONE_PLY
814
        && !ttMove
764
        && !ttMove
815
        && (PvNode || ss->staticEval + 256 >= beta))
765
        && (PvNode || ss->staticEval + 256 >= beta))
816
    {
766
    {
817
        Depth d = (3 * depth / (4 * ONE_PLY) - 2) * ONE_PLY;
767
        Depth d = (3 * depth / (4 * ONE_PLY) - 2) * ONE_PLY;
818
        ss->skipEarlyPruning = true;
-
 
819
        search<NT>(pos, ss, alpha, beta, d, cutNode);
768
        search<NT>(pos, ss, alpha, beta, d, cutNode, true);
820
        ss->skipEarlyPruning = false;
-
 
821
 
769
 
822
        tte = TT.probe(posKey, ttHit);
770
        tte = TT.probe(posKey, ttHit);
823
        ttMove = ttHit ? tte->move() : MOVE_NONE;
771
        ttMove = ttHit ? tte->move() : MOVE_NONE;
824
    }
772
    }
825
 
773
 
826
moves_loop: // When in check search starts from here
774
moves_loop: // When in check search starts from here
827
 
775
 
828
    const CounterMoveStats* cmh  = (ss-1)->counterMoves;
776
    const PieceToHistory* contHist[] = { (ss-1)->contHistory, (ss-2)->contHistory, nullptr, (ss-4)->contHistory };
829
    const CounterMoveStats* fmh  = (ss-2)->counterMoves;
777
    Move countermove = thisThread->counterMoves[pos.piece_on(prevSq)][prevSq];
830
    const CounterMoveStats* fmh2 = (ss-4)->counterMoves;
-
 
831
 
778
 
832
    MovePicker mp(pos, ttMove, depth, ss);
779
    MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory, &thisThread->captureHistory, contHist, countermove, ss->killers);
833
    value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
780
    value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
834
    improving =   ss->staticEval >= (ss-2)->staticEval
781
    improving =   ss->staticEval >= (ss-2)->staticEval
835
            /* || ss->staticEval == VALUE_NONE Already implicit in the previous condition */
782
            /* || ss->staticEval == VALUE_NONE Already implicit in the previous condition */
836
               ||(ss-2)->staticEval == VALUE_NONE;
783
               ||(ss-2)->staticEval == VALUE_NONE;
837
 
784
 
Line 840... Line 787...
840
                           &&  ttMove != MOVE_NONE
787
                           &&  ttMove != MOVE_NONE
841
                           &&  ttValue != VALUE_NONE
788
                           &&  ttValue != VALUE_NONE
842
                           && !excludedMove // Recursive singular search is not allowed
789
                           && !excludedMove // Recursive singular search is not allowed
843
                           && (tte->bound() & BOUND_LOWER)
790
                           && (tte->bound() & BOUND_LOWER)
844
                           &&  tte->depth() >= depth - 3 * ONE_PLY;
791
                           &&  tte->depth() >= depth - 3 * ONE_PLY;
-
 
792
    skipQuiets = false;
-
 
793
    ttCapture = false;
-
 
794
    pvExact = PvNode && ttHit && tte->bound() == BOUND_EXACT;
845
 
795
 
846
    // Step 11. Loop through moves
796
    // Step 11. Loop through moves
847
    // Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
797
    // Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
848
    while ((move = mp.next_move()) != MOVE_NONE)
798
    while ((move = mp.next_move(skipQuiets)) != MOVE_NONE)
849
    {
799
    {
850
      assert(is_ok(move));
800
      assert(is_ok(move));
851
 
801
 
852
      if (move == excludedMove)
802
      if (move == excludedMove)
853
          continue;
803
          continue;
Line 869... Line 819...
869
      if (PvNode)
819
      if (PvNode)
870
          (ss+1)->pv = nullptr;
820
          (ss+1)->pv = nullptr;
871
 
821
 
872
      extension = DEPTH_ZERO;
822
      extension = DEPTH_ZERO;
873
      captureOrPromotion = pos.capture_or_promotion(move);
823
      captureOrPromotion = pos.capture_or_promotion(move);
874
      moved_piece = pos.moved_piece(move);
824
      movedPiece = pos.moved_piece(move);
875
 
825
 
876
      givesCheck =  type_of(move) == NORMAL && !pos.discovered_check_candidates()
826
      givesCheck =  type_of(move) == NORMAL && !pos.discovered_check_candidates()
877
                  ? pos.check_squares(type_of(pos.piece_on(from_sq(move)))) & to_sq(move)
827
                  ? pos.check_squares(type_of(movedPiece)) & to_sq(move)
878
                  : pos.gives_check(move);
828
                  : pos.gives_check(move);
879
 
829
 
880
      moveCountPruning =   depth < 16 * ONE_PLY
830
      moveCountPruning =   depth < 16 * ONE_PLY
881
                        && moveCount >= FutilityMoveCounts[improving][depth / ONE_PLY];
831
                        && moveCount >= FutilityMoveCounts[improving][depth / ONE_PLY];
882
 
832
 
883
      // Step 12. Extend checks
833
      // Step 12. Singular and Gives Check Extensions
884
      if (    givesCheck
-
 
885
          && !moveCountPruning
-
 
886
          &&  pos.see_ge(move, VALUE_ZERO))
-
 
887
          extension = ONE_PLY;
-
 
888
 
834
 
889
      // Singular extension search. If all moves but one fail low on a search of
835
      // Singular extension search. If all moves but one fail low on a search of
890
      // (alpha-s, beta-s), and just one fails high on (alpha, beta), then that move
836
      // (alpha-s, beta-s), and just one fails high on (alpha, beta), then that move
891
      // is singular and should be extended. To verify this we do a reduced search
837
      // is singular and should be extended. To verify this we do a reduced search
892
      // on all the other moves but the ttMove and if the result is lower than
838
      // on all the other moves but the ttMove and if the result is lower than
893
      // ttValue minus a margin then we extend the ttMove.
839
      // ttValue minus a margin then we will extend the ttMove.
894
      if (    singularExtensionNode
840
      if (    singularExtensionNode
895
          &&  move == ttMove
841
          &&  move == ttMove
896
          && !extension
-
 
897
          &&  pos.legal(move))
842
          &&  pos.legal(move))
898
      {
843
      {
899
          Value rBeta = std::max(ttValue - 2 * depth / ONE_PLY, -VALUE_MATE);
844
          Value rBeta = std::max(ttValue - 2 * depth / ONE_PLY, -VALUE_MATE);
900
          Depth d = (depth / (2 * ONE_PLY)) * ONE_PLY;
845
          Depth d = (depth / (2 * ONE_PLY)) * ONE_PLY;
901
          ss->excludedMove = move;
846
          ss->excludedMove = move;
902
          ss->skipEarlyPruning = true;
-
 
903
          value = search<NonPV>(pos, ss, rBeta - 1, rBeta, d, cutNode);
847
          value = search<NonPV>(pos, ss, rBeta - 1, rBeta, d, cutNode, true);
904
          ss->skipEarlyPruning = false;
-
 
905
          ss->excludedMove = MOVE_NONE;
848
          ss->excludedMove = MOVE_NONE;
906
 
849
 
907
          if (value < rBeta)
850
          if (value < rBeta)
908
              extension = ONE_PLY;
851
              extension = ONE_PLY;
909
      }
852
      }
-
 
853
      else if (    givesCheck
-
 
854
               && !moveCountPruning
-
 
855
               &&  pos.see_ge(move))
-
 
856
          extension = ONE_PLY;
910
 
857
 
911
      // Update the current move (this must be done after singular extension search)
858
      // Calculate new depth for this move
912
      newDepth = depth - ONE_PLY + extension;
859
      newDepth = depth - ONE_PLY + extension;
913
 
860
 
914
      // Step 13. Pruning at shallow depth
861
      // Step 13. Pruning at shallow depth
915
      if (  !rootNode
862
      if (  !rootNode
-
 
863
          && pos.non_pawn_material(pos.side_to_move())
916
          && bestValue > VALUE_MATED_IN_MAX_PLY)
864
          && bestValue > VALUE_MATED_IN_MAX_PLY)
917
      {
865
      {
918
          if (   !captureOrPromotion
866
          if (   !captureOrPromotion
919
              && !givesCheck
867
              && !givesCheck
920
              && !pos.advanced_pawn_push(move))
868
              && (!pos.advanced_pawn_push(move) || pos.non_pawn_material() >= Value(5000)))
921
          {
869
          {
922
              // Move count based pruning
870
              // Move count based pruning
923
              if (moveCountPruning)
871
              if (moveCountPruning)
-
 
872
              {
-
 
873
                  skipQuiets = true;
924
                  continue;
874
                  continue;
-
 
875
              }
925
 
876
 
926
              // Reduced depth of the next LMR search
877
              // Reduced depth of the next LMR search
927
              int lmrDepth = std::max(newDepth - reduction<PvNode>(improving, depth, moveCount), DEPTH_ZERO) / ONE_PLY;
878
              int lmrDepth = std::max(newDepth - reduction<PvNode>(improving, depth, moveCount), DEPTH_ZERO) / ONE_PLY;
928
 
879
 
929
              // Countermoves based pruning
880
              // Countermoves based pruning
930
              if (   lmrDepth < 3
881
              if (   lmrDepth < 3
931
                  && (!cmh  || (*cmh )[moved_piece][to_sq(move)] < VALUE_ZERO)
882
                  && (*contHist[0])[movedPiece][to_sq(move)] < CounterMovePruneThreshold
932
                  && (!fmh  || (*fmh )[moved_piece][to_sq(move)] < VALUE_ZERO)
-
 
933
                  && (!fmh2 || (*fmh2)[moved_piece][to_sq(move)] < VALUE_ZERO || (cmh && fmh)))
883
                  && (*contHist[1])[movedPiece][to_sq(move)] < CounterMovePruneThreshold)
934
                  continue;
884
                  continue;
935
 
885
 
936
              // Futility pruning: parent node
886
              // Futility pruning: parent node
937
              if (   lmrDepth < 7
887
              if (   lmrDepth < 7
938
                  && !inCheck
888
                  && !inCheck
Line 942... Line 892...
942
              // Prune moves with negative SEE
892
              // Prune moves with negative SEE
943
              if (   lmrDepth < 8
893
              if (   lmrDepth < 8
944
                  && !pos.see_ge(move, Value(-35 * lmrDepth * lmrDepth)))
894
                  && !pos.see_ge(move, Value(-35 * lmrDepth * lmrDepth)))
945
                  continue;
895
                  continue;
946
          }
896
          }
947
          else if (   depth < 7 * ONE_PLY
897
          else if (    depth < 7 * ONE_PLY
948
                   && !extension
898
                   && !extension
949
                   && !pos.see_ge(move, Value(-35 * depth / ONE_PLY * depth / ONE_PLY)))
899
                   && !pos.see_ge(move, -PawnValueEg * (depth / ONE_PLY)))
950
                  continue;
900
                  continue;
951
      }
901
      }
952
 
902
 
953
      // Speculative prefetch as early as possible
903
      // Speculative prefetch as early as possible
954
      prefetch(TT.first_entry(pos.key_after(move)));
904
      prefetch(TT.first_entry(pos.key_after(move)));
Line 958... Line 908...
958
      {
908
      {
959
          ss->moveCount = --moveCount;
909
          ss->moveCount = --moveCount;
960
          continue;
910
          continue;
961
      }
911
      }
962
 
912
 
-
 
913
      if (move == ttMove && captureOrPromotion)
-
 
914
          ttCapture = true;
-
 
915
 
-
 
916
      // Update the current move (this must be done after singular extension search)
963
      ss->currentMove = move;
917
      ss->currentMove = move;
964
      ss->counterMoves = &thisThread->counterMoveHistory[moved_piece][to_sq(move)];
918
      ss->contHistory = &thisThread->contHistory[movedPiece][to_sq(move)];
965
 
919
 
966
      // Step 14. Make the move
920
      // Step 14. Make the move
967
      pos.do_move(move, st, givesCheck);
921
      pos.do_move(move, st, givesCheck);
968
 
922
 
969
      // Step 15. Reduced depth search (LMR). If the move fails high it will be
923
      // Step 15. Reduced depth search (LMR). If the move fails high it will be
Line 976... Line 930...
976
 
930
 
977
          if (captureOrPromotion)
931
          if (captureOrPromotion)
978
              r -= r ? ONE_PLY : DEPTH_ZERO;
932
              r -= r ? ONE_PLY : DEPTH_ZERO;
979
          else
933
          else
980
          {
934
          {
-
 
935
              // Decrease reduction if opponent's move count is high
-
 
936
              if ((ss-1)->moveCount > 15)
-
 
937
                  r -= ONE_PLY;
-
 
938
 
-
 
939
              // Decrease reduction for exact PV nodes
-
 
940
              if (pvExact)
-
 
941
                  r -= ONE_PLY;
-
 
942
 
-
 
943
              // Increase reduction if ttMove is a capture
-
 
944
              if (ttCapture)
-
 
945
                  r += ONE_PLY;
-
 
946
 
981
              // Increase reduction for cut nodes
947
              // Increase reduction for cut nodes
982
              if (cutNode)
948
              if (cutNode)
983
                  r += 2 * ONE_PLY;
949
                  r += 2 * ONE_PLY;
984
 
950
 
985
              // Decrease reduction for moves that escape a capture. Filter out
951
              // Decrease reduction for moves that escape a capture. Filter out
986
              // castling moves, because they are coded as "king captures rook" and
952
              // 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.
953
              // hence break make_move().
989
              else if (   type_of(move) == NORMAL
954
              else if (    type_of(move) == NORMAL
990
                       && type_of(pos.piece_on(to_sq(move))) != PAWN
-
 
991
                       && !pos.see_ge(make_move(to_sq(move), from_sq(move)),  VALUE_ZERO))
955
                       && !pos.see_ge(make_move(to_sq(move), from_sq(move))))
992
                  r -= 2 * ONE_PLY;
956
                  r -= 2 * ONE_PLY;
993
 
957
 
994
              ss->history = thisThread->history[moved_piece][to_sq(move)]
958
              ss->statScore =  thisThread->mainHistory[~pos.side_to_move()][from_to(move)]
995
                           +    (cmh  ? (*cmh )[moved_piece][to_sq(move)] : VALUE_ZERO)
959
                             + (*contHist[0])[movedPiece][to_sq(move)]
996
                           +    (fmh  ? (*fmh )[moved_piece][to_sq(move)] : VALUE_ZERO)
960
                             + (*contHist[1])[movedPiece][to_sq(move)]
997
                           +    (fmh2 ? (*fmh2)[moved_piece][to_sq(move)] : VALUE_ZERO)
961
                             + (*contHist[3])[movedPiece][to_sq(move)]
998
                           +    thisThread->fromTo.get(~pos.side_to_move(), move)
-
 
999
                           -    8000; // Correction factor
962
                             - 4000;
1000
 
963
 
1001
              // Decrease/increase reduction by comparing opponent's stat score
964
              // Decrease/increase reduction by comparing opponent's stat score
1002
              if (ss->history > VALUE_ZERO && (ss-1)->history < VALUE_ZERO)
965
              if (ss->statScore >= 0 && (ss-1)->statScore < 0)
1003
                  r -= ONE_PLY;
966
                  r -= ONE_PLY;
1004
 
967
 
1005
              else if (ss->history < VALUE_ZERO && (ss-1)->history > VALUE_ZERO)
968
              else if ((ss-1)->statScore >= 0 && ss->statScore < 0)
1006
                  r += ONE_PLY;
969
                  r += ONE_PLY;
1007
 
970
 
1008
              // Decrease/increase reduction for moves with a good/bad history
971
              // Decrease/increase reduction for moves with a good/bad history
1009
              r = std::max(DEPTH_ZERO, (r / ONE_PLY - ss->history / 20000) * ONE_PLY);
972
              r = std::max(DEPTH_ZERO, (r / ONE_PLY - ss->statScore / 20000) * ONE_PLY);
1010
          }
973
          }
1011
 
974
 
1012
          Depth d = std::max(newDepth - r, ONE_PLY);
975
          Depth d = std::max(newDepth - r, ONE_PLY);
1013
 
976
 
1014
          value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
977
          value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true, false);
1015
 
978
 
1016
          doFullDepthSearch = (value > alpha && d != newDepth);
979
          doFullDepthSearch = (value > alpha && d != newDepth);
1017
      }
980
      }
1018
      else
981
      else
1019
          doFullDepthSearch = !PvNode || moveCount > 1;
982
          doFullDepthSearch = !PvNode || moveCount > 1;
1020
 
983
 
1021
      // Step 16. Full depth search when LMR is skipped or fails high
984
      // Step 16. Full depth search when LMR is skipped or fails high
1022
      if (doFullDepthSearch)
985
      if (doFullDepthSearch)
1023
          value = newDepth <   ONE_PLY ?
986
          value = newDepth <   ONE_PLY ?
1024
                            givesCheck ? -qsearch<NonPV,  true>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO)
987
                            givesCheck ? -qsearch<NonPV,  true>(pos, ss+1, -(alpha+1), -alpha)
1025
                                       : -qsearch<NonPV, false>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO)
988
                                       : -qsearch<NonPV, false>(pos, ss+1, -(alpha+1), -alpha)
1026
                                       : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, !cutNode);
989
                                       : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, !cutNode, false);
1027
 
990
 
1028
      // For PV nodes only, do a full PV search on the first move or after a fail
991
      // For PV nodes only, do a full PV search on the first move or after a fail
1029
      // high (in the latter case search only if value < beta), otherwise let the
992
      // high (in the latter case search only if value < beta), otherwise let the
1030
      // parent node fail low with value <= alpha and try another move.
993
      // parent node fail low with value <= alpha and try another move.
1031
      if (PvNode && (moveCount == 1 || (value > alpha && (rootNode || value < beta))))
994
      if (PvNode && (moveCount == 1 || (value > alpha && (rootNode || value < beta))))
1032
      {
995
      {
1033
          (ss+1)->pv = pv;
996
          (ss+1)->pv = pv;
1034
          (ss+1)->pv[0] = MOVE_NONE;
997
          (ss+1)->pv[0] = MOVE_NONE;
1035
 
998
 
1036
          value = newDepth <   ONE_PLY ?
999
          value = newDepth <   ONE_PLY ?
1037
                            givesCheck ? -qsearch<PV,  true>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
1000
                            givesCheck ? -qsearch<PV,  true>(pos, ss+1, -beta, -alpha)
1038
                                       : -qsearch<PV, false>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
1001
                                       : -qsearch<PV, false>(pos, ss+1, -beta, -alpha)
1039
                                       : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, false);
1002
                                       : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, false, false);
1040
      }
1003
      }
1041
 
1004
 
1042
      // Step 17. Undo move
1005
      // Step 17. Undo move
1043
      pos.undo_move(move);
1006
      pos.undo_move(move);
1044
 
1007
 
Line 1046... Line 1009...
1046
 
1009
 
1047
      // Step 18. Check for a new best move
1010
      // Step 18. Check for a new best move
1048
      // Finished searching the move. If a stop occurred, the return value of
1011
      // Finished searching the move. If a stop occurred, the return value of
1049
      // the search cannot be trusted, and we return immediately without
1012
      // the search cannot be trusted, and we return immediately without
1050
      // updating best move, PV and TT.
1013
      // updating best move, PV and TT.
1051
      if (Signals.stop.load(std::memory_order_relaxed))
1014
      if (Threads.stop.load(std::memory_order_relaxed))
1052
          return VALUE_ZERO;
1015
          return VALUE_ZERO;
1053
 
1016
 
1054
      if (rootNode)
1017
      if (rootNode)
1055
      {
1018
      {
1056
          RootMove& rm = *std::find(thisThread->rootMoves.begin(),
1019
          RootMove& rm = *std::find(thisThread->rootMoves.begin(),
Line 1058... Line 1021...
1058
 
1021
 
1059
          // PV move or new best move ?
1022
          // PV move or new best move ?
1060
          if (moveCount == 1 || value > alpha)
1023
          if (moveCount == 1 || value > alpha)
1061
          {
1024
          {
1062
              rm.score = value;
1025
              rm.score = value;
-
 
1026
              rm.selDepth = thisThread->selDepth;
1063
              rm.pv.resize(1);
1027
              rm.pv.resize(1);
1064
 
1028
 
1065
              assert((ss+1)->pv);
1029
              assert((ss+1)->pv);
1066
 
1030
 
1067
              for (Move* m = (ss+1)->pv; *m != MOVE_NONE; ++m)
1031
              for (Move* m = (ss+1)->pv; *m != MOVE_NONE; ++m)
Line 1072... Line 1036...
1072
              // the best move changes frequently, we allocate some more time.
1036
              // the best move changes frequently, we allocate some more time.
1073
              if (moveCount > 1 && thisThread == Threads.main())
1037
              if (moveCount > 1 && thisThread == Threads.main())
1074
                  ++static_cast<MainThread*>(thisThread)->bestMoveChanges;
1038
                  ++static_cast<MainThread*>(thisThread)->bestMoveChanges;
1075
          }
1039
          }
1076
          else
1040
          else
1077
              // All other moves but the PV are set to the lowest value: this is
1041
              // All other moves but the PV are set to the lowest value: this
1078
              // not a problem when sorting because the sort is stable and the
1042
              // is not a problem when sorting because the sort is stable and the
1079
              // move position in the list is preserved - just the PV is pushed up.
1043
              // move position in the list is preserved - just the PV is pushed up.
1080
              rm.score = -VALUE_INFINITE;
1044
              rm.score = -VALUE_INFINITE;
1081
      }
1045
      }
1082
 
1046
 
1083
      if (value > bestValue)
1047
      if (value > bestValue)
1084
      {
1048
      {
1085
          bestValue = value;
1049
          bestValue = value;
1086
 
1050
 
1087
          if (value > alpha)
1051
          if (value > alpha)
1088
          {
1052
          {
1089
              // If there is an easy move for this position, clear it if unstable
-
 
1090
              if (    PvNode
-
 
1091
                  &&  thisThread == Threads.main()
-
 
1092
                  &&  EasyMove.get(pos.key())
-
 
1093
                  && (move != EasyMove.get(pos.key()) || moveCount > 1))
-
 
1094
                  EasyMove.clear();
-
 
1095
 
-
 
1096
              bestMove = move;
1053
              bestMove = move;
1097
 
1054
 
1098
              if (PvNode && !rootNode) // Update pv even in fail-high case
1055
              if (PvNode && !rootNode) // Update pv even in fail-high case
1099
                  update_pv(ss->pv, move, (ss+1)->pv);
1056
                  update_pv(ss->pv, move, (ss+1)->pv);
1100
 
1057
 
Line 1108... Line 1065...
1108
          }
1065
          }
1109
      }
1066
      }
1110
 
1067
 
1111
      if (!captureOrPromotion && move != bestMove && quietCount < 64)
1068
      if (!captureOrPromotion && move != bestMove && quietCount < 64)
1112
          quietsSearched[quietCount++] = move;
1069
          quietsSearched[quietCount++] = move;
-
 
1070
      else if (captureOrPromotion && move != bestMove && captureCount < 32)
-
 
1071
          capturesSearched[captureCount++] = move;
1113
    }
1072
    }
1114
 
1073
 
1115
    // The following condition would detect a stop only after move loop has been
1074
    // The following condition would detect a stop only after move loop has been
1116
    // completed. But in this case bestValue is valid because we have fully
1075
    // completed. But in this case bestValue is valid because we have fully
1117
    // searched our subtree, and we can anyhow save the result in TT.
1076
    // searched our subtree, and we can anyhow save the result in TT.
1118
    /*
1077
    /*
1119
       if (Signals.stop)
1078
       if (Threads.stop)
1120
        return VALUE_DRAW;
1079
        return VALUE_DRAW;
1121
    */
1080
    */
1122
 
1081
 
1123
    // Step 20. Check for mate and stalemate
1082
    // Step 20. Check for mate and stalemate
1124
    // All legal moves have been searched and if there are no legal moves, it
1083
    // All legal moves have been searched and if there are no legal moves, it
Line 1127... Line 1086...
1127
 
1086
 
1128
    assert(moveCount || !inCheck || excludedMove || !MoveList<LEGAL>(pos).size());
1087
    assert(moveCount || !inCheck || excludedMove || !MoveList<LEGAL>(pos).size());
1129
 
1088
 
1130
    if (!moveCount)
1089
    if (!moveCount)
1131
        bestValue = excludedMove ? alpha
1090
        bestValue = excludedMove ? alpha
1132
                   :     inCheck ? mated_in(ss->ply) : DrawValue[pos.side_to_move()];
1091
                   :     inCheck ? mated_in(ss->ply) : VALUE_DRAW;
1133
    else if (bestMove)
1092
    else if (bestMove)
1134
    {
1093
    {
1135
        int d = depth / ONE_PLY;
-
 
1136
 
-
 
1137
        // Quiet best move: update killers, history and countermoves
1094
        // Quiet best move: update move sorting heuristics
1138
        if (!pos.capture_or_promotion(bestMove))
1095
        if (!pos.capture_or_promotion(bestMove))
1139
        {
-
 
1140
            Value bonus = Value(d * d + 2 * d - 2);
-
 
1141
            update_stats(pos, ss, bestMove, quietsSearched, quietCount, bonus);
1096
            update_stats(pos, ss, bestMove, quietsSearched, quietCount, stat_bonus(depth));
1142
        }
1097
        else
-
 
1098
            update_capture_stats(pos, bestMove, capturesSearched, captureCount, stat_bonus(depth));
1143
 
1099
 
1144
        // Extra penalty for a quiet TT move in previous ply when it gets refuted
1100
        // Extra penalty for a quiet TT move in previous ply when it gets refuted
1145
        if ((ss-1)->moveCount == 1 && !pos.captured_piece())
1101
        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);
1102
            update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY));
1150
        }
-
 
1151
    }
1103
    }
1152
    // Bonus for prior countermove that caused the fail low
1104
    // Bonus for prior countermove that caused the fail low
1153
    else if (    depth >= 3 * ONE_PLY
1105
    else if (    depth >= 3 * ONE_PLY
1154
             && !pos.captured_piece()
1106
             && !pos.captured_piece()
1155
             && is_ok((ss-1)->currentMove))
1107
             && is_ok((ss-1)->currentMove))
1156
    {
-
 
1157
        int d = depth / ONE_PLY;
-
 
1158
        Value bonus = Value(d * d + 2 * d - 2);
-
 
1159
        Square prevSq = to_sq((ss-1)->currentMove);
-
 
1160
        update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, bonus);
1108
        update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth));
1161
    }
-
 
1162
 
1109
 
-
 
1110
    if (PvNode)
-
 
1111
        bestValue = std::min(bestValue, maxValue);
-
 
1112
 
-
 
1113
    if (!excludedMove)
1163
    tte->save(posKey, value_to_tt(bestValue, ss->ply),
1114
        tte->save(posKey, value_to_tt(bestValue, ss->ply),
1164
              bestValue >= beta ? BOUND_LOWER :
1115
                  bestValue >= beta ? BOUND_LOWER :
1165
              PvNode && bestMove ? BOUND_EXACT : BOUND_UPPER,
1116
                  PvNode && bestMove ? BOUND_EXACT : BOUND_UPPER,
1166
              depth, bestMove, ss->staticEval, TT.generation());
1117
                  depth, bestMove, ss->staticEval, TT.generation());
1167
 
1118
 
1168
    assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
1119
    assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
1169
 
1120
 
1170
    return bestValue;
1121
    return bestValue;
1171
  }
1122
  }
1172
 
1123
 
1173
 
1124
 
1174
  // qsearch() is the quiescence search function, which is called by the main
1125
  // qsearch() is the quiescence search function, which is called by the main
1175
  // search function when the remaining depth is zero (or, to be more precise,
1126
  // search function with depth zero, or recursively with depth less than ONE_PLY.
1176
  // less than ONE_PLY).
-
 
1177
 
1127
 
1178
  template <NodeType NT, bool InCheck>
1128
  template <NodeType NT, bool InCheck>
1179
  Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) {
1129
  Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) {
1180
 
1130
 
1181
    const bool PvNode = NT == PV;
1131
    const bool PvNode = NT == PV;
1182
 
1132
 
1183
    assert(InCheck == !!pos.checkers());
1133
    assert(InCheck == bool(pos.checkers()));
1184
    assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE);
1134
    assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE);
1185
    assert(PvNode || (alpha == beta - 1));
1135
    assert(PvNode || (alpha == beta - 1));
1186
    assert(depth <= DEPTH_ZERO);
1136
    assert(depth <= DEPTH_ZERO);
1187
    assert(depth / ONE_PLY * ONE_PLY == depth);
1137
    assert(depth / ONE_PLY * ONE_PLY == depth);
1188
 
1138
 
Line 1192... Line 1142...
1192
    Key posKey;
1142
    Key posKey;
1193
    Move ttMove, move, bestMove;
1143
    Move ttMove, move, bestMove;
1194
    Value bestValue, value, ttValue, futilityValue, futilityBase, oldAlpha;
1144
    Value bestValue, value, ttValue, futilityValue, futilityBase, oldAlpha;
1195
    bool ttHit, givesCheck, evasionPrunable;
1145
    bool ttHit, givesCheck, evasionPrunable;
1196
    Depth ttDepth;
1146
    Depth ttDepth;
-
 
1147
    int moveCount;
1197
 
1148
 
1198
    if (PvNode)
1149
    if (PvNode)
1199
    {
1150
    {
1200
        oldAlpha = alpha; // To flag BOUND_EXACT when eval above alpha and no available moves
1151
        oldAlpha = alpha; // To flag BOUND_EXACT when eval above alpha and no available moves
1201
        (ss+1)->pv = pv;
1152
        (ss+1)->pv = pv;
1202
        ss->pv[0] = MOVE_NONE;
1153
        ss->pv[0] = MOVE_NONE;
1203
    }
1154
    }
1204
 
1155
 
1205
    ss->currentMove = bestMove = MOVE_NONE;
1156
    ss->currentMove = bestMove = MOVE_NONE;
1206
    ss->ply = (ss-1)->ply + 1;
1157
    (ss+1)->ply = ss->ply + 1;
-
 
1158
    moveCount = 0;
1207
 
1159
 
1208
    // Check for an instant draw or if the maximum ply has been reached
1160
    // Check for an instant draw or if the maximum ply has been reached
1209
    if (pos.is_draw() || ss->ply >= MAX_PLY)
1161
    if (pos.is_draw(ss->ply) || ss->ply >= MAX_PLY)
1210
        return ss->ply >= MAX_PLY && !InCheck ? evaluate(pos)
1162
        return ss->ply >= MAX_PLY && !InCheck ? evaluate(pos) : VALUE_DRAW;
1211
                                              : DrawValue[pos.side_to_move()];
-
 
1212
 
1163
 
1213
    assert(0 <= ss->ply && ss->ply < MAX_PLY);
1164
    assert(0 <= ss->ply && ss->ply < MAX_PLY);
1214
 
1165
 
1215
    // Decide whether or not to include checks: this fixes also the type of
1166
    // Decide whether or not to include checks: this fixes also the type of
1216
    // TT entry depth that we are going to use. Note that in qsearch we use
1167
    // TT entry depth that we are going to use. Note that in qsearch we use
1217
    // only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS.
1168
    // only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS.
1218
    ttDepth = InCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS
1169
    ttDepth = InCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS
1219
                                                  : DEPTH_QS_NO_CHECKS;
1170
                                                  : DEPTH_QS_NO_CHECKS;
1220
 
-
 
1221
    // Transposition table lookup
1171
    // Transposition table lookup
1222
    posKey = pos.key();
1172
    posKey = pos.key();
1223
    tte = TT.probe(posKey, ttHit);
1173
    tte = TT.probe(posKey, ttHit);
1224
    ttMove = ttHit ? tte->move() : MOVE_NONE;
1174
    ttMove = ttHit ? tte->move() : MOVE_NONE;
1225
    ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
1175
    ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
Line 1245... Line 1195...
1245
            // Never assume anything on values stored in TT
1195
            // Never assume anything on values stored in TT
1246
            if ((ss->staticEval = bestValue = tte->eval()) == VALUE_NONE)
1196
            if ((ss->staticEval = bestValue = tte->eval()) == VALUE_NONE)
1247
                ss->staticEval = bestValue = evaluate(pos);
1197
                ss->staticEval = bestValue = evaluate(pos);
1248
 
1198
 
1249
            // Can ttValue be used as a better position evaluation?
1199
            // Can ttValue be used as a better position evaluation?
1250
            if (ttValue != VALUE_NONE)
1200
            if (   ttValue != VALUE_NONE
1251
                if (tte->bound() & (ttValue > bestValue ? BOUND_LOWER : BOUND_UPPER))
1201
                && (tte->bound() & (ttValue > bestValue ? BOUND_LOWER : BOUND_UPPER)))
1252
                    bestValue = ttValue;
1202
                bestValue = ttValue;
1253
        }
1203
        }
1254
        else
1204
        else
1255
            ss->staticEval = bestValue =
1205
            ss->staticEval = bestValue =
1256
            (ss-1)->currentMove != MOVE_NULL ? evaluate(pos)
1206
            (ss-1)->currentMove != MOVE_NULL ? evaluate(pos)
1257
                                             : -(ss-1)->staticEval + 2 * Eval::Tempo;
1207
                                             : -(ss-1)->staticEval + 2 * Eval::Tempo;
1258
 
1208
 
1259
        // Stand pat. Return immediately if static value is at least beta
1209
        // Stand pat. Return immediately if static value is at least beta
1260
        if (bestValue >= beta)
1210
        if (bestValue >= beta)
1261
        {
1211
        {
1262
            if (!ttHit)
1212
            if (!ttHit)
1263
                tte->save(pos.key(), value_to_tt(bestValue, ss->ply), BOUND_LOWER,
1213
                tte->save(posKey, value_to_tt(bestValue, ss->ply), BOUND_LOWER,
1264
                          DEPTH_NONE, MOVE_NONE, ss->staticEval, TT.generation());
1214
                          DEPTH_NONE, MOVE_NONE, ss->staticEval, TT.generation());
1265
 
1215
 
1266
            return bestValue;
1216
            return bestValue;
1267
        }
1217
        }
1268
 
1218
 
Line 1274... Line 1224...
1274
 
1224
 
1275
    // Initialize a MovePicker object for the current position, and prepare
1225
    // Initialize a MovePicker object for the current position, and prepare
1276
    // to search the moves. Because the depth is <= 0 here, only captures,
1226
    // to search the moves. Because the depth is <= 0 here, only captures,
1277
    // queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
1227
    // queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
1278
    // be generated.
1228
    // be generated.
1279
    MovePicker mp(pos, ttMove, depth, to_sq((ss-1)->currentMove));
1229
    MovePicker mp(pos, ttMove, depth, &pos.this_thread()->mainHistory, &pos.this_thread()->captureHistory, to_sq((ss-1)->currentMove));
1280
 
1230
 
1281
    // Loop through the moves until no moves remain or a beta cutoff occurs
1231
    // Loop through the moves until no moves remain or a beta cutoff occurs
1282
    while ((move = mp.next_move()) != MOVE_NONE)
1232
    while ((move = mp.next_move()) != MOVE_NONE)
1283
    {
1233
    {
1284
      assert(is_ok(move));
1234
      assert(is_ok(move));
1285
 
1235
 
1286
      givesCheck =  type_of(move) == NORMAL && !pos.discovered_check_candidates()
1236
      givesCheck =  type_of(move) == NORMAL && !pos.discovered_check_candidates()
1287
                  ? pos.check_squares(type_of(pos.piece_on(from_sq(move)))) & to_sq(move)
1237
                  ? pos.check_squares(type_of(pos.moved_piece(move))) & to_sq(move)
1288
                  : pos.gives_check(move);
1238
                  : pos.gives_check(move);
-
 
1239
 
-
 
1240
      moveCount++;
1289
 
1241
 
1290
      // Futility pruning
1242
      // Futility pruning
1291
      if (   !InCheck
1243
      if (   !InCheck
1292
          && !givesCheck
1244
          && !givesCheck
1293
          &&  futilityBase > -VALUE_KNOWN_WIN
1245
          &&  futilityBase > -VALUE_KNOWN_WIN
Line 1310... Line 1262...
1310
          }
1262
          }
1311
      }
1263
      }
1312
 
1264
 
1313
      // Detect non-capture evasions that are candidates to be pruned
1265
      // Detect non-capture evasions that are candidates to be pruned
1314
      evasionPrunable =    InCheck
1266
      evasionPrunable =    InCheck
-
 
1267
                       &&  (depth != DEPTH_ZERO || moveCount > 2)
1315
                       &&  bestValue > VALUE_MATED_IN_MAX_PLY
1268
                       &&  bestValue > VALUE_MATED_IN_MAX_PLY
1316
                       && !pos.capture(move);
1269
                       && !pos.capture(move);
1317
 
1270
 
1318
      // Don't search moves with negative SEE values
1271
      // Don't search moves with negative SEE values
1319
      if (  (!InCheck || evasionPrunable)
1272
      if (  (!InCheck || evasionPrunable)
1320
          &&  type_of(move) != PROMOTION
-
 
1321
          &&  !pos.see_ge(move, VALUE_ZERO))
1273
          &&  !pos.see_ge(move))
1322
          continue;
1274
          continue;
1323
 
1275
 
1324
      // Speculative prefetch as early as possible
1276
      // Speculative prefetch as early as possible
1325
      prefetch(TT.first_entry(pos.key_after(move)));
1277
      prefetch(TT.first_entry(pos.key_after(move)));
1326
 
1278
 
1327
      // Check for legality just before making the move
1279
      // Check for legality just before making the move
1328
      if (!pos.legal(move))
1280
      if (!pos.legal(move))
-
 
1281
      {
-
 
1282
          moveCount--;
1329
          continue;
1283
          continue;
-
 
1284
      }
1330
 
1285
 
1331
      ss->currentMove = move;
1286
      ss->currentMove = move;
1332
 
1287
 
1333
      // Make and search the move
1288
      // Make and search the move
1334
      pos.do_move(move, st, givesCheck);
1289
      pos.do_move(move, st, givesCheck);
Line 1412... Line 1367...
1412
        *pv++ = *childPv++;
1367
        *pv++ = *childPv++;
1413
    *pv = MOVE_NONE;
1368
    *pv = MOVE_NONE;
1414
  }
1369
  }
1415
 
1370
 
1416
 
1371
 
1417
  // update_cm_stats() updates countermove and follow-up move history
1372
  // update_continuation_histories() updates histories of the move pairs formed
-
 
1373
  // by moves at ply -1, -2, and -4 with current move.
1418
 
1374
 
1419
  void update_cm_stats(Stack* ss, Piece pc, Square s, Value bonus) {
1375
  void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus) {
1420
 
1376
 
1421
    CounterMoveStats* cmh  = (ss-1)->counterMoves;
1377
    for (int i : {1, 2, 4})
1422
    CounterMoveStats* fmh1 = (ss-2)->counterMoves;
1378
        if (is_ok((ss-i)->currentMove))
1423
    CounterMoveStats* fmh2 = (ss-4)->counterMoves;
1379
            (ss-i)->contHistory->update(pc, to, bonus);
-
 
1380
  }
1424
 
1381
 
1425
    if (cmh)
-
 
1426
        cmh->update(pc, s, bonus);
-
 
1427
 
1382
 
1428
    if (fmh1)
-
 
1429
        fmh1->update(pc, s, bonus);
1383
  // update_capture_stats() updates move sorting heuristics when a new capture best move is found
1430
 
1384
 
-
 
1385
  void update_capture_stats(const Position& pos, Move move,
-
 
1386
                            Move* captures, int captureCnt, int bonus) {
-
 
1387
 
-
 
1388
      CapturePieceToHistory& captureHistory =  pos.this_thread()->captureHistory;
-
 
1389
      Piece moved_piece = pos.moved_piece(move);
-
 
1390
      PieceType captured = type_of(pos.piece_on(to_sq(move)));
-
 
1391
      captureHistory.update(moved_piece, to_sq(move), captured, bonus);
-
 
1392
 
-
 
1393
      // Decrease all the other played capture moves
-
 
1394
      for (int i = 0; i < captureCnt; ++i)
1431
    if (fmh2)
1395
      {
1432
        fmh2->update(pc, s, bonus);
1396
          moved_piece = pos.moved_piece(captures[i]);
-
 
1397
          captured = type_of(pos.piece_on(to_sq(captures[i])));
-
 
1398
          captureHistory.update(moved_piece, to_sq(captures[i]), captured, -bonus);
-
 
1399
      }
1433
  }
1400
  }
1434
 
1401
 
1435
 
1402
 
1436
  // update_stats() updates killers, history, countermove and countermove plus
-
 
1437
  // follow-up move history when a new quiet best move is found.
1403
  // update_stats() updates move sorting heuristics when a new quiet best move is found
1438
 
1404
 
1439
  void update_stats(const Position& pos, Stack* ss, Move move,
1405
  void update_stats(const Position& pos, Stack* ss, Move move,
1440
                    Move* quiets, int quietsCnt, Value bonus) {
1406
                    Move* quiets, int quietsCnt, int bonus) {
1441
 
1407
 
1442
    if (ss->killers[0] != move)
1408
    if (ss->killers[0] != move)
1443
    {
1409
    {
1444
        ss->killers[1] = ss->killers[0];
1410
        ss->killers[1] = ss->killers[0];
1445
        ss->killers[0] = move;
1411
        ss->killers[0] = move;
1446
    }
1412
    }
1447
 
1413
 
1448
    Color c = pos.side_to_move();
1414
    Color c = pos.side_to_move();
1449
    Thread* thisThread = pos.this_thread();
1415
    Thread* thisThread = pos.this_thread();
1450
    thisThread->fromTo.update(c, move, bonus);
1416
    thisThread->mainHistory.update(c, 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);
1417
    update_continuation_histories(ss, pos.moved_piece(move), to_sq(move), bonus);
1453
 
1418
 
1454
    if ((ss-1)->counterMoves)
1419
    if (is_ok((ss-1)->currentMove))
1455
    {
1420
    {
1456
        Square prevSq = to_sq((ss-1)->currentMove);
1421
        Square prevSq = to_sq((ss-1)->currentMove);
1457
        thisThread->counterMoves.update(pos.piece_on(prevSq), prevSq, move);
1422
        thisThread->counterMoves[pos.piece_on(prevSq)][prevSq] = move;
1458
    }
1423
    }
1459
 
1424
 
1460
    // Decrease all the other played quiet moves
1425
    // Decrease all the other played quiet moves
1461
    for (int i = 0; i < quietsCnt; ++i)
1426
    for (int i = 0; i < quietsCnt; ++i)
1462
    {
1427
    {
1463
        thisThread->fromTo.update(c, quiets[i], -bonus);
1428
        thisThread->mainHistory.update(c, quiets[i], -bonus);
1464
        thisThread->history.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);
1429
        update_continuation_histories(ss, pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus);
1466
    }
1430
    }
-
 
1431
  }
-
 
1432
 
-
 
1433
 
-
 
1434
  // Is the PV leading to a draw position? Assumes all pv moves are legal
-
 
1435
  bool pv_is_draw(Position& pos) {
-
 
1436
 
-
 
1437
    StateInfo st[MAX_PLY];
-
 
1438
    auto& pv = pos.this_thread()->rootMoves[0].pv;
-
 
1439
 
-
 
1440
    for (size_t i = 0; i < pv.size(); ++i)
-
 
1441
        pos.do_move(pv[i], st[i]);
-
 
1442
 
-
 
1443
    bool isDraw = pos.is_draw(pv.size());
-
 
1444
 
-
 
1445
    for (size_t i = pv.size(); i > 0; --i)
-
 
1446
        pos.undo_move(pv[i-1]);
-
 
1447
 
-
 
1448
    return isDraw;
1467
  }
1449
  }
1468
 
1450
 
1469
 
1451
 
1470
  // When playing with strength handicap, choose best move among a set of RootMoves
1452
  // When playing with strength handicap, choose best move among a set of RootMoves
1471
  // using a statistical rule dependent on 'level'. Idea by Heinz van Saanen.
1453
  // using a statistical rule dependent on 'level'. Idea by Heinz van Saanen.
Line 1488... Line 1470...
1488
    {
1470
    {
1489
        // This is our magic formula
1471
        // This is our magic formula
1490
        int push = (  weakness * int(topScore - rootMoves[i].score)
1472
        int push = (  weakness * int(topScore - rootMoves[i].score)
1491
                    + delta * (rng.rand<unsigned>() % weakness)) / 128;
1473
                    + delta * (rng.rand<unsigned>() % weakness)) / 128;
1492
 
1474
 
1493
        if (rootMoves[i].score + push > maxScore)
1475
        if (rootMoves[i].score + push >= maxScore)
1494
        {
1476
        {
1495
            maxScore = rootMoves[i].score + push;
1477
            maxScore = rootMoves[i].score + push;
1496
            best = rootMoves[i].pv[0];
1478
            best = rootMoves[i].pv[0];
1497
        }
1479
        }
1498
    }
1480
    }
1499
 
1481
 
1500
    return best;
1482
    return best;
1501
  }
1483
  }
1502
 
1484
 
-
 
1485
} // namespace
1503
 
1486
 
1504
  // check_time() is used to print debug info and, more importantly, to detect
1487
  // check_time() is used to print debug info and, more importantly, to detect
1505
  // when we are out of available time and thus stop the search.
1488
  // when we are out of available time and thus stop the search.
1506
 
1489
 
1507
  void check_time() {
1490
  void MainThread::check_time() {
-
 
1491
 
-
 
1492
    if (--callsCnt > 0)
-
 
1493
        return;
-
 
1494
 
-
 
1495
    // At low node count increase the checking rate to about 0.1% of nodes
-
 
1496
    // otherwise use a default value.
-
 
1497
    callsCnt = Limits.nodes ? std::min(4096, int(Limits.nodes / 1024)) : 4096;
1508
 
1498
 
1509
    static TimePoint lastInfoTime = now();
1499
    static TimePoint lastInfoTime = now();
1510
 
1500
 
1511
    int elapsed = Time.elapsed();
1501
    int elapsed = Time.elapsed();
1512
    TimePoint tick = Limits.startTime + elapsed;
1502
    TimePoint tick = Limits.startTime + elapsed;
Line 1516... Line 1506...
1516
        lastInfoTime = tick;
1506
        lastInfoTime = tick;
1517
        dbg_print();
1507
        dbg_print();
1518
    }
1508
    }
1519
 
1509
 
1520
    // An engine may not stop pondering until told so by the GUI
1510
    // An engine may not stop pondering until told so by the GUI
1521
    if (Limits.ponder)
1511
    if (Threads.ponder)
1522
        return;
1512
        return;
1523
 
1513
 
1524
    if (   (Limits.use_time_management() && elapsed > Time.maximum() - 10)
1514
    if (   (Limits.use_time_management() && elapsed > Time.maximum() - 10)
1525
        || (Limits.movetime && elapsed >= Limits.movetime)
1515
        || (Limits.movetime && elapsed >= Limits.movetime)
1526
        || (Limits.nodes && Threads.nodes_searched() >= (uint64_t)Limits.nodes))
1516
        || (Limits.nodes && Threads.nodes_searched() >= (uint64_t)Limits.nodes))
1527
            Signals.stop = true;
1517
            Threads.stop = true;
1528
  }
1518
  }
1529
 
-
 
1530
} // namespace
-
 
1531
 
1519
 
1532
 
1520
 
1533
/// UCI::pv() formats PV information according to the UCI protocol. UCI requires
1521
/// UCI::pv() formats PV information according to the UCI protocol. UCI requires
1534
/// that all (if any) unsearched PV lines are sent using a previous search score.
1522
/// that all (if any) unsearched PV lines are sent using a previous search score.
1535
 
1523
 
Line 1543... Line 1531...
1543
  uint64_t nodesSearched = Threads.nodes_searched();
1531
  uint64_t nodesSearched = Threads.nodes_searched();
1544
  uint64_t tbHits = Threads.tb_hits() + (TB::RootInTB ? rootMoves.size() : 0);
1532
  uint64_t tbHits = Threads.tb_hits() + (TB::RootInTB ? rootMoves.size() : 0);
1545
 
1533
 
1546
  for (size_t i = 0; i < multiPV; ++i)
1534
  for (size_t i = 0; i < multiPV; ++i)
1547
  {
1535
  {
1548
      bool updated = (i <= PVIdx);
1536
      bool updated = (i <= PVIdx && rootMoves[i].score != -VALUE_INFINITE);
1549
 
1537
 
1550
      if (depth == ONE_PLY && !updated)
1538
      if (depth == ONE_PLY && !updated)
1551
          continue;
1539
          continue;
1552
 
1540
 
1553
      Depth d = updated ? depth : depth - ONE_PLY;
1541
      Depth d = updated ? depth : depth - ONE_PLY;
Line 1559... Line 1547...
1559
      if (ss.rdbuf()->in_avail()) // Not at first line
1547
      if (ss.rdbuf()->in_avail()) // Not at first line
1560
          ss << "\n";
1548
          ss << "\n";
1561
 
1549
 
1562
      ss << "info"
1550
      ss << "info"
1563
         << " depth "    << d / ONE_PLY
1551
         << " depth "    << d / ONE_PLY
1564
         << " seldepth " << pos.this_thread()->maxPly
1552
         << " seldepth " << rootMoves[i].selDepth
1565
         << " multipv "  << i + 1
1553
         << " multipv "  << i + 1
1566
         << " score "    << UCI::value(v);
1554
         << " score "    << UCI::value(v);
1567
 
1555
 
1568
      if (!tb && i == PVIdx)
1556
      if (!tb && i == PVIdx)
1569
          ss << (v >= beta ? " lowerbound" : v <= alpha ? " upperbound" : "");
1557
          ss << (v >= beta ? " lowerbound" : v <= alpha ? " upperbound" : "");
Line 1599... Line 1587...
1599
    assert(pv.size() == 1);
1587
    assert(pv.size() == 1);
1600
 
1588
 
1601
    if (!pv[0])
1589
    if (!pv[0])
1602
        return false;
1590
        return false;
1603
 
1591
 
1604
    pos.do_move(pv[0], st, pos.gives_check(pv[0]));
1592
    pos.do_move(pv[0], st);
1605
    TTEntry* tte = TT.probe(pos.key(), ttHit);
1593
    TTEntry* tte = TT.probe(pos.key(), ttHit);
1606
 
1594
 
1607
    if (ttHit)
1595
    if (ttHit)
1608
    {
1596
    {
1609
        Move m = tte->move(); // Local copy to be SMP safe
1597
        Move m = tte->move(); // Local copy to be SMP safe
Line 1628... Line 1616...
1628
        Cardinality = MaxCardinality;
1616
        Cardinality = MaxCardinality;
1629
        ProbeDepth = DEPTH_ZERO;
1617
        ProbeDepth = DEPTH_ZERO;
1630
    }
1618
    }
1631
 
1619
 
1632
    if (Cardinality < popcount(pos.pieces()) || pos.can_castle(ANY_CASTLING))
1620
    if (Cardinality < popcount(pos.pieces()) || pos.can_castle(ANY_CASTLING))
-
 
1621
        return;
-
 
1622
 
-
 
1623
    // Don't filter any moves if the user requested analysis on multiple
-
 
1624
    if (Options["MultiPV"] != 1)
1633
        return;
1625
        return;
1634
 
1626
 
1635
    // If the current root position is in the tablebases, then RootMoves
1627
    // If the current root position is in the tablebases, then RootMoves
1636
    // contains only moves that preserve the draw or the win.
1628
    // contains only moves that preserve the draw or the win.
1637
    RootInTB = root_probe(pos, rootMoves, TB::Score);
1629
    RootInTB = root_probe(pos, rootMoves, TB::Score);
Line 1651... Line 1643...
1651
 
1643
 
1652
    if (RootInTB && !UseRule50)
1644
    if (RootInTB && !UseRule50)
1653
        TB::Score =  TB::Score > VALUE_DRAW ?  VALUE_MATE - MAX_PLY - 1
1645
        TB::Score =  TB::Score > VALUE_DRAW ?  VALUE_MATE - MAX_PLY - 1
1654
                   : TB::Score < VALUE_DRAW ? -VALUE_MATE + MAX_PLY + 1
1646
                   : TB::Score < VALUE_DRAW ? -VALUE_MATE + MAX_PLY + 1
1655
                                            :  VALUE_DRAW;
1647
                                            :  VALUE_DRAW;
-
 
1648
 
-
 
1649
    // Since root_probe() and root_probe_wdl() dirty the root move scores,
-
 
1650
    // we reset them to -VALUE_INFINITE
-
 
1651
    for (RootMove& rm : rootMoves)
-
 
1652
        rm.score = -VALUE_INFINITE;
1656
}
1653
}