]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Use operator() instead of apply() in endgames
[stockfish] / src / search.cpp
index 6615a1efacbc2bc1454ad0732568ab3c2716a8c1..77acd89e39b12310d5333708de19c5c85c7a883f 100644 (file)
@@ -30,7 +30,6 @@
 #include "evaluate.h"
 #include "history.h"
 #include "misc.h"
-#include "move.h"
 #include "movegen.h"
 #include "movepick.h"
 #include "search.h"
 #include "tt.h"
 #include "ucioption.h"
 
-using std::cout;
-using std::endl;
-using std::string;
-using Search::Signals;
-using Search::Limits;
-
 namespace Search {
 
   volatile SignalsType Signals;
   LimitsType Limits;
   std::vector<Move> RootMoves;
-  Position* RootPosition;
+  Position RootPosition;
 }
 
+using std::cout;
+using std::endl;
+using std::string;
+using namespace Search;
+
 namespace {
 
   // Set to true to force running with one thread. Used for debugging
@@ -187,10 +185,10 @@ namespace {
   Move id_loop(Position& pos, Move rootMoves[], Move* ponderMove);
 
   template <NodeType NT>
-  Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth);
+  Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth);
 
   template <NodeType NT>
-  Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth);
+  Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth);
 
   bool check_is_dangerous(Position &pos, Move move, Value futilityBase, Value beta, Value *bValue);
   bool connected_moves(const Position& pos, Move m1, Move m2);
@@ -202,7 +200,7 @@ namespace {
   void update_history(const Position& pos, Move move, Depth depth, Move movesSearched[], int moveCount);
   void do_skill_level(Move* best, Move* ponder);
 
-  int elapsed_search_time(int set = 0);
+  int elapsed_time(bool reset = false);
   string score_to_uci(Value v, Value alpha = -VALUE_INFINITE, Value beta = VALUE_INFINITE);
   string speed_to_uci(int64_t nodes);
   string pv_to_uci(const Move pv[], int pvNum, bool chess960);
@@ -214,14 +212,14 @@ namespace {
   // we simply create and use a standard MovePicker object.
   template<bool SpNode> struct MovePickerExt : public MovePicker {
 
-    MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, SearchStack* ss, Value b)
+    MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, Stack* ss, Value b)
                   : MovePicker(p, ttm, d, h, ss, b) {}
   };
 
   // In case of a SpNode we use split point's shared MovePicker object as moves source
   template<> struct MovePickerExt<true> : public MovePicker {
 
-    MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, SearchStack* ss, Value b)
+    MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, Stack* ss, Value b)
                   : MovePicker(p, ttm, d, h, ss, b), mp(ss->sp->mp) {}
 
     Move get_next_move() { return mp->get_next_move(); }
@@ -353,19 +351,18 @@ int64_t Search::perft(Position& pos, Depth depth) {
 }
 
 
-/// think() is the external interface to Stockfish's search, and is called when
-/// the program receives the UCI 'go' command. It initializes various global
-/// variables, and calls id_loop(). It returns false when a "quit" command is
-/// received during the search.
+/// think() is the external interface to Stockfish's search, and is called by the
+/// main thread when the program receives the UCI 'go' command. It searches from
+/// RootPosition and at the end prints the "bestmove" to output.
 
 void Search::think() {
 
   static Book book; // Defined static to initialize the PRNG only once
 
-  Position& pos = *RootPosition;
+  Position& pos = RootPosition;
 
-  // Save "search start" time and reset elapsed time to zero
-  elapsed_search_time(get_system_time());
+  // Reset elapsed search time
+  elapsed_time(true);
 
   // Set output stream mode: normal or chess960. Castling notation is different
   cout << set960(pos.is_chess960());
@@ -450,7 +447,7 @@ void Search::think() {
   // Write current search final statistics to log file
   if (Options["Use Search Log"].value<bool>())
   {
-      int e = elapsed_search_time();
+      int e = elapsed_time();
 
       Log log(Options["Search Log Filename"].value<string>());
       log << "Nodes: "          << pos.nodes_searched()
@@ -489,7 +486,7 @@ namespace {
 
   Move id_loop(Position& pos, Move rootMoves[], Move* ponderMove) {
 
-    SearchStack ss[PLY_MAX_PLUS_2];
+    Stack ss[PLY_MAX_PLUS_2];
     Value bestValues[PLY_MAX_PLUS_2];
     int bestMoveChanges[PLY_MAX_PLUS_2];
     int depth, aspirationDelta;
@@ -498,7 +495,7 @@ namespace {
     bool bestMoveNeverChanged = true;
 
     // Initialize stuff before a new search
-    memset(ss, 0, 4 * sizeof(SearchStack));
+    memset(ss, 0, 4 * sizeof(Stack));
     TT.new_search();
     H.clear();
     *ponderMove = bestMove = skillBest = skillPonder = MOVE_NONE;
@@ -585,7 +582,7 @@ namespace {
                 // if we have a fail high/low and we are deep in the search. UCI
                 // protocol requires to send all the PV lines also if are still
                 // to be searched and so refer to the previous search's score.
-                if ((bestValue > alpha && bestValue < beta) || elapsed_search_time() > 2000)
+                if ((bestValue > alpha && bestValue < beta) || elapsed_time() > 2000)
                     for (int i = 0; i < std::min(UCIMultiPV, (int)Rml.size()); i++)
                     {
                         bool updated = (i <= MultiPVIdx);
@@ -638,7 +635,7 @@ namespace {
         if (Options["Use Search Log"].value<bool>())
         {
             Log log(Options["Search Log Filename"].value<string>());
-            log << pretty_pv(pos, depth, bestValue, elapsed_search_time(), &Rml[0].pv[0]) << endl;
+            log << pretty_pv(pos, depth, bestValue, elapsed_time(), &Rml[0].pv[0]) << endl;
         }
 
         // Filter out startup noise when monitoring best move stability
@@ -656,14 +653,14 @@ namespace {
 
             // Stop search if most of available time is already consumed. We probably don't
             // have enough time to search the first move at the next iteration anyway.
-            if (elapsed_search_time() > (TimeMgr.available_time() * 62) / 100)
+            if (elapsed_time() > (TimeMgr.available_time() * 62) / 100)
                 stop = true;
 
             // Stop search early if one move seems to be much better than others
             if (   depth >= 10
                 && !stop
                 && (   bestMoveNeverChanged
-                    || elapsed_search_time() > (TimeMgr.available_time() * 40) / 100))
+                    || elapsed_time() > (TimeMgr.available_time() * 40) / 100))
             {
                 Value rBeta = bestValue - EasyMoveMargin;
                 (ss+1)->excludedMove = bestMove;
@@ -680,7 +677,7 @@ namespace {
             {
                 // If we are allowed to ponder do not stop the search now but
                 // keep pondering until GUI sends "ponderhit" or "stop".
-                if (Limits.ponder) // FIXME racing
+                if (Limits.ponder)
                     Signals.stopOnPonderhit = true;
                 else
                     Signals.stop = true;
@@ -710,7 +707,7 @@ namespace {
   // here: This is taken care of after we return from the split point.
 
   template <NodeType NT>
-  Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth) {
+  Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) {
 
     const bool PvNode   = (NT == PV || NT == Root || NT == SplitPointPV || NT == SplitPointRoot);
     const bool SpNode   = (NT == SplitPointPV || NT == SplitPointNonPV || NT == SplitPointRoot);
@@ -1028,7 +1025,7 @@ split_point_start: // At split points actual search starts from here
           nodes = pos.nodes_searched();
 
           // For long searches send current move info to GUI
-          if (pos.thread() == 0 && elapsed_search_time() > 2000)
+          if (pos.thread() == 0 && elapsed_time() > 2000)
               cout << "info" << depth_to_uci(depth)
                    << " currmove " << move
                    << " currmovenumber " << moveCount + MultiPVIdx << endl;
@@ -1299,7 +1296,7 @@ split_point_start: // At split points actual search starts from here
   // less than ONE_PLY).
 
   template <NodeType NT>
-  Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth) {
+  Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) {
 
     const bool PvNode = (NT == PV);
 
@@ -1734,12 +1731,12 @@ split_point_start: // At split points actual search starts from here
   // current_search_time() returns the number of milliseconds which have passed
   // since the beginning of the current search.
 
-  int elapsed_search_time(int set) {
+  int elapsed_time(bool reset) {
 
     static int searchStartTime;
 
-    if (set)
-        searchStartTime = set;
+    if (reset)
+        searchStartTime = get_system_time();
 
     return get_system_time() - searchStartTime;
   }
@@ -1773,7 +1770,7 @@ split_point_start: // At split points actual search starts from here
   string speed_to_uci(int64_t nodes) {
 
     std::stringstream s;
-    int t = elapsed_search_time();
+    int t = elapsed_time();
 
     s << " nodes " << nodes
       << " nps " << (t > 0 ? int(nodes * 1000 / t) : 0)
@@ -2103,11 +2100,11 @@ void Thread::idle_loop(SplitPoint* sp) {
           assert(!do_terminate);
 
           // Copy split point position and search stack and call search()
-          SearchStack ss[PLY_MAX_PLUS_2];
+          Stack ss[PLY_MAX_PLUS_2];
           SplitPoint* tsp = splitPoint;
           Position pos(*tsp->pos, threadID);
 
-          memcpy(ss, tsp->ss - 1, 4 * sizeof(SearchStack));
+          memcpy(ss, tsp->ss - 1, 4 * sizeof(Stack));
           (ss+1)->sp = tsp;
 
           if (tsp->nodeType == Root)
@@ -2150,7 +2147,7 @@ void Thread::idle_loop(SplitPoint* sp) {
 void do_timer_event() {
 
   static int lastInfoTime;
-  int e = elapsed_search_time();
+  int e = elapsed_time();
 
   // Print debug information every one second
   if (!lastInfoTime || get_system_time() - lastInfoTime >= 1000)