]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Split transposition table lookup in a separate function
[stockfish] / src / search.cpp
index 02595ac53a58e751486ffa13aec6d58824b1e4c0..2779bf8c83dfb27fb8d0c05822ecef8f9017add0 100644 (file)
@@ -51,10 +51,11 @@ namespace {
   // root move, we store a score, a node count, and a PV (really a refutation
   // in the case of moves which fail low).
 
-  class RootMove {
+  struct RootMove {
 
-  public:
     RootMove();
+    bool operator<(const RootMove&); // used to sort
+
     Move move;
     Value score;
     int64_t nodes, cumulativeNodes;
@@ -75,14 +76,13 @@ namespace {
     void set_move_nodes(int moveNum, int64_t nodes);
     void set_move_pv(int moveNum, const Move pv[]);
     Move get_move_pv(int moveNum, int i) const;
-    int64_t get_move_cumulative_nodes(int moveNum);
+    int64_t get_move_cumulative_nodes(int moveNum) const;
     int move_count() const;
     Move scan_for_easy_move() const;
     void sort();
     void sort_multipv(int n);
 
   private:
-    static bool compare_root_moves(const RootMove &rm1, const RootMove &rm2);
     static const int MaxRootMoves = 500;
     RootMove moves[MaxRootMoves];
     int count;
@@ -240,6 +240,7 @@ namespace {
                   bool singleReply, bool mateThreat);
   bool ok_to_do_nullmove(const Position &pos);
   bool ok_to_prune(const Position &pos, Move m, Move threat, Depth d);
+  bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply);
 
   bool fail_high_ply_1();
   int current_search_time();
@@ -458,7 +459,7 @@ void think(const Position &pos, bool infinite, bool ponder, int time,
 
   // We're ready to start thinking.  Call the iterative deepening loop
   // function:
-  id_loop(pos, searchMoves);
+  id_loop(pos, searchMoves);;
 
   if(UseLogFile)
     LogFile.close();
@@ -859,14 +860,11 @@ namespace {
 
     // Transposition table lookup.  At PV nodes, we don't use the TT for
     // pruning, but only for move ordering.
-    Value ttValue;
-    Depth ttDepth;
-    Move ttMove = MOVE_NONE;
-    ValueType ttValueType;
+    const TTEntry* tte = TT.retrieve(pos);
 
-    TT.retrieve(pos, &ttValue, &ttDepth, &ttMove, &ttValueType);
+    Move ttMove = (tte ? tte->move() : MOVE_NONE);
 
-    // Internal iterative deepening.
+    // Go with internal iterative deepening if we don't have a TT move.
     if(UseIIDAtPVNodes && ttMove == MOVE_NONE && depth >= 5*OnePly) {
       search_pv(pos, ss, alpha, beta, depth-2*OnePly, ply, threadID);
       ttMove = ss[ply].pv[ply];
@@ -1045,24 +1043,14 @@ namespace {
       return beta-1;
 
     // Transposition table lookup
-    bool ttFound;
-    Value ttValue;
-    Depth ttDepth;
-    Move ttMove = MOVE_NONE;
-    ValueType ttValueType;
-
-    ttFound = TT.retrieve(pos, &ttValue, &ttDepth, &ttMove, &ttValueType);
-    if(ttFound) {
-      ttValue = value_from_tt(ttValue, ply);
-      if(ttDepth >= depth
-         || ttValue >= Max(value_mate_in(100), beta)
-         || ttValue < Min(value_mated_in(100), beta)) {
-        if((is_lower_bound(ttValueType) && ttValue >= beta) ||
-           (is_upper_bound(ttValueType) && ttValue < beta)) {
-          ss[ply].currentMove = ttMove;
-          return ttValue;
-        }
-      }
+    const TTEntry* tte = TT.retrieve(pos);
+
+    Move ttMove = (tte ? tte->move() : MOVE_NONE);
+
+    if (tte && ok_to_use_TT(tte, depth, beta, ply))
+    {
+        ss[ply].currentMove = ttMove; // can be MOVE_NONE ?
+        return value_from_tt(tte->value(), ply);
     }
 
     Value approximateEval = quick_evaluate(pos);
@@ -1590,6 +1578,20 @@ namespace {
     lock_release(&(sp->lock));
   }
 
+  // ok_to_use_TT() returns true if a transposition table score
+  // can be used at a given point in search.
+
+  bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply) {
+
+    Value v = value_from_tt(tte->value(), ply);
+
+    return   (   tte->depth() >= depth
+              || v >= Max(value_mate_in(100), beta)
+              || v < Min(value_mated_in(100), beta))
+
+          && (   (is_lower_bound(tte->type()) && v >= beta)
+              || (is_upper_bound(tte->type()) && v < beta));
+  }
 
   /// The RootMove class
 
@@ -1599,6 +1601,18 @@ namespace {
     nodes = cumulativeNodes = 0ULL;
   }
 
+  // RootMove::operator<() is the comparison function used when
+  // sorting the moves.  A move m1 is considered to be better
+  // than a move m2 if it has a higher score, or if the moves
+  // have equal score but m1 has the higher node count.
+
+  bool RootMove::operator<(const RootMove& m) {
+
+    if (score != m.score)
+        return (score < m.score);
+
+    return nodes <= m.nodes;
+  }
 
   /// The RootMoveList class
 
@@ -1643,19 +1657,19 @@ namespace {
 
   // Simple accessor methods for the RootMoveList class
 
-  Move RootMoveList::get_move(int moveNum) const {
+  inline Move RootMoveList::get_move(int moveNum) const {
     return moves[moveNum].move;
   }
 
-  Value RootMoveList::get_move_score(int moveNum) const {
+  inline Value RootMoveList::get_move_score(int moveNum) const {
     return moves[moveNum].score;
   }
 
-  void RootMoveList::set_move_score(int moveNum, Value score) {
+  inline void RootMoveList::set_move_score(int moveNum, Value score) {
     moves[moveNum].score = score;
   }
 
-  void RootMoveList::set_move_nodes(int moveNum, int64_t nodes) {
+  inline void RootMoveList::set_move_nodes(int moveNum, int64_t nodes) {
     moves[moveNum].nodes = nodes;
     moves[moveNum].cumulativeNodes += nodes;
   }
@@ -1667,15 +1681,15 @@ namespace {
     moves[moveNum].pv[j] = MOVE_NONE;
   }
 
-  Move RootMoveList::get_move_pv(int moveNum, int i) const {
+  inline Move RootMoveList::get_move_pv(int moveNum, int i) const {
     return moves[moveNum].pv[i];
   }
 
-  int64_t RootMoveList::get_move_cumulative_nodes(int moveNum) {
+  inline int64_t RootMoveList::get_move_cumulative_nodes(int moveNum) const {
     return moves[moveNum].cumulativeNodes;
   }
 
-  int RootMoveList::move_count() const {
+  inline int RootMoveList::move_count() const {
     return count;
   }
 
@@ -1702,45 +1716,27 @@ namespace {
     return MOVE_NONE;
   }
 
-
-  // RootMoveList::compare_root_moves() is the comparison function used by
-  // RootMoveList::sort when sorting the moves.  A move m1 is considered to
-  // be better than a move m2 if it has a higher score, or if the moves have
-  // equal score but m1 has the higher node count.
-
-  bool RootMoveList::compare_root_moves(const RootMove &rm1,
-                                        const RootMove &rm2) {
-    if (rm1.score != rm2.score)
-        return (rm1.score < rm2.score);
-
-    return rm1.nodes <= rm2.nodes;
-  }
-
-
   // RootMoveList::sort() sorts the root move list at the beginning of a new
   // iteration.
 
-  void RootMoveList::sort() {
-    for(int i = 1; i < count; i++) {
-      RootMove rm = moves[i];
-      int j;
-      for(j = i; j > 0 && compare_root_moves(moves[j-1], rm); j--)
-        moves[j] = moves[j-1];
-      moves[j] = rm;
-    }
+  inline void RootMoveList::sort() {
+
+    sort_multipv(count - 1); // all items
   }
 
 
   // RootMoveList::sort_multipv() sorts the first few moves in the root move
-  // list by their scores and depths.  It is used to order the different PVs
+  // list by their scores and depths. It is used to order the different PVs
   // correctly in MultiPV mode.
 
   void RootMoveList::sort_multipv(int n) {
-    for(int i = 1; i <= n; i++) {
+
+    for (int i = 1; i <= n; i++)
+    {
       RootMove rm = moves[i];
       int j;
-      for(j = i; j > 0 && moves[j-1].score < rm.score; j--)
-        moves[j] = moves[j-1];
+      for (j = i; j > 0 && moves[j-1] < rm; j--)
+          moves[j] = moves[j-1];
       moves[j] = rm;
     }
   }