// Threat[attacking][attacked] contains bonuses according to which piece
// type attacks which one.
const Score Threat[][PIECE_TYPE_NB] = {
- { S(0, 0), S(0, 38), S(32, 45), S(32, 45), S(41,100), S(35,104) }, // Minor
- { S(0, 0), S(7, 28), S(20, 49), S(20, 49), S(8 , 42), S(23, 44) } // Major
+ { S(0, 0), S( 0, 0), S(19, 37), S(24, 37), S(44, 97), S(35,106) }, // Protected Minor attacks
+ { S(0, 0), S( 0, 0), S( 9, 14), S( 9, 14), S( 7, 14), S(24, 48) }, // Protected Major attacks
+ { S(0, 0), S( 0,32), S(33, 41), S(31, 50), S(41,100), S(35,104) }, // Weak Minor attacks
+ { S(0, 0), S( 0,27), S(26, 57), S(26, 57), S(0 , 43), S(23, 51) } // Weak Major attacks
};
// ThreatenedByPawn[PieceType] contains a penalty according to which piece
// type is attacked by an enemy pawn.
const Score ThreatenedByPawn[] = {
- S(0, 0), S(0, 0), S(80, 119), S(80, 119), S(117, 199), S(127, 218)
+ S(0, 0), S(0, 0), S(87, 118), S(84, 122), S(114, 203), S(121, 217)
};
// Assorted bonuses and penalties used by evaluation
const Score KingOnOne = S(2 , 58);
const Score KingOnMany = S(6 ,125);
- const Score RookOnPawn = S(10, 28);
+ const Score RookOnPawn = S(7 , 27);
const Score RookOpenFile = S(43, 21);
const Score RookSemiOpenFile = S(19, 10);
const Score BishopPawns = S( 8, 12);
const Score MinorBehindPawn = S(16, 0);
const Score TrappedRook = S(92, 0);
const Score Unstoppable = S( 0, 20);
- const Score Hanging = S(23, 20);
+ const Score Hanging = S(31, 26);
// 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
// scores, indexed by a calculated integer number.
Score KingDanger[128];
- const int ScalePawnSpan[2] = { 38, 56 };
-
// apply_weight() weighs score 'v' by weight 'w' trying to prevent overflow
Score apply_weight(Score v, const Weight& w) {
return make_score(mg_value(v) * w.mg / 256, eg_value(v) * w.eg / 256);
ei.attackedBy[Us][ALL_PIECES] = ei.attackedBy[Us][PAWN] = ei.pi->pawn_attacks(Us);
// Init king safety tables only if we are going to use them
- if (pos.non_pawn_material(Us) > QueenValueMg + PawnValueMg)
+ if (pos.non_pawn_material(Us) >= QueenValueMg)
{
ei.kingRing[Them] = b | shift_bb<Down>(b);
b &= ei.attackedBy[Us][PAWN];
}
- // max_piece_type() is a helper function used by evaluate_threats() to get
- // the value of the biggest PieceType of color C in 'target' bitboard.
-
- template<Color C>
- inline PieceType max_piece_type(const Position& pos, const Bitboard target) {
-
- assert(target & (pos.pieces(C) ^ pos.pieces(C, KING)));
-
- for (PieceType pt = QUEEN; pt > PAWN; --pt)
- if (target & pos.pieces(C, pt))
- return pt;
-
- return PAWN;
- }
// evaluate_threats() assigns bonuses according to the type of attacking piece
const Color Them = (Us == WHITE ? BLACK : WHITE);
- enum { Minor, Major };
-
+ enum { Protected_Minor, Protected_Major, Minor, Major };
Bitboard b, weakEnemies, protectedEnemies;
Score score = SCORE_ZERO;
- // Enemies defended by a pawn and under our attack by a minor piece
- protectedEnemies = (pos.pieces(Them) ^ pos.pieces(Them, PAWN))
- & ei.attackedBy[Them][PAWN]
- & (ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]);
+ // Enemies defended by a pawn and under our attack
+ protectedEnemies = (pos.pieces(Them) ^ pos.pieces(Them, PAWN))
+ & ei.attackedBy[Them][PAWN]
+ & (ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK]);
if (protectedEnemies)
- score += Threat[Minor][max_piece_type<Them>(pos, protectedEnemies)];
+ {
+ // Enemies defended by a pawn and under our attack by a minor piece
+ b = protectedEnemies & (ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]);
+ while (b)
+ score += Threat[Protected_Minor][type_of(pos.piece_on(pop_lsb(&b)))];
+
+ // Enemies defended by a pawn and under our attack by a ROOK
+ b = protectedEnemies & (ei.attackedBy[Us][ROOK]);
+ while (b)
+ score += Threat[Protected_Major][type_of(pos.piece_on(pop_lsb(&b)))];
+ }
// Enemies not defended by a pawn and under our attack
weakEnemies = pos.pieces(Them)
if (weakEnemies)
{
b = weakEnemies & (ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]);
- if (b)
- score += Threat[Minor][max_piece_type<Them>(pos, b)];
+ while (b)
+ score += Threat[Minor][type_of(pos.piece_on(pop_lsb(&b)))];
b = weakEnemies & (ei.attackedBy[Us][ROOK] | ei.attackedBy[Us][QUEEN]);
- if (b)
- score += Threat[Major][max_piece_type<Them>(pos, b)];
+ while (b)
+ score += Threat[Major][type_of(pos.piece_on(pop_lsb(&b)))];
b = weakEnemies & ~ei.attackedBy[Them][ALL_PIECES];
if (b)
else if ( abs(eg_value(score)) <= BishopValueEg
&& ei.pi->pawn_span(strongSide) <= 1
&& !pos.pawn_passed(~strongSide, pos.king_square(~strongSide)))
- sf = ScaleFactor(ScalePawnSpan[ei.pi->pawn_span(strongSide)]);
+ sf = ei.pi->pawn_span(strongSide) ? ScaleFactor(56) : ScaleFactor(38);
}
// Interpolate between a middlegame and a (scaled by 'sf') endgame score