- // Main king safety evaluation
- if (kingAttackersCount[Them] > (1 - pos.count<QUEEN>(Them)))
- {
- // Find the attacked squares which are defended only by our king...
- kingOnlyDefended = attackedBy[Them][ALL_PIECES]
- & attackedBy[Us][KING]
- & ~attackedBy2[Us];
-
- // ... and those which are not defended at all in the larger king ring
- undefended = attackedBy[Them][ALL_PIECES]
- & ~attackedBy[Us][ALL_PIECES]
- & kingRing[Us]
- & ~pos.pieces(Them);
-
- // Initialize the 'kingDanger' variable, which will be transformed
- // later into a king danger score. The initial value is based on the
- // number and types of the enemy's attacking pieces, the number of
- // attacked and weak squares around our king, the absence of queen and
- // the quality of the pawn shelter (current 'score' value).
- kingDanger = kingAttackersCount[Them] * kingAttackersWeight[Them]
- + 102 * kingAdjacentZoneAttacksCount[Them]
- + 191 * popcount(kingOnlyDefended | undefended)
- + 143 * !!pos.pinned_pieces(Us)
- - 848 * !pos.count<QUEEN>(Them)
- - 9 * mg_value(score) / 8
- + 40;
-
- // Analyse the safe enemy's checks which are possible on next move
- safe = ~pos.pieces(Them);
- safe &= ~attackedBy[Us][ALL_PIECES] | (kingOnlyDefended & attackedBy2[Them]);
-
- b1 = pos.attacks_from< ROOK>(ksq);
- b2 = pos.attacks_from<BISHOP>(ksq);
-
- // Enemy queen safe checks
- if ((b1 | b2) & attackedBy[Them][QUEEN] & safe)
- kingDanger += QueenCheck;
-
- // For minors and rooks, also consider the square safe if attacked twice,
- // and only defended by our queen.
- safe |= attackedBy2[Them]
- & ~(attackedBy2[Us] | pos.pieces(Them))
- & attackedBy[Us][QUEEN];
-
- // Some other potential checks are also analysed, even from squares
- // currently occupied by the opponent own pieces, as long as the square
- // is not attacked by our pawns, and is not occupied by a blocked pawn.
- other = ~( attackedBy[Us][PAWN]
- | (pos.pieces(Them, PAWN) & shift<Up>(pos.pieces(PAWN))));
-
- // Enemy rooks safe and other checks
- if (b1 & attackedBy[Them][ROOK] & safe)
- kingDanger += RookCheck;
-
- else if (b1 & attackedBy[Them][ROOK] & other)
- score -= OtherCheck;
-
- // Enemy bishops safe and other checks
- if (b2 & attackedBy[Them][BISHOP] & safe)
- kingDanger += BishopCheck;
-
- else if (b2 & attackedBy[Them][BISHOP] & other)
- score -= OtherCheck;
-
- // Enemy knights safe and other checks
- b = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
- if (b & safe)
- kingDanger += KnightCheck;
-
- else if (b & other)
- score -= OtherCheck;
-
- // Transform the kingDanger units into a Score, and substract it from the evaluation
- if (kingDanger > 0)
- score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
- }