]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Use a set to store SearchMoves
[stockfish] / src / search.cpp
index 3ed8ced0326e5ab162f3f70559a1bc80c8a07358..0839bd0fcc73999bc245b441abe083157d83b3ee 100644 (file)
@@ -42,7 +42,7 @@ namespace Search {
 
   volatile SignalsType Signals;
   LimitsType Limits;
-  std::vector<Move> SearchMoves;
+  std::set<Move> SearchMoves;
   Position RootPosition;
 }
 
@@ -200,7 +200,7 @@ namespace {
   FORCE_INLINE bool is_dangerous(const Position& pos, Move m, bool captureOrPromotion) {
 
     // Test for a pawn pushed to 7th or a passed pawn move
-    if (type_of(pos.piece_on(from_sq(m))) == PAWN)
+    if (type_of(pos.piece_moved(m)) == PAWN)
     {
         Color c = pos.side_to_move();
         if (   relative_rank(c, to_sq(m)) == RANK_7
@@ -282,6 +282,7 @@ void Search::think() {
 
   static Book book; // Defined static to initialize the PRNG only once
 
+  Move bm;
   Position& pos = RootPosition;
   Chess960 = pos.is_chess960();
   elapsed_time(true);
@@ -293,18 +294,24 @@ void Search::think() {
   // 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() || count(SearchMoves.begin(), SearchMoves.end(), ml.move()))
+      if (SearchMoves.empty() || SearchMoves.count(ml.move()))
           RootMoves.push_back(RootMove(ml.move()));
 
-  if (Options["OwnBook"])
+  if (RootMoves.empty())
   {
-      Move bookMove = book.probe(pos, Options["Book File"], Options["Best Book Move"]);
+      cout << "info depth 0 score "
+           << score_to_uci(pos.in_check() ? -VALUE_MATE : VALUE_DRAW) << endl;
 
-      if (bookMove && count(RootMoves.begin(), RootMoves.end(), bookMove))
-      {
-          std::swap(RootMoves[0], *find(RootMoves.begin(), RootMoves.end(), bookMove));
-          goto finalize;
-      }
+      RootMoves.push_back(MOVE_NONE);
+      goto finalize;
+  }
+
+  if (   Options["OwnBook"]
+      && (bm = book.probe(pos, Options["Book File"], Options["Best Book Move"])) != MOVE_NONE
+      && count(RootMoves.begin(), RootMoves.end(), bm))
+  {
+      std::swap(RootMoves[0], *find(RootMoves.begin(), RootMoves.end(), bm));
+      goto finalize;
   }
 
   // Read UCI options: GUI could change UCI parameters during the game
@@ -375,9 +382,9 @@ void Search::think() {
 
 finalize:
 
-  // When we reach max depth we arrive here even without a StopRequest, but if
-  // we are pondering or in infinite search, we shouldn't print the best move
-  // before we are told to do so.
+  // When we reach max depth we arrive here even without Signals.stop is raised,
+  // but if we are pondering or in infinite search, we shouldn't print the best
+  // move before we are told to do so.
   if (!Signals.stop && (Limits.ponder || Limits.infinite))
       Threads.wait_for_stop_or_ponderhit();
 
@@ -406,16 +413,6 @@ namespace {
     bestValue = delta = -VALUE_INFINITE;
     ss->currentMove = MOVE_NULL; // Hack to skip update gains
 
-    // Handle the special case of a mated/stalemate position
-    if (RootMoves.empty())
-    {
-        cout << "info depth 0 score "
-             << score_to_uci(pos.in_check() ? -VALUE_MATE : VALUE_DRAW) << endl;
-
-        RootMoves.push_back(MOVE_NONE);
-        return;
-    }
-
     // Iterative deepening loop until requested to stop or target depth reached
     while (!Signals.stop && ++depth <= MAX_PLY && (!Limits.maxDepth || depth <= Limits.maxDepth))
     {
@@ -531,15 +528,15 @@ namespace {
                 stop = true;
 
             // Stop search early if one move seems to be much better than others
-            if (   depth >= 10
+            if (    depth >= 12
                 && !stop
-                && (   bestMoveNeverChanged
+                && (   (bestMoveNeverChanged &&  pos.captured_piece_type())
                     || elapsed_time() > (TimeMgr.available_time() * 40) / 100))
             {
                 Value rBeta = bestValue - EasyMoveMargin;
                 (ss+1)->excludedMove = RootMoves[0].pv[0];
                 (ss+1)->skipNullMove = true;
-                Value v = search<NonPV>(pos, ss+1, rBeta - 1, rBeta, (depth * ONE_PLY) / 2);
+                Value v = search<NonPV>(pos, ss+1, rBeta - 1, rBeta, (depth - 3) * ONE_PLY);
                 (ss+1)->skipNullMove = false;
                 (ss+1)->excludedMove = MOVE_NONE;
 
@@ -701,7 +698,7 @@ namespace {
     if (   (move = (ss-1)->currentMove) != MOVE_NULL
         && (ss-1)->eval != VALUE_NONE
         && ss->eval != VALUE_NONE
-        && pos.captured_piece_type() == NO_PIECE_TYPE
+        && !pos.captured_piece_type()
         && !is_special(move))
     {
         Square to = to_sq(move);
@@ -970,7 +967,7 @@ split_point_start: // At split points actual search starts from here
           // but fixing this made program slightly weaker.
           Depth predictedDepth = newDepth - reduction<PvNode>(depth, moveCount);
           futilityValue =  futilityBase + futility_margin(predictedDepth, moveCount)
-                         + H.gain(pos.piece_on(from_sq(move)), to_sq(move));
+                         + H.gain(pos.piece_moved(move), to_sq(move));
 
           if (futilityValue < beta)
           {
@@ -1154,13 +1151,13 @@ split_point_start: // At split points actual search starts from here
 
             // Increase history value of the cut-off move
             Value bonus = Value(int(depth) * int(depth));
-            H.add(pos.piece_on(from_sq(move)), to_sq(move), bonus);
+            H.add(pos.piece_moved(move), to_sq(move), bonus);
 
             // Decrease history of all the other played non-capture moves
             for (int i = 0; i < playedMoveCount - 1; i++)
             {
                 Move m = movesSearched[i];
-                H.add(pos.piece_on(from_sq(m)), to_sq(m), -bonus);
+                H.add(pos.piece_moved(m), to_sq(m), -bonus);
             }
         }
     }
@@ -1393,7 +1390,7 @@ split_point_start: // At split points actual search starts from here
 
     from = from_sq(move);
     to = to_sq(move);
-    them = flip(pos.side_to_move());
+    them = ~pos.side_to_move();
     ksq = pos.king_square(them);
     kingAtt = pos.attacks_from<KING>(ksq);
     pc = pos.piece_on(from);