Move struct RootMove to Search namespace
authorMarco Costalba <mcostalba@gmail.com>
Sat, 14 Jan 2012 12:49:25 +0000 (13:49 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 14 Jan 2012 13:22:34 +0000 (14:22 +0100)
And directly pass RootMoves instead of SearchMoves
to main thread. A class declaration is better suited
in a header and slims a bit the fatty search.cpp

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/benchmark.cpp
src/search.cpp
src/search.h
src/thread.cpp
src/thread.h

index 1491e222ea4b108bb726bdb557b7feae12349baa..ba05ac7fb8af7561bfd425e8dc1f4cdcfe738f16 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <fstream>
 #include <iostream>
-#include <set>
 #include <vector>
 
 #include "misc.h"
@@ -29,7 +28,6 @@
 #include "ucioption.h"
 
 using namespace std;
-using namespace Search;
 
 static const char* Defaults[] = {
   "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
@@ -62,7 +60,7 @@ static const char* Defaults[] = {
 void benchmark(int argc, char* argv[]) {
 
   vector<string> fens;
-  LimitsType limits;
+  Search::LimitsType limits;
   int time;
   int64_t nodes = 0;
 
@@ -116,14 +114,14 @@ void benchmark(int argc, char* argv[]) {
 
       if (valType == "perft")
       {
-          int64_t cnt = perft(pos, limits.maxDepth * ONE_PLY);
+          int64_t cnt = Search::perft(pos, limits.maxDepth * ONE_PLY);
           cerr << "\nPerft " << limits.maxDepth  << " leaf nodes: " << cnt << endl;
           nodes += cnt;
       }
       else
       {
-          Threads.start_thinking(pos, limits, set<Move>(), false);
-          nodes += RootPosition.nodes_searched();
+          Threads.start_thinking(pos, limits);
+          nodes += Search::RootPosition.nodes_searched();
       }
   }
 
index 0839bd0fcc73999bc245b441abe083157d83b3ee..48cb4d6bdd9df3a36bacff4d04b3ce0dfd5dac34 100644 (file)
@@ -24,7 +24,6 @@
 #include <iomanip>
 #include <iostream>
 #include <sstream>
-#include <vector>
 
 #include "book.h"
 #include "evaluate.h"
@@ -42,7 +41,7 @@ namespace Search {
 
   volatile SignalsType Signals;
   LimitsType Limits;
-  std::set<Move> SearchMoves;
+  std::vector<RootMove> RootMoves;
   Position RootPosition;
 }
 
@@ -59,33 +58,6 @@ namespace {
   // Different node types, used as template parameter
   enum NodeType { Root, PV, NonPV, SplitPointRoot, SplitPointPV, SplitPointNonPV };
 
-  // RootMove struct is used for moves at the root of the tree. For each root
-  // move we store a score, a node count, and a PV (really a refutation in the
-  // case of moves which fail low). Score is normally set at -VALUE_INFINITE for
-  // all non-pv moves.
-  struct RootMove {
-
-    RootMove(){}
-    RootMove(Move m) {
-      score = prevScore = -VALUE_INFINITE;
-      pv.push_back(m);
-      pv.push_back(MOVE_NONE);
-    }
-
-    bool operator<(const RootMove& m) const { return score < m.score; }
-    bool operator==(const Move& m) const { return pv[0] == m; }
-
-    void extract_pv_from_tt(Position& pos);
-    void insert_pv_in_tt(Position& pos);
-
-    Value score;
-    Value prevScore;
-    std::vector<Move> pv;
-  };
-
-
-  /// Constants
-
   // Lookup table to check if a Piece is a slider and its access function
   const bool Slidings[18] = { 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1 };
   inline bool piece_is_slider(Piece p) { return Slidings[p]; }
@@ -135,17 +107,14 @@ namespace {
     return (Depth) Reductions[PvNode][std::min(int(d) / ONE_PLY, 63)][std::min(mn, 63)];
   }
 
-  // Easy move margin. An easy move candidate must be at least this much
-  // better than the second best move.
+  // Easy move margin. An easy move candidate must be at least this much better
+  // than the second best move.
   const Value EasyMoveMargin = Value(0x150);
 
   // This is the minimum interval in msec between two check_time() calls
   const int TimerResolution = 5;
 
 
-  /// Namespace variables
-
-  std::vector<RootMove> RootMoves;
   size_t MultiPV, UCIMultiPV, PVIdx;
   TimeManager TimeMgr;
   int BestMoveChanges;
@@ -154,8 +123,6 @@ namespace {
   History H;
 
 
-  /// Local functions
-
   template <NodeType NT>
   Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth);
 
@@ -289,13 +256,6 @@ void Search::think() {
   TimeMgr.init(Limits, pos.startpos_ply_counter());
   TT.new_search();
   H.clear();
-  RootMoves.clear();
-
-  // Populate RootMoves with all the legal moves (default) or, if a SearchMoves
-  // is given, with the subset of legal moves to search.
-  for (MoveList<MV_LEGAL> ml(pos); !ml.end(); ++ml)
-      if (SearchMoves.empty() || SearchMoves.count(ml.move()))
-          RootMoves.push_back(RootMove(ml.move()));
 
   if (RootMoves.empty())
   {
@@ -1798,74 +1758,74 @@ split_point_start: // At split points actual search starts from here
     return best;
   }
 
+} // namespace
 
-  // extract_pv_from_tt() builds a PV by adding moves from the transposition table.
-  // We consider also failing high nodes and not only VALUE_TYPE_EXACT nodes. This
-  // allow to always have a ponder move even when we fail high at root and also a
-  // long PV to print that is important for position analysis.
 
-  void RootMove::extract_pv_from_tt(Position& pos) {
+/// RootMove::extract_pv_from_tt() builds a PV by adding moves from the TT table.
+/// We consider also failing high nodes and not only VALUE_TYPE_EXACT nodes so
+/// to allow to always have a ponder move even when we fail high at root, and
+/// a long PV to print that is important for position analysis.
 
-    StateInfo state[MAX_PLY_PLUS_2], *st = state;
-    TTEntry* tte;
-    int ply = 1;
-    Move m = pv[0];
-
-    assert(m != MOVE_NONE && pos.is_pseudo_legal(m));
-
-    pv.clear();
-    pv.push_back(m);
-    pos.do_move(m, *st++);
-
-    while (   (tte = TT.probe(pos.key())) != NULL
-           && tte->move() != MOVE_NONE
-           && pos.is_pseudo_legal(tte->move())
-           && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces())
-           && ply < MAX_PLY
-           && (!pos.is_draw<false>() || ply < 2))
-    {
-        pv.push_back(tte->move());
-        pos.do_move(tte->move(), *st++);
-        ply++;
-    }
-    pv.push_back(MOVE_NONE);
+void RootMove::extract_pv_from_tt(Position& pos) {
+
+  StateInfo state[MAX_PLY_PLUS_2], *st = state;
+  TTEntry* tte;
+  int ply = 1;
+  Move m = pv[0];
+
+  assert(m != MOVE_NONE && pos.is_pseudo_legal(m));
 
-    do pos.undo_move(pv[--ply]); while (ply);
+  pv.clear();
+  pv.push_back(m);
+  pos.do_move(m, *st++);
+
+  while (   (tte = TT.probe(pos.key())) != NULL
+         && tte->move() != MOVE_NONE
+         && pos.is_pseudo_legal(tte->move())
+         && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces())
+         && ply < MAX_PLY
+         && (!pos.is_draw<false>() || ply < 2))
+  {
+      pv.push_back(tte->move());
+      pos.do_move(tte->move(), *st++);
+      ply++;
   }
+  pv.push_back(MOVE_NONE);
 
+  do pos.undo_move(pv[--ply]); while (ply);
+}
 
-  // insert_pv_in_tt() is called at the end of a search iteration, and inserts
-  // the PV back into the TT. This makes sure the old PV moves are searched
-  // first, even if the old TT entries have been overwritten.
 
-  void RootMove::insert_pv_in_tt(Position& pos) {
+/// RootMove::insert_pv_in_tt() is called at the end of a search iteration, and
+/// inserts the PV back into the TT. This makes sure the old PV moves are searched
+/// first, even if the old TT entries have been overwritten.
 
-    StateInfo state[MAX_PLY_PLUS_2], *st = state;
-    TTEntry* tte;
-    Key k;
-    Value v, m = VALUE_NONE;
-    int ply = 0;
+void RootMove::insert_pv_in_tt(Position& pos) {
 
-    assert(pv[ply] != MOVE_NONE && pos.is_pseudo_legal(pv[ply]));
+  StateInfo state[MAX_PLY_PLUS_2], *st = state;
+  TTEntry* tte;
+  Key k;
+  Value v, m = VALUE_NONE;
+  int ply = 0;
 
-    do {
-        k = pos.key();
-        tte = TT.probe(k);
+  assert(pv[ply] != MOVE_NONE && pos.is_pseudo_legal(pv[ply]));
 
-        // Don't overwrite existing correct entries
-        if (!tte || tte->move() != pv[ply])
-        {
-            v = (pos.in_check() ? VALUE_NONE : evaluate(pos, m));
-            TT.store(k, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, pv[ply], v, m);
-        }
-        pos.do_move(pv[ply], *st++);
+  do {
+      k = pos.key();
+      tte = TT.probe(k);
 
-    } while (pv[++ply] != MOVE_NONE);
+      // Don't overwrite existing correct entries
+      if (!tte || tte->move() != pv[ply])
+      {
+          v = (pos.in_check() ? VALUE_NONE : evaluate(pos, m));
+          TT.store(k, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, pv[ply], v, m);
+      }
+      pos.do_move(pv[ply], *st++);
 
-    do pos.undo_move(pv[--ply]); while (ply);
-  }
+  } while (pv[++ply] != MOVE_NONE);
 
-} // namespace
+  do pos.undo_move(pv[--ply]); while (ply);
+}
 
 
 /// Thread::idle_loop() is where the thread is parked when it has no work to do.
index d805d4629424cf9a991ee1b06d8eb979d0dbdcc3..a4cba6bf700ed7e716b8a8aaf2fdd1c723290b42 100644 (file)
@@ -21,7 +21,7 @@
 #define SEARCH_H_INCLUDED
 
 #include <cstring>
-#include <set>
+#include <vector>
 
 #include "types.h"
 
@@ -48,13 +48,36 @@ struct Stack {
 };
 
 
+/// RootMove struct is used for moves at the root of the tree. For each root
+/// move we store a score, a node count, and a PV (really a refutation in the
+/// case of moves which fail low). Score is normally set at -VALUE_INFINITE for
+/// all non-pv moves.
+struct RootMove {
+
+  RootMove(){} // Needed by sort()
+  RootMove(Move m) : score(-VALUE_INFINITE), prevScore(-VALUE_INFINITE) {
+    pv.push_back(m); pv.push_back(MOVE_NONE);
+  }
+
+  bool operator<(const RootMove& m) const { return score < m.score; }
+  bool operator==(const Move& m) const { return pv[0] == m; }
+
+  void extract_pv_from_tt(Position& pos);
+  void insert_pv_in_tt(Position& pos);
+
+  Value score;
+  Value prevScore;
+  std::vector<Move> pv;
+};
+
+
 /// The LimitsType struct stores information sent by GUI about available time
 /// to search the current move, maximum depth/time, if we are in analysis mode
 /// or if we have to ponder while is our opponent's side to move.
 
 struct LimitsType {
 
-  LimitsType() {  memset(this, 0, sizeof(LimitsType)); }
+  LimitsType() { memset(this, 0, sizeof(LimitsType)); }
   bool use_time_management() const { return !(maxTime | maxDepth | maxNodes | infinite); }
 
   int time, increment, movesToGo, maxTime, maxDepth, maxNodes, infinite, ponder;
@@ -70,13 +93,13 @@ struct SignalsType {
 
 extern volatile SignalsType Signals;
 extern LimitsType Limits;
-extern std::set<Move> SearchMoves;
+extern std::vector<RootMove> RootMoves;
 extern Position RootPosition;
 
 extern void init();
 extern int64_t perft(Position& pos, Depth depth);
 extern void think();
 
-} // namespace
+} // namespace Search
 
 #endif // !defined(SEARCH_H_INCLUDED)
index 74ca48cc7e81ea175f734f31b9fb26828320067b..1db61a20671e77376de2c7501175f2699f02b1c3 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <iostream>
 
+#include "movegen.h"
 #include "search.h"
 #include "thread.h"
 #include "ucioption.h"
@@ -420,7 +421,7 @@ void Thread::main_loop() {
       if (do_terminate)
           return;
 
-      think(); // This is the search entry point
+      Search::think();
   }
 }
 
@@ -431,7 +432,7 @@ void Thread::main_loop() {
 // the search to finish.
 
 void ThreadsManager::start_thinking(const Position& pos, const LimitsType& limits,
-                                    const std::set<Move>& searchMoves, bool asyncMode) {
+                                    const std::set<Move>& searchMoves, bool async) {
   Thread& main = threads[0];
 
   lock_grab(&main.sleepLock);
@@ -443,7 +444,13 @@ void ThreadsManager::start_thinking(const Position& pos, const LimitsType& limit
   // Copy input arguments to initialize the search
   RootPosition.copy(pos, 0);
   Limits = limits;
-  SearchMoves = searchMoves;
+  RootMoves.clear();
+
+  // Populate RootMoves with all the legal moves (default) or, if a searchMoves
+  // set is given, with the subset of legal moves to search.
+  for (MoveList<MV_LEGAL> ml(pos); !ml.end(); ++ml)
+      if (searchMoves.empty() || searchMoves.count(ml.move()))
+          RootMoves.push_back(RootMove(ml.move()));
 
   // Reset signals before to start the new search
   Signals.stopOnPonderhit = Signals.firstRootMove = false;
@@ -452,7 +459,7 @@ void ThreadsManager::start_thinking(const Position& pos, const LimitsType& limit
   main.do_sleep = false;
   cond_signal(&main.sleepCond); // Wake up main thread and start searching
 
-  if (!asyncMode)
+  if (!async)
       while (!main.do_sleep)
           cond_wait(&sleepCond, &main.sleepLock);
 
index 6bccde4c4671425cbd1f1c279c3e1f9c6a5b2f75..cc490639ed4f4c8bb23a400166a840fa10a9ec86 100644 (file)
@@ -121,7 +121,7 @@ public:
   void wait_for_stop_or_ponderhit();
   void stop_thinking();
   void start_thinking(const Position& pos, const Search::LimitsType& limits,
-                      const std::set<Move>& searchMoves, bool asyncMode);
+                      const std::set<Move>& = std::set<Move>(), bool async = false);
 
   template <bool Fake>
   Value split(Position& pos, Search::Stack* ss, Value alpha, Value beta, Value bestValue,