// Bonuses for enemy's safe checks
const int QueenContactCheckBonus = 6;
+ const int RookContactCheckBonus = 4;
const int QueenCheckBonus = 3;
const int RookCheckBonus = 2;
const int BishopCheckBonus = 1;
// Function prototypes
template<bool HasPopCnt>
- Value do_evaluate(const Position& pos, Value margins[]);
+ Value do_evaluate(const Position& pos, Value& margin);
template<Color Us, bool HasPopCnt>
void init_eval_info(const Position& pos, EvalInfo& ei);
Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score& mobility);
template<Color Us, bool HasPopCnt>
- Score evaluate_king(const Position& pos, EvalInfo& ei, Value margins[]);
+ Score evaluate_king(const Position& pos, EvalInfo& ei, Value& margin);
template<Color Us>
Score evaluate_threats(const Position& pos, EvalInfo& ei);
/// evaluate() is the main evaluation function. It always computes two
/// values, an endgame score and a middle game score, and interpolates
/// between them based on the remaining material.
-Value evaluate(const Position& pos, Value margins[]) {
+Value evaluate(const Position& pos, Value& margin) {
- return CpuHasPOPCNT ? do_evaluate<true>(pos, margins)
- : do_evaluate<false>(pos, margins);
+ return CpuHasPOPCNT ? do_evaluate<true>(pos, margin)
+ : do_evaluate<false>(pos, margin);
}
namespace {
template<bool HasPopCnt>
-Value do_evaluate(const Position& pos, Value margins[]) {
+Value do_evaluate(const Position& pos, Value& margin) {
EvalInfo ei;
ScaleFactor factor[2];
// in the position object (material + piece square tables).
Score bonus = pos.value();
- // margins[color] is the uncertainty estimation of position's evaluation
+ // margin is the uncertainty estimation of position's evaluation
// and typically is used by the search for pruning decisions.
- margins[WHITE] = margins[BLACK] = VALUE_ZERO;
+ margin = VALUE_ZERO;
// Probe the material hash table
MaterialInfo* mi = MaterialTable[pos.thread()]->get_material_info(pos);
// Evaluate kings after all other pieces because we need complete attack
// information when computing the king safety evaluation.
- bonus += evaluate_king<WHITE, HasPopCnt>(pos, ei, margins)
- - evaluate_king<BLACK, HasPopCnt>(pos, ei, margins);
+ bonus += evaluate_king<WHITE, HasPopCnt>(pos, ei, margin)
+ - evaluate_king<BLACK, HasPopCnt>(pos, ei, margin);
// Evaluate tactical threats, we need full attack information including king
bonus += evaluate_threats<WHITE>(pos, ei)
// evaluate_king<>() assigns bonuses and penalties to a king of a given color
template<Color Us, bool HasPopCnt>
- Score evaluate_king(const Position& pos, EvalInfo& ei, Value margins[]) {
+ Score evaluate_king(const Position& pos, EvalInfo& ei, Value& margin) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
* (Them == pos.side_to_move() ? 2 : 1);
}
+ // Analyse enemy's safe rook contact checks. First find undefended
+ // squares around the king attacked by enemy rooks...
+ b = undefended & ei.attackedBy[Them][ROOK] & ~pos.pieces_of_color(Them);
+
+ // Consider only squares where the enemy rook gives check
+ b &= RookPseudoAttacks[ksq];
+
+ if (b)
+ {
+ // ...then remove squares not supported by another enemy piece
+ b &= ( ei.attackedBy[Them][PAWN] | ei.attackedBy[Them][KNIGHT]
+ | ei.attackedBy[Them][BISHOP] | ei.attackedBy[Them][QUEEN]);
+ if (b)
+ attackUnits += RookContactCheckBonus
+ * count_1s_max_15<HasPopCnt>(b)
+ * (Them == pos.side_to_move() ? 2 : 1);
+ }
+
// Analyse enemy's safe distance checks for sliders and knights
safe = ~(pos.pieces_of_color(Them) | ei.attackedBy[Us][0]);
// be very big, and so capturing a single attacking piece can therefore
// result in a score change far bigger than the value of the captured piece.
bonus -= KingDangerTable[Us][attackUnits];
- margins[Us] += mg_value(KingDangerTable[Us][attackUnits]);
+ if (pos.side_to_move() == Us)
+ margin += mg_value(KingDangerTable[Us][attackUnits]);
}
return bonus;
}