const Score UndefendedMinor = make_score(25, 10);
const Score TrappedRook = make_score(90, 0);
const Score Unstoppable = make_score( 0, 20);
+ const Score LowMobPenalty = make_score(40, 20);
// Penalty for a bishop on a1/h1 (a8/h8 for black) which is trapped by
// a friendly pawn on b2/g2 (b7/g7 for black). This can obviously only
(FileCBB | FileDBB | FileEBB | FileFBB) & (Rank7BB | Rank6BB | Rank5BB)
};
+ const Bitboard EdgeBB = Rank1BB | Rank8BB | FileABB | FileHBB;
+
// King danger constants and variables. The king danger scores are taken
// from KingDanger[]. Various little "meta-bonuses" measuring the strength
// of the enemy attack are added up into an integer, which is used as an
template<Color Us>
void init_eval_info(const Position& pos, EvalInfo& ei);
- template<bool Trace>
- Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility);
+ template<PieceType Pt, Color Us, bool Trace>
+ Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility, Bitboard* mobilityArea);
template<Color Us, bool Trace>
Score evaluate_king(const Position& pos, const EvalInfo& ei);
init_eval_info<WHITE>(pos, ei);
init_eval_info<BLACK>(pos, ei);
+ // Do not include in mobility squares protected by enemy pawns or occupied by our pieces
+ Bitboard mobilityArea[] = { ~(ei.attackedBy[BLACK][PAWN] | pos.pieces(WHITE, PAWN, KING)),
+ ~(ei.attackedBy[WHITE][PAWN] | pos.pieces(BLACK, PAWN, KING)) };
+
// Evaluate pieces and mobility
- score += evaluate_pieces<Trace>(pos, ei, mobility);
+ score += evaluate_pieces<KNIGHT, WHITE, Trace>(pos, ei, mobility, mobilityArea);
+
+ // Sum up all attacked squares (updated in evaluate_pieces)
+ ei.attackedBy[WHITE][ALL_PIECES] = ei.attackedBy[WHITE][PAWN] | ei.attackedBy[WHITE][KNIGHT]
+ | ei.attackedBy[WHITE][BISHOP] | ei.attackedBy[WHITE][ROOK]
+ | ei.attackedBy[WHITE][QUEEN] | ei.attackedBy[WHITE][KING];
+
+ ei.attackedBy[BLACK][ALL_PIECES] = ei.attackedBy[BLACK][PAWN] | ei.attackedBy[BLACK][KNIGHT]
+ | ei.attackedBy[BLACK][BISHOP] | ei.attackedBy[BLACK][ROOK]
+ | ei.attackedBy[BLACK][QUEEN] | ei.attackedBy[BLACK][KING];
score += apply_weight(mobility[WHITE] - mobility[BLACK], Weights[Mobility]);
Tracing::add_term(Tracing::PST, pos.psq_score());
Tracing::add_term(Tracing::IMBALANCE, ei.mi->material_value());
Tracing::add_term(PAWN, ei.pi->pawns_value());
+ Tracing::add_term(Tracing::MOBILITY, apply_weight(mobility[WHITE], Weights[Mobility])
+ , apply_weight(mobility[BLACK], Weights[Mobility]));
Score w = ei.mi->space_weight() * evaluate_space<WHITE>(pos, ei);
Score b = ei.mi->space_weight() * evaluate_space<BLACK>(pos, ei);
Tracing::add_term(Tracing::SPACE, apply_weight(w, Weights[Space]), apply_weight(b, Weights[Space]));
// evaluate_pieces() assigns bonuses and penalties to the pieces of a given color
template<PieceType Pt, Color Us, bool Trace>
- Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility, Bitboard mobilityArea) {
+ Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility, Bitboard* mobilityArea) {
Bitboard b;
Square s;
| ei.attackedBy[Them][BISHOP]
| ei.attackedBy[Them][ROOK]);
- int mob = Pt != QUEEN ? popcount<Max15>(b & mobilityArea)
- : popcount<Full >(b & mobilityArea);
+ int mob = Pt != QUEEN ? popcount<Max15>(b & mobilityArea[Us])
+ : popcount<Full >(b & mobilityArea[Us]);
mobility[Us] += MobilityBonus[Pt][mob];
+ if (mob <= 1 && (EdgeBB & s))
+ score -= LowMobPenalty;
+
// Decrease score if we are attacked by an enemy pawn. The remaining part
// of threat evaluation must be done later when we have full attack info.
if (ei.attackedBy[Them][PAWN] & s)
if (Trace)
Tracing::terms[Us][Pt] = score;
- return score;
- }
-
-
- // evaluate_pieces() assigns bonuses and penalties to all the pieces of both colors
+ const PieceType NextPt = (Us == WHITE ? Pt : PieceType(Pt + 1));
- template<bool Trace>
- Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility) {
-
- // Do not include in mobility squares protected by enemy pawns or occupied by our pieces
- const Bitboard whiteMobilityArea = ~(ei.attackedBy[BLACK][PAWN] | pos.pieces(WHITE, PAWN, KING));
- const Bitboard blackMobilityArea = ~(ei.attackedBy[WHITE][PAWN] | pos.pieces(BLACK, PAWN, KING));
-
- Score score;
-
- score = evaluate_pieces<KNIGHT, WHITE, Trace>(pos, ei, mobility, whiteMobilityArea)
- - evaluate_pieces<KNIGHT, BLACK, Trace>(pos, ei, mobility, blackMobilityArea);
- score += evaluate_pieces<BISHOP, WHITE, Trace>(pos, ei, mobility, whiteMobilityArea)
- - evaluate_pieces<BISHOP, BLACK, Trace>(pos, ei, mobility, blackMobilityArea);
- score += evaluate_pieces< ROOK, WHITE, Trace>(pos, ei, mobility, whiteMobilityArea)
- - evaluate_pieces< ROOK, BLACK, Trace>(pos, ei, mobility, blackMobilityArea);
- score += evaluate_pieces< QUEEN, WHITE, Trace>(pos, ei, mobility, whiteMobilityArea)
- - evaluate_pieces< QUEEN, BLACK, Trace>(pos, ei, mobility, blackMobilityArea);
-
- // Sum up all attacked squares (updated in evaluate_pieces)
- ei.attackedBy[WHITE][ALL_PIECES] = ei.attackedBy[WHITE][PAWN] | ei.attackedBy[WHITE][KNIGHT]
- | ei.attackedBy[WHITE][BISHOP] | ei.attackedBy[WHITE][ROOK]
- | ei.attackedBy[WHITE][QUEEN] | ei.attackedBy[WHITE][KING];
-
- ei.attackedBy[BLACK][ALL_PIECES] = ei.attackedBy[BLACK][PAWN] | ei.attackedBy[BLACK][KNIGHT]
- | ei.attackedBy[BLACK][BISHOP] | ei.attackedBy[BLACK][ROOK]
- | ei.attackedBy[BLACK][QUEEN] | ei.attackedBy[BLACK][KING];
- if (Trace)
- {
- Tracing::terms[WHITE][Tracing::MOBILITY] = apply_weight(mobility[WHITE], Weights[Mobility]);
- Tracing::terms[BLACK][Tracing::MOBILITY] = apply_weight(mobility[BLACK], Weights[Mobility]);
- }
-
- return score;
+ return score - evaluate_pieces<NextPt, Them, Trace>(pos, ei, mobility, mobilityArea);
}
+ template<>
+ Score evaluate_pieces<KING, WHITE, false>(const Position&, EvalInfo&, Score*, Bitboard*) { return SCORE_ZERO; }
+ template<>
+ Score evaluate_pieces<KING, WHITE, true>(const Position&, EvalInfo&, Score*, Bitboard*) { return SCORE_ZERO; }
+
// evaluate_king() assigns bonuses and penalties to a king of a given color