]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Set moveCount base to 1 as in search()
[stockfish] / src / search.cpp
index 0e249705fa59a89e00d1f689d714bf33bbe024f9..9b00b2b7d94ac244e3126909be1ae5fe6340b1b7 100644 (file)
@@ -146,10 +146,10 @@ namespace {
     typedef std::vector<RootMove> Base;
 
     RootMoveList(Position& pos, Move searchMoves[]);
-    void set_non_pv_scores(const Position& pos);
+    void set_non_pv_scores(const Position& pos, Move ttm, SearchStack* ss);
 
     void sort() { insertion_sort<RootMove, Base::iterator>(begin(), end()); }
-    void sort_multipv(int n) { insertion_sort<RootMove, Base::iterator>(begin(), begin() + n + 1); }
+    void sort_multipv(int n) { insertion_sort<RootMove, Base::iterator>(begin(), begin() + n); }
   };
 
 
@@ -364,12 +364,12 @@ void init_search() {
 /// perft() is our utility to verify move generation is bug free. All the legal
 /// moves up to given depth are generated and counted and the sum returned.
 
-int perft(Position& pos, Depth depth)
+int64_t perft(Position& pos, Depth depth)
 {
     MoveStack mlist[MOVES_MAX];
     StateInfo st;
     Move m;
-    int sum = 0;
+    int64_t sum = 0;
 
     // Generate all legal moves
     MoveStack* last = generate_moves(pos, mlist);
@@ -677,13 +677,15 @@ namespace {
   Value root_search(Position& pos, SearchStack* ss, Value alpha,
                     Value beta, Depth depth, RootMoveList& rml) {
     StateInfo st;
+    Move movesSearched[MOVES_MAX];
     CheckInfo ci(pos);
     int64_t nodes;
     Move move;
     Depth ext, newDepth;
     Value value, oldAlpha;
-    bool isCheck, moveIsCheck, captureOrPromotion, dangerous;
-    int researchCountFH, researchCountFL;
+    RootMoveList::iterator rm;
+    bool isCheck, moveIsCheck, captureOrPromotion, dangerous, isPvMove;
+    int moveCount, researchCountFH, researchCountFL;
 
     researchCountFH = researchCountFL = 0;
     oldAlpha = alpha;
@@ -712,14 +714,15 @@ namespace {
     while (1)
     {
         // Sort the moves before to (re)search
-        rml.set_non_pv_scores(pos);
+        rml.set_non_pv_scores(pos, rml[0].pv[0], ss);
         rml.sort();
+        moveCount = 0;
 
         // Step 10. Loop through all moves in the root move list
-        for (int i = 0; i < (int)rml.size() && !StopRequest; i++)
+        for (rm = rml.begin(); rm != rml.end() && !StopRequest; ++rm)
         {
             // This is used by time management
-            FirstRootMove = (i == 0);
+            FirstRootMove = (rm == rml.begin());
 
             // Save the current node count before the move is searched
             nodes = pos.nodes_searched();
@@ -736,11 +739,13 @@ namespace {
 
             // Pick the next root move, and print the move and the move number to
             // the standard output.
-            move = ss->currentMove = rml[i].pv[0];
+            move = ss->currentMove = rm->pv[0];
+            movesSearched[moveCount++] = move;
+            isPvMove = (moveCount <= MultiPV);
 
             if (current_search_time() >= 1000)
                 cout << "info currmove " << move
-                     << " currmovenumber " << i + 1 << endl;
+                     << " currmovenumber " << moveCount << endl;
 
             moveIsCheck = pos.move_is_check(move);
             captureOrPromotion = pos.move_is_capture_or_promotion(move);
@@ -762,9 +767,8 @@ namespace {
                 pos.do_move(move, st, ci, moveIsCheck);
 
                 // Step extra. pv search
-                // We do pv search for first moves (i < MultiPV)
-                // and for fail high research (value > alpha)
-                if (i < MultiPV || value > alpha)
+                // We do pv search for PV moves and when failing high
+                if (isPvMove || value > alpha)
                 {
                     // Aspiration window is disabled in multi-pv case
                     if (MultiPV > 1)
@@ -784,7 +788,7 @@ namespace {
                         && !captureOrPromotion
                         && !move_is_castle(move))
                     {
-                        ss->reduction = reduction<PV>(depth, i - MultiPV + 2);
+                        ss->reduction = reduction<PV>(depth, moveCount - MultiPV + 1);
                         if (ss->reduction)
                         {
                             assert(newDepth-ss->reduction >= ONE_PLY);
@@ -819,11 +823,18 @@ namespace {
                 // We are failing high and going to do a research. It's important to update
                 // the score before research in case we run out of time while researching.
                 ss->bestMove = move;
-                rml[i].pv_score = value;
-                rml[i].extract_pv_from_tt(pos);
+                rm->pv_score = value;
+                rm->extract_pv_from_tt(pos);
+
+                // Update killers and history only for non capture moves that fails high
+                if (!pos.move_is_capture_or_promotion(move))
+                {
+                    update_history(pos, move, depth, movesSearched, moveCount);
+                    update_killers(move, ss);
+                }
 
                 // Inform GUI that PV has changed
-                cout << rml[i].pv_info_to_uci(pos, alpha, beta) << endl;
+                cout << rm->pv_info_to_uci(pos, alpha, beta) << endl;
 
                 // Prepare for a research after a fail high, each time with a wider window
                 beta = Min(beta + AspirationDelta * (1 << researchCountFH), VALUE_INFINITE);
@@ -840,32 +851,32 @@ namespace {
                 break;
 
             // Remember searched nodes counts for this move
-            rml[i].nodes += pos.nodes_searched() - nodes;
+            rm->nodes += pos.nodes_searched() - nodes;
 
             assert(value >= -VALUE_INFINITE && value <= VALUE_INFINITE);
             assert(value < beta);
 
             // Step 17. Check for new best move
-            if (value <= alpha && i >= MultiPV)
-                rml[i].pv_score = -VALUE_INFINITE;
+            if (!isPvMove && value <= alpha)
+                rm->pv_score = -VALUE_INFINITE;
             else
             {
                 // PV move or new best move!
 
                 // Update PV
                 ss->bestMove = move;
-                rml[i].pv_score = value;
-                rml[i].extract_pv_from_tt(pos);
+                rm->pv_score = value;
+                rm->extract_pv_from_tt(pos);
 
                 // We record how often the best move has been changed in each
                 // iteration. This information is used for time managment: When
                 // the best move changes frequently, we allocate some more time.
-                if (MultiPV == 1 && i > 0)
+                if (!isPvMove && MultiPV == 1)
                     BestMoveChangesByIteration[Iteration]++;
 
                 // Inform GUI that PV has changed, in case of multi-pv UCI protocol
                 // requires we send all the PV lines properly sorted.
-                rml.sort_multipv(i);
+                rml.sort_multipv(moveCount);
 
                 for (int j = 0; j < Min(MultiPV, (int)rml.size()); j++)
                     cout << rml[j].pv_info_to_uci(pos, alpha, beta, j) << endl;
@@ -878,7 +889,7 @@ namespace {
                         alpha = value;
                 }
                 else // Set alpha equal to minimum score among the PV lines
-                    alpha = rml[Min(i, MultiPV - 1)].pv_score;
+                    alpha = rml[Min(moveCount, MultiPV) - 1].pv_score; // FIXME why moveCount?
 
             } // PV move or new best move
 
@@ -2685,11 +2696,11 @@ split_point_start: // At split points actual search starts from here
   // This is the second order score that is used to compare the moves when
   // the first order pv scores of both moves are equal.
 
-  void RootMoveList::set_non_pv_scores(const Position& pos)
+  void RootMoveList::set_non_pv_scores(const Position& pos, Move ttm, SearchStack* ss)
   {
       Move move;
       Value score = VALUE_ZERO;
-      MovePicker mp(pos, MOVE_NONE, ONE_PLY, H);
+      MovePicker mp(pos, ttm, ONE_PLY, H, ss);
 
       while ((move = mp.get_next_move()) != MOVE_NONE)
           for (Base::iterator it = begin(); it != end(); ++it)