- constexpr Score Hanging = S( 62, 34);
- constexpr Score KingProtector = S( 6, 7);
- constexpr Score KnightOnQueen = S( 20, 12);
- constexpr Score LongDiagonalBishop = S( 44, 0);
- constexpr Score MinorBehindPawn = S( 16, 0);
- constexpr Score PawnlessFlank = S( 18, 94);
- constexpr Score RestrictedPiece = S( 7, 6);
- constexpr Score RookOnPawn = S( 10, 28);
- constexpr Score SliderOnQueen = S( 49, 21);
- constexpr Score ThreatByKing = S( 21, 84);
- constexpr Score ThreatByPawnPush = S( 48, 42);
- constexpr Score ThreatByRank = S( 14, 3);
- constexpr Score ThreatBySafePawn = S(169, 99);
- constexpr Score TrappedRook = S( 98, 5);
- constexpr Score WeakQueen = S( 51, 10);
- constexpr Score WeakUnopposedPawn = S( 14, 20);
+ constexpr Score Hanging = S( 69, 36);
+ constexpr Score KingProtector = S( 7, 8);
+ constexpr Score KnightOnQueen = S( 16, 12);
+ constexpr Score LongDiagonalBishop = S( 45, 0);
+ constexpr Score MinorBehindPawn = S( 18, 3);
+ constexpr Score PawnlessFlank = S( 17, 95);
+ constexpr Score RestrictedPiece = S( 7, 7);
+ constexpr Score RookOnPawn = S( 10, 32);
+ constexpr Score SliderOnQueen = S( 59, 18);
+ constexpr Score ThreatByKing = S( 24, 89);
+ constexpr Score ThreatByPawnPush = S( 48, 39);
+ constexpr Score ThreatByRank = S( 13, 0);
+ constexpr Score ThreatBySafePawn = S(173, 94);
+ constexpr Score TrappedRook = S( 96, 4);
+ constexpr Score WeakQueen = S( 49, 15);
+ constexpr Score WeakUnopposedPawn = S( 12, 23);
// kingRing[color] are the squares adjacent to the king, plus (only for a
// king on its first rank) the squares two ranks in front. For instance,
// if black's king is on g8, kingRing[BLACK] is f8, h8, f7, g7, h7, f6, g6
// kingRing[color] are the squares adjacent to the king, plus (only for a
// king on its first rank) the squares two ranks in front. For instance,
// if black's king is on g8, kingRing[BLACK] is f8, h8, f7, g7, h7, f6, g6
- // Init our king safety tables only if we are going to use them
- if (pos.non_pawn_material(Them) >= RookValueMg + KnightValueMg)
- {
- kingRing[Us] = attackedBy[Us][KING];
- if (relative_rank(Us, pos.square<KING>(Us)) == RANK_1)
- kingRing[Us] |= shift<Up>(kingRing[Us]);
-
- if (file_of(pos.square<KING>(Us)) == FILE_H)
- kingRing[Us] |= shift<WEST>(kingRing[Us]);
+ if (file_of(pos.square<KING>(Us)) == FILE_H)
+ kingRing[Us] |= shift<WEST>(kingRing[Us]);
- kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
- kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
- }
+ kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
+ kingRing[Us] &= ~double_pawn_attacks_bb<Us>(pos.pieces(Us, PAWN));
+ kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
- // Attacked squares defended at most once by our queen or king
- weak = attackedBy[Them][ALL_PIECES]
- & ~attackedBy2[Us]
- & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
+ // Attacked squares defended at most once by our queen or king
+ weak = attackedBy[Them][ALL_PIECES]
+ & ~attackedBy2[Us]
+ & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
- // Analyse the safe enemy's checks which are possible on next move
- safe = ~pos.pieces(Them);
- safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
+ // Analyse the safe enemy's checks which are possible on next move
+ safe = ~pos.pieces(Them);
+ safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
- b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
- b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
+ b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
+ b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
- // Enemy queen safe checks
- if ((b1 | b2) & attackedBy[Them][QUEEN] & safe & ~attackedBy[Us][QUEEN])
- kingDanger += QueenSafeCheck;
+ // Enemy queen safe checks
+ if ((b1 | b2) & attackedBy[Them][QUEEN] & safe & ~attackedBy[Us][QUEEN])
+ kingDanger += QueenSafeCheck;
- // Enemy knights checks
- b = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
- if (b & safe)
- kingDanger += KnightSafeCheck;
- else
- unsafeChecks |= b;
-
- // Unsafe or occupied checking squares will also be considered, as long as
- // the square is in the attacker's mobility area.
- unsafeChecks &= mobilityArea[Them];
-
- kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
- + 69 * kingAttacksCount[Them]
- + 185 * popcount(kingRing[Us] & weak)
- + 150 * popcount(pos.blockers_for_king(Us) | unsafeChecks)
- + tropism * tropism / 4
- - 873 * !pos.count<QUEEN>(Them)
- - 6 * mg_value(score) / 8
- + mg_value(mobility[Them] - mobility[Us])
- - 30;
-
- // Transform the kingDanger units into a Score, and subtract it from the evaluation
- if (kingDanger > 0)
- score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
- }
+ // Enemy knights checks
+ b = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
+ if (b & safe)
+ kingDanger += KnightSafeCheck;
+ else
+ unsafeChecks |= b;
+
+ // Unsafe or occupied checking squares will also be considered, as long as
+ // the square is in the attacker's mobility area.
+ unsafeChecks &= mobilityArea[Them];
+
+ kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
+ + 69 * kingAttacksCount[Them]
+ + 185 * popcount(kingRing[Us] & weak)
+ + 150 * popcount(pos.blockers_for_king(Us) | unsafeChecks)
+ + tropism * tropism / 4
+ - 873 * !pos.count<QUEEN>(Them)
+ - 6 * mg_value(score) / 8
+ + mg_value(mobility[Them] - mobility[Us])
+ - 30;
+
+ // Transform the kingDanger units into a Score, and subtract it from the evaluation
+ if (kingDanger > 0)
+ score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
// Squares strongly protected by the enemy, either because they defend the
// square with a pawn, or because they defend the square twice and we don't.
// Squares strongly protected by the enemy, either because they defend the
// square with a pawn, or because they defend the square twice and we don't.
- int complexity = 8 * pe->pawn_asymmetry()
- + 12 * pos.count<PAWN>()
- + 12 * outflanking
- + 16 * pawnsOnBothFlanks
- + 48 * !pos.non_pawn_material()
- -118 ;
+ int complexity = 9 * pe->pawn_asymmetry()
+ + 11 * pos.count<PAWN>()
+ + 9 * outflanking
+ + 18 * pawnsOnBothFlanks
+ + 49 * !pos.non_pawn_material()
+ -121 ;