]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
MovePicker: introduce per square MVV/LVA ordering
[stockfish] / src / search.cpp
index cdc34ba6d3a74b03fe413446d140972629c99dfc..e28b866e9cb26b2bc26c5bc5460a6e091aa2ef81 100644 (file)
@@ -144,7 +144,7 @@ namespace {
   bool UseFutilityPruning = true;
 
   // Margins for futility pruning in the quiescence search, at frontier
-  // nodes, and at pre-frontier nodes:
+  // nodes, and at pre-frontier nodes
   Value FutilityMargin0 = Value(0x80);
   Value FutilityMargin1 = Value(0x100);
   Value FutilityMargin2 = Value(0x300);
@@ -167,21 +167,22 @@ namespace {
   Depth PawnEndgameExtension[2] = {OnePly, OnePly};
   Depth MateThreatExtension[2] = {Depth(0), Depth(0)};
 
-  // Search depth at iteration 1:
+  // Search depth at iteration 1
   const Depth InitialDepth = OnePly /*+ OnePly/2*/;
 
   // Node counters
   int NodesSincePoll;
   int NodesBetweenPolls = 30000;
 
-  // Iteration counter:
+  // Iteration counter
   int Iteration;
+  bool LastIterations;
 
   // Scores and number of times the best move changed for each iteration:
   Value ValueByIteration[PLY_MAX_PLUS_2];
   int BestMoveChangesByIteration[PLY_MAX_PLUS_2];
 
-  // MultiPV mode:
+  // MultiPV mode
   int MultiPV = 1;
 
   // Time managment variables
@@ -617,6 +618,7 @@ namespace {
     ValueByIteration[0] = Value(0);
     ValueByIteration[1] = rml.get_move_score(0);
     Iteration = 1;
+    LastIterations = false;
 
     EasyMove = rml.scan_for_easy_move();
 
@@ -675,6 +677,9 @@ namespace {
             if (ExtraSearchTime > 0 && TimeAdvantage > 2 * MaxSearchTime)
                 ExtraSearchTime += MaxSearchTime / 2;
 
+            // Try to guess if the current iteration is the last one or the last two
+            LastIterations = (current_search_time() > ((MaxSearchTime + ExtraSearchTime)*58) / 128);
+
             // Stop search if most of MaxSearchTime is consumed at the end of the
             // iteration.  We probably don't have enough time to search the first
             // move at the next iteration anyway.
@@ -1143,7 +1148,8 @@ namespace {
 
         UndoInfo u;
         pos.do_null_move(u);
-        Value nullValue = -search(pos, ss, -(beta-1), depth-4*OnePly, ply+1, false, threadID);
+        int R = (depth > 7 ? 4 : 3);
+        Value nullValue = -search(pos, ss, -(beta-1), depth-R*OnePly, ply+1, false, threadID);
         pos.undo_null_move(u);
 
         if (nullValue >= beta)
@@ -1463,6 +1469,18 @@ namespace {
     // Update transposition table
     TT.store(pos, value_to_tt(bestValue, ply), depth, MOVE_NONE, VALUE_TYPE_EXACT);
 
+    // Update killers only for good check moves
+    Move m = ss[ply].currentMove;
+    if (alpha >= beta && ok_to_history(pos, m)) // Only non capture moves are considered
+    {
+        // Wrong to update history when depth is <= 0
+
+        if (m != ss[ply].killer1)
+        {
+            ss[ply].killer2 = ss[ply].killer1;
+            ss[ply].killer1 = m;
+        }
+    }
     return bestValue;
   }
 
@@ -2137,13 +2155,11 @@ namespace {
 
 
   // ok_to_history() returns true if a move m can be stored
-  // in history. Should be a non capturing move.
+  // in history. Should be a non capturing move nor a promotion.
 
   bool ok_to_history(const Position& pos, Move m) {
 
-    return    pos.square_is_empty(move_to(m))
-          && !move_promotion(m)
-          && !move_is_ep(m);
+    return !pos.move_is_capture(m) && !move_promotion(m);
   }
 
 
@@ -2156,8 +2172,11 @@ namespace {
     H.success(pos.piece_on(move_from(m)), m, depth);
 
     for (int i = 0; i < moveCount - 1; i++)
-        if (ok_to_history(pos, movesSearched[i]) && m != movesSearched[i])
+    {
+        assert(m != movesSearched[i]);
+        if (ok_to_history(pos, movesSearched[i]))
             H.failure(pos.piece_on(move_from(movesSearched[i])), movesSearched[i]);
+    }
   }
 
   // fail_high_ply_1() checks if some thread is currently resolving a fail