};
- /// Constants
+ /// Adjustments
- // Search depth at iteration 1
- const Depth InitialDepth = OnePly;
-
- // Use internal iterative deepening?
- const bool UseIIDAtPVNodes = true;
- const bool UseIIDAtNonPVNodes = true;
+ // Step 6. Razoring
- // Internal iterative deepening margin. At Non-PV moves, when
- // UseIIDAtNonPVNodes is true, we do an internal iterative deepening
- // search when the static evaluation is at most IIDMargin below beta.
- const Value IIDMargin = Value(0x100);
+ const Depth RazorDepth = 4 * OnePly;
+ inline Value razor_margin(Depth d) { return Value(0x200 + 0x10 * d); }
- // Easy move margin. An easy move candidate must be at least this much
- // better than the second best move.
- const Value EasyMoveMargin = Value(0x200);
+ // Step 8. Null move search with verification search
// Null move margin. A null move search will not be done if the static
// evaluation of the position is more than NullMoveMargin below beta.
const Value NullMoveMargin = Value(0x200);
- // If the TT move is at least SingleReplyMargin better then the
+ // Step 9. Internal iterative deepening
+
+ const Depth IIDDepthAtPVNodes = 5 * OnePly;
+ const Depth IIDDepthAtNonPVNodes = 8 * OnePly;
+
+ // Internal iterative deepening margin. At Non-PV nodes
+ // we do an internal iterative deepening
+ // search when the static evaluation is at most IIDMargin below beta.
+ const Value IIDMargin = Value(0x100);
+
+ // Step 11. Decide the new search depth
+
+ // Extensions. Configurable UCI options.
+ // Array index 0 is used at non-PV nodes, index 1 at PV nodes.
+ Depth CheckExtension[2], SingleEvasionExtension[2], PawnPushTo7thExtension[2];
+ Depth PassedPawnExtension[2], PawnEndgameExtension[2], MateThreatExtension[2];
+
+ const Depth SingularExtensionDepthAtPVNodes = 6 * OnePly;
+ const Depth SingularExtensionDepthAtNonPVNodes = 8 * OnePly;
+
+ // If the TT move is at least SingularExtensionMargin better then the
// remaining ones we will extend it.
- const Value SingleReplyMargin = Value(0x20);
+ const Value SingularExtensionMargin = Value(0x20);
- // Depth limit for razoring
- const Depth RazorDepth = 4 * OnePly;
+
+
+ // Search depth at iteration 1
+ const Depth InitialDepth = OnePly;
+
+ // Easy move margin. An easy move candidate must be at least this much
+ // better than the second best move.
+ const Value EasyMoveMargin = Value(0x200);
/// Lookup tables initialized at startup
const Value LSNValue = value_from_centipawns(200);
bool loseOnTime = false;
- // Extensions. Array index 0 is used at non-PV nodes, index 1 at PV nodes.
- Depth CheckExtension[2], SingleEvasionExtension[2], PawnPushTo7thExtension[2];
- Depth PassedPawnExtension[2], PawnEndgameExtension[2], MateThreatExtension[2];
-
// Iteration counters
int Iteration;
// Step 8. Null move search with verification search (is omitted in PV nodes)
// Step 9. Internal iterative deepening
- if ( UseIIDAtPVNodes
- && depth >= 5*OnePly
+ if ( depth >= IIDDepthAtPVNodes
&& ttMove == MOVE_NONE)
{
search_pv(pos, ss, alpha, beta, depth-2*OnePly, ply, threadID);
// 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
+ if ( depth >= SingularExtensionDepthAtPVNodes
&& tte
&& move == tte->move()
&& ext < OnePly
if (abs(ttValue) < VALUE_KNOWN_WIN)
{
- Value excValue = search(pos, ss, ttValue - SingleReplyMargin, depth / 2, ply, false, threadID, move);
+ Value excValue = search(pos, ss, ttValue - SingularExtensionMargin, depth / 2, ply, false, threadID, move);
- if (excValue < ttValue - SingleReplyMargin)
+ if (excValue < ttValue - SingularExtensionMargin)
ext = OnePly;
}
}
if ( !value_is_mate(beta)
&& !isCheck
&& depth < RazorDepth
- && refinedValue < beta - (0x200 + 16 * depth)
+ && refinedValue < beta - razor_margin(depth)
&& ss[ply - 1].currentMove != MOVE_NULL
&& ttMove == MOVE_NONE
&& !pos.has_pawn_on_7th(pos.side_to_move()))
{
- Value rbeta = beta - (0x200 + 16 * depth);
+ Value rbeta = beta - razor_margin(depth);
Value v = qsearch(pos, ss, rbeta-1, rbeta, Depth(0), ply, threadID);
if (v < rbeta)
- return v; //FIXME: Logically should be: return (v + 0x200 + 16 * depth);
+ return v; //FIXME: Logically should be: return (v + razor_margin(depth));
}
// Step 7. Static null move pruning
}
// Step 9. Internal iterative deepening
- if (UseIIDAtNonPVNodes && ttMove == MOVE_NONE && depth >= 8*OnePly &&
- !isCheck && ss[ply].eval >= beta - IIDMargin)
+ if ( depth >= IIDDepthAtNonPVNodes
+ && ttMove == MOVE_NONE
+ && !isCheck
+ && ss[ply].eval >= beta - IIDMargin)
{
search(pos, ss, beta, depth/2, ply, false, threadID);
ttMove = ss[ply].pv[ply];
// 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 >= 8 * OnePly
+ if ( depth >= SingularExtensionDepthAtNonPVNodes
&& tte
&& move == tte->move()
&& !excludedMove // Do not allow recursive single-reply search
if (abs(ttValue) < VALUE_KNOWN_WIN)
{
- Value excValue = search(pos, ss, ttValue - SingleReplyMargin, depth / 2, ply, false, threadID, move);
+ Value excValue = search(pos, ss, ttValue - SingularExtensionMargin, depth / 2, ply, false, threadID, move);
- if (excValue < ttValue - SingleReplyMargin)
+ if (excValue < ttValue - SingularExtensionMargin)
ext = OnePly;
}
}