// when the static evaluation is at most IIDMargin below beta.
const Value IIDMargin = Value(0x100);
- // Use easy moves?
- const bool UseEasyMove = true;
-
// Easy move margin. An easy move candidate must be at least this much
// better than the second best move.
const Value EasyMoveMargin = Value(0x200);
bool UseQSearchFutilityPruning = true;
bool UseFutilityPruning = true;
- // Margins for futility pruning in the quiescence search, at frontier
- // nodes, and at pre-frontier nodes
- Value FutilityMargin0 = Value(0x80);
- Value FutilityMargin1 = Value(0x100);
- Value FutilityMargin2 = Value(0x300);
+ // Margins for futility pruning in the quiescence search, and at frontier
+ // and near frontier nodes
+ Value FutilityMarginQS = Value(0x80);
+ Value FutilityMargins[6] = { Value(0x120), Value(0x220), Value(0x250),
+ Value(0x280), Value(0x320), Value(0x360) };
// Razoring
Depth RazorDepth = 4*OnePly;
UseQSearchFutilityPruning = get_option_value_bool("Futility Pruning (Quiescence Search)");
UseFutilityPruning = get_option_value_bool("Futility Pruning (Main Search)");
- FutilityMargin0 = value_from_centipawns(get_option_value_int("Futility Margin 0"));
- FutilityMargin1 = value_from_centipawns(get_option_value_int("Futility Margin 1"));
- FutilityMargin2 = value_from_centipawns(get_option_value_int("Futility Margin 2"));
+ FutilityMarginQS = value_from_centipawns(get_option_value_int("Futility Margin (Quiescence Search)"));
+ int fmScale = get_option_value_int("Futility Margin (Main Serach)");
+ for (int i = 0; i < 6; i++)
+ FutilityMargins[i] = (FutilityMargins[i] * fmScale) / 100;
RazorDepth = (get_option_value_int("Maximum Razoring Depth") + 1) * OnePly;
RazorMargin = value_from_centipawns(get_option_value_int("Razoring Margin"));
else
value = alpha + 1; // Just to trigger next condition
- if (value > alpha) // Go with full depth pv search
+ if (value > alpha) // Go with full depth non-pv search
{
ss[ply].reduction = Depth(0);
value = -search(pos, ss, -alpha, newDepth, ply+1, true, threadID);
// If we are at ply 1, and we are searching the first root move at
// ply 0, set the 'Problem' variable if the score has dropped a lot
// (from the computer's point of view) since the previous iteration:
- if (Iteration >= 2 && -value <= ValueByIteration[Iteration-1] - ProblemMargin)
+ if ( ply == 1
+ && Iteration >= 2
+ && -value <= ValueByIteration[Iteration-1] - ProblemMargin)
Problem = true;
}
// Null move search not allowed, try razoring
else if ( !value_is_mate(beta)
&& approximateEval < beta - RazorMargin
- && depth < RazorDepth)
+ && depth < RazorDepth
+ && depth > OnePly
+ && ttMove == MOVE_NONE
+ && !pos.has_pawn_on_7th(pos.side_to_move()))
{
Value v = qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID);
- if (v < beta - RazorMargin / 2)
+ if (v < beta - RazorMargin / 2 - int(depth - OnePly) * RazorMargin / 8)
return v;
}
&& !moveIsCapture
&& !move_promotion(move))
{
- // History pruning. See ok_to_prune() definition.
+ // History pruning. See ok_to_prune() definition
if ( moveCount >= 2 + int(depth)
&& ok_to_prune(pos, move, ss[ply].threatMove, depth))
continue;
- // Value based pruning.
- if (depth < 3 * OnePly && approximateEval < beta)
+ // Value based pruning
+ if (depth < 7 * OnePly && approximateEval < beta)
{
if (futilityValue == VALUE_NONE)
futilityValue = evaluate(pos, ei, threadID)
- + (depth < 2 * OnePly ? FutilityMargin1 : FutilityMargin2);
+ + FutilityMargins[int(depth)/2 - 1]
+ + 32 * (depth & 1);
if (futilityValue < beta)
{
+ Max(pos.midgame_value_of_piece_on(move_to(move)),
pos.endgame_value_of_piece_on(move_to(move)))
+ (move_is_ep(move) ? PawnValueEndgame : Value(0))
- + FutilityMargin0
+ + FutilityMarginQS
+ ei.futilityMargin;
if (futilityValue < alpha)
}
// If we are at ply 1, and we are searching the first root move at
// ply 0, set the 'Problem' variable if the score has dropped a lot
- // (from the computer's point of view) since the previous iteration:
- if (Iteration >= 2 && -value <= ValueByIteration[Iteration-1] - ProblemMargin)
+ // (from the computer's point of view) since the previous iteration.
+ if ( sp->ply == 1
+ && Iteration >= 2
+ && -value <= ValueByIteration[Iteration-1] - ProblemMargin)
Problem = true;
}
lock_release(&(sp->lock));
lock_grab(&(sp->lock));
// If this is the master thread and we have been asked to stop because of
- // a beta cutoff higher up in the tree, stop all slave threads:
+ // a beta cutoff higher up in the tree, stop all slave threads.
if (sp->master == threadID && thread_should_stop(threadID))
for (int i = 0; i < ActiveThreads; i++)
if (sp->slaves[i])