// Outpost[knight/bishop][supported by pawn] contains bonuses for knights and
// bishops outposts, bigger if outpost piece is supported by a pawn.
const Score Outpost[][2] = {
- { S(28, 7), S(42,11) }, // Knights
- { S(12, 3), S(18, 5) } // Bishops
+ { S(42,11), S(63,17) }, // Knights
+ { S(18, 5), S(27, 8) } // Bishops
};
- // Threat[defended/weak][minor/major attacking][attacked PieceType] contains
+ // Threat[defended/weak][minor/rook attacking][attacked PieceType] contains
// bonuses according to which piece type attacks which one.
const Score Threat[][2][PIECE_TYPE_NB] = {
- { { S(0, 0), S( 0, 0), S(19, 37), S(24, 37), S(44, 97), S(35,106) }, // Defended Minor
- { S(0, 0), S( 0, 0), S( 9, 14), S( 9, 14), S( 7, 14), S(24, 48) } }, // Defended Major
- { { S(0, 0), S( 0,32), S(33, 41), S(31, 50), S(41,100), S(35,104) }, // Weak Minor
- { S(0, 0), S( 0,27), S(26, 57), S(26, 57), S(0 , 43), S(23, 51) } } // Weak Major
+ { { S(0, 0), S( 0, 0), S(19, 37), S(24, 37), S(44, 97), S(35,106) }, // Minor on Defended
+ { S(0, 0), S( 0, 0), S( 9, 14), S( 9, 14), S( 7, 14), S(24, 48) } }, // Rook on Defended
+ { { S(0, 0), S( 0,32), S(33, 41), S(31, 50), S(41,100), S(35,104) }, // Minor on Weak
+ { S(0, 0), S( 0,27), S(26, 57), S(26, 57), S(0 , 43), S(23, 51) } } // Rook on Weak
};
// ThreatenedByPawn[PieceType] contains a penalty according to which piece
{ V(7), V(14), V(37), V(63), V(134), V(189) }
};
+ // PassedFile[File] contains a bonus according to the file of a passed pawn.
+ const Score PassedFile[] = {
+ S( 14, 13), S( 2, 5), S(-3, -4), S(-19, -14),
+ S(-19, -14), S(-3, -4), S( 2, 5), S( 14, 13)
+ };
+
const Score ThreatenedByHangingPawn = S(40, 60);
// Assorted bonuses and penalties used by evaluation
const Score Unstoppable = S( 0, 20);
const Score Hanging = S(31, 26);
const Score PawnAttackThreat = S(20, 20);
+ const Score Checked = S(20, 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
{
// Bonus for outpost square
if ( relative_rank(Us, s) >= RANK_4
+ && relative_rank(Us, s) <= RANK_6
&& !(pos.pieces(Them, PAWN) & pawn_attack_span(Us, s)))
score += Outpost[Pt == BISHOP][!!(ei.attackedBy[Us][PAWN] & s)];
// Enemy queen safe checks
b = (b1 | b2) & ei.attackedBy[Them][QUEEN];
if (b)
+ {
attackUnits += QueenCheck * popcount<Max15>(b);
+ score -= Checked;
+ }
// Enemy rooks safe checks
b = b1 & ei.attackedBy[Them][ROOK];
if (b)
+ {
attackUnits += RookCheck * popcount<Max15>(b);
+ score -= Checked;
+ }
// Enemy bishops safe checks
b = b2 & ei.attackedBy[Them][BISHOP];
if (b)
+ {
attackUnits += BishopCheck * popcount<Max15>(b);
+ score -= Checked;
+ }
// Enemy knights safe checks
b = pos.attacks_from<KNIGHT>(ksq) & ei.attackedBy[Them][KNIGHT] & safe;
if (b)
+ {
attackUnits += KnightCheck * popcount<Max15>(b);
+ score -= Checked;
+ }
// Finally, extract the king danger score from the KingDanger[]
// array and subtract the score from evaluation.
const Bitboard TRank7BB = (Us == WHITE ? Rank7BB : Rank2BB);
enum { Defended, Weak };
- enum { Minor, Major };
+ enum { Minor, Rook };
Bitboard b, weak, defended, safeThreats;
Score score = SCORE_ZERO;
while (b)
score += Threat[Defended][Minor][type_of(pos.piece_on(pop_lsb(&b)))];
- b = defended & (ei.attackedBy[Us][ROOK]);
+ b = defended & ei.attackedBy[Us][ROOK];
while (b)
- score += Threat[Defended][Major][type_of(pos.piece_on(pop_lsb(&b)))];
+ score += Threat[Defended][Rook][type_of(pos.piece_on(pop_lsb(&b)))];
}
// Enemies not defended by a pawn and under our attack
while (b)
score += Threat[Weak][Minor][type_of(pos.piece_on(pop_lsb(&b)))];
- b = weak & (ei.attackedBy[Us][ROOK] | ei.attackedBy[Us][QUEEN]);
+ b = weak & ei.attackedBy[Us][ROOK];
while (b)
- score += Threat[Weak][Major][type_of(pos.piece_on(pop_lsb(&b)))];
+ score += Threat[Weak][Rook][type_of(pos.piece_on(pop_lsb(&b)))];
b = weak & ~ei.attackedBy[Them][ALL_PIECES];
if (b)
if (pos.count<PAWN>(Us) < pos.count<PAWN>(Them))
ebonus += ebonus / 4;
- score += make_score(mbonus, ebonus);
+ score += make_score(mbonus, ebonus) + PassedFile[file_of(s)];
}
if (DoTrace)