- // Main king safety evaluation
- if (kingAttackersCount[Them] > (1 - pos.count<QUEEN>(Them)))
- {
- // Attacked squares defended at most once by our queen or king
- weak = attackedBy[Them][ALL_PIECES]
- & ~attackedBy2[Us]
- & (attackedBy[Us][KING] | attackedBy[Us][QUEEN] | ~attackedBy[Us][ALL_PIECES]);
-
- // 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(kingRing[Us] & weak)
- + 143 * bool(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] | (weak & 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 & ~attackedBy[Us][QUEEN])
- kingDanger += QueenCheck;
-
- // 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);
- }