- // Update gain statistics of the previous move that lead
- // us in this position.
- EvalInfo ei;
- ss[ply].eval = evaluate(pos, ei, threadID);
- update_gains(pos, ss[ply - 1].currentMove, ss[ply - 1].eval, ss[ply].eval);
- }
-
- // Initialize a MovePicker object for the current position, and prepare
- // to search all moves
- mateThreat = pos.has_mate_threat(opposite_color(pos.side_to_move()));
- CheckInfo ci(pos);
- MovePicker mp = MovePicker(pos, ttMove, depth, H, &ss[ply]);
-
- // Loop through all legal moves until no moves remain or a beta cutoff
- // occurs.
- while ( alpha < beta
- && (move = mp.get_next_move()) != MOVE_NONE
- && !TM.thread_should_stop(threadID))
- {
- assert(move_is_ok(move));
-
- singleEvasion = (isCheck && mp.number_of_evasions() == 1);
- moveIsCheck = pos.move_is_check(move, ci);
- captureOrPromotion = pos.move_is_capture_or_promotion(move);
-
- // Decide the new search depth
- ext = extension(pos, move, true, captureOrPromotion, moveIsCheck, singleEvasion, mateThreat, &dangerous);
-
- // Singular extension search. We extend the TT move if its value is much better than
- // its siblings. To verify this we do a reduced search on all the other moves but the
- // ttMove, if result is lower then ttValue minus a margin then we extend ttMove.
- if ( depth >= 6 * OnePly
- && tte
- && move == tte->move()
- && ext < OnePly
- && is_lower_bound(tte->type())
- && tte->depth() >= depth - 3 * OnePly)
- {
- Value ttValue = value_from_tt(tte->value(), ply);
-
- if (abs(ttValue) < VALUE_KNOWN_WIN)
- {
- Value excValue = search(pos, ss, ttValue - SingleReplyMargin, depth / 2, ply, false, threadID, move);
-
- if (excValue < ttValue - SingleReplyMargin)
- ext = OnePly;
- }
- }
-
- newDepth = depth - OnePly + ext;
-
- // Update current move
- movesSearched[moveCount++] = ss[ply].currentMove = move;
-
- // Make and search the move
- pos.do_move(move, st, ci, moveIsCheck);
-
- if (moveCount == 1) // The first move in list is the PV
- value = -search_pv(pos, ss, -beta, -alpha, newDepth, ply+1, threadID);
- else
- {
- // Try to reduce non-pv search depth by one ply if move seems not problematic,
- // if the move fails high will be re-searched at full depth.
- bool doFullDepthSearch = true;
-
- if ( depth >= 3*OnePly
- && !dangerous
- && !captureOrPromotion
- && !move_is_castle(move)
- && !move_is_killer(move, ss[ply]))