const int GrainSize = 8;
// Evaluation weights, initialized from UCI options
- enum { Mobility, PawnStructure, PassedPawns, Space, KingDangerUs, KingDangerThem };
+ enum { Mobility, PassedPawns, Space, KingDangerUs, KingDangerThem };
Score Weights[6];
typedef Value V;
//
// Values modified by Joona Kiiski
const Score WeightsInternal[] = {
- S(248, 271), S(233, 201), S(252, 259), S(46, 0), S(247, 0), S(259, 0)
+ S(248, 271), S(252, 259), S(46, 0), S(247, 0), S(259, 0)
};
// MobilityBonus[PieceType][attacked] contains mobility bonuses for middle and
{ S(0, 0), S(15, 39), S(15, 39), S(15, 39), S(15, 39), S( 0, 0) } // QUEEN
};
- // ThreatedByPawnPenalty[PieceType] contains a penalty according to which
+ // ThreatenedByPawnPenalty[PieceType] contains a penalty according to which
// piece type is attacked by an enemy pawn.
- const Score ThreatedByPawnPenalty[] = {
+ const Score ThreatenedByPawnPenalty[] = {
S(0, 0), S(0, 0), S(56, 70), S(56, 70), S(76, 99), S(86, 118)
};
// Probe the pawn hash table
ei.pi = Threads[pos.thread()].pawnTable.get_pawn_info(pos);
- score += apply_weight(ei.pi->pawns_value(), Weights[PawnStructure]);
+ score += ei.pi->pawns_value();
// Initialize attack and king safety bitboards
init_eval_info<WHITE, HasPopCnt>(pos, ei);
{
trace_add(PST, pos.value());
trace_add(IMBALANCE, ei.mi->material_value());
- trace_add(PAWN, apply_weight(ei.pi->pawns_value(), Weights[PawnStructure]));
+ trace_add(PAWN, ei.pi->pawns_value());
trace_add(MOBILITY, apply_weight(mobilityWhite, Weights[Mobility]), apply_weight(mobilityBlack, Weights[Mobility]));
trace_add(THREAT, evaluate_threats<WHITE>(pos, ei), evaluate_threats<BLACK>(pos, ei));
trace_add(PASSED, evaluate_passed_pawns<WHITE>(pos, ei), evaluate_passed_pawns<BLACK>(pos, ei));
const int kingDangerThem = (us == WHITE ? KingDangerThem : KingDangerUs);
Weights[Mobility] = weight_option("Mobility (Middle Game)", "Mobility (Endgame)", WeightsInternal[Mobility]);
- Weights[PawnStructure] = weight_option("Pawn Structure (Middle Game)", "Pawn Structure (Endgame)", WeightsInternal[PawnStructure]);
Weights[PassedPawns] = weight_option("Passed Pawns (Middle Game)", "Passed Pawns (Endgame)", WeightsInternal[PassedPawns]);
Weights[Space] = weight_option("Space", "Space", WeightsInternal[Space]);
Weights[kingDangerUs] = weight_option("Cowardice", "Cowardice", WeightsInternal[KingDangerUs]);
// Decrease score if we are attacked by an enemy pawn. Remaining part
// of threat evaluation must be done later when we have full attack info.
if (bit_is_set(ei.attackedBy[Them][PAWN], s))
- score -= ThreatedByPawnPenalty[Piece];
+ score -= ThreatenedByPawnPenalty[Piece];
// Bishop and knight outposts squares
if ((Piece == BISHOP || Piece == KNIGHT) && pos.square_is_weak(s, Us))
Square blockSq = s + pawn_push(Us);
// Adjust bonus based on kings proximity
- ebonus -= Value(square_distance(pos.king_square(Us), blockSq) * 3 * rr);
- ebonus -= Value(square_distance(pos.king_square(Us), blockSq + pawn_push(Us)) * rr);
ebonus += Value(square_distance(pos.king_square(Them), blockSq) * 6 * rr);
+ ebonus -= Value(square_distance(pos.king_square(Us), blockSq) * 3 * rr);
+
+ // If blockSq is not the queening square then consider also a second push
+ if (square_rank(blockSq) != (Us == WHITE ? RANK_8 : RANK_1))
+ ebonus -= Value(square_distance(pos.king_square(Us), blockSq + pawn_push(Us)) * rr);
// If the pawn is free to advance, increase bonus
if (pos.square_is_empty(blockSq))
// Opponent king cannot block because path is defended and position
// is not in check. So only friendly pieces can be blockers.
assert(!pos.in_check());
- assert(queeningPath & pos.occupied_squares() == queeningPath & pos.pieces_of_color(c));
+ assert((queeningPath & pos.occupied_squares()) == (queeningPath & pos.pieces_of_color(c)));
// Add moves needed to free the path from friendly pieces and retest condition
movesToGo += count_1s<Max15>(queeningPath & pos.pieces_of_color(c));
// apply_weight() applies an evaluation weight to a value trying to prevent overflow
inline Score apply_weight(Score v, Score w) {
- return make_score((int(mg_value(v)) * mg_value(w)) / 0x100,
- (int(eg_value(v)) * eg_value(w)) / 0x100);
+ return make_score((int(mg_value(v)) * mg_value(w)) / 0x100,
+ (int(eg_value(v)) * eg_value(w)) / 0x100);
}