// capturing a single attacking piece can therefore result in a score
// change far bigger than the value of the captured piece.
Score v = apply_weight(make_score(SafetyTable[attackUnits], 0), WeightKingSafety[Us]);
-
ei.value -= Sign[Us] * v;
-
- if (Us == pos.side_to_move())
- ei.futilityMargin += mg_value(v);
+ ei.futilityMargin[Us] += mg_value(v);
}
}
struct EvalInfo {
- EvalInfo() : futilityMargin(Value(0)) {}
+ EvalInfo() { futilityMargin[0] = futilityMargin[1] = Value(0); }
// Middle game and endgame evaluations
Score value;
Score mobility;
// Extra futility margin. This is added to the standard futility margin
- // in the quiescence search.
- Value futilityMargin;
+ // in the quiescence search. One for each color.
+ Value futilityMargin[2];
};
if (bestValue >= beta)
{
// Store the score to avoid a future costly evaluation() call
- if (!isCheck && !tte && ei.futilityMargin == 0)
+ if (!isCheck && !tte && ei.futilityMargin[pos.side_to_move()] == 0)
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EV_LO, Depth(-127*OnePly), MOVE_NONE);
return bestValue;
MovePicker mp = MovePicker(pos, ttMove, deepChecks ? Depth(0) : depth, H);
CheckInfo ci(pos);
enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame;
- futilityBase = staticValue + FutilityMarginQS + ei.futilityMargin;
+ futilityBase = staticValue + FutilityMarginQS + ei.futilityMargin[pos.side_to_move()];
// Loop through the moves until no moves remain or a beta cutoff
// occurs.
{
// If bestValue isn't changed it means it is still the static evaluation
// of the node, so keep this info to avoid a future evaluation() call.
- ValueType type = (bestValue == staticValue && !ei.futilityMargin ? VALUE_TYPE_EV_UP : VALUE_TYPE_UPPER);
+ ValueType type = (bestValue == staticValue && !ei.futilityMargin[pos.side_to_move()] ? VALUE_TYPE_EV_UP : VALUE_TYPE_UPPER);
TT.store(pos.get_key(), value_to_tt(bestValue, ply), type, d, MOVE_NONE);
}
else if (bestValue >= beta)