- // Main king safety evaluation
- if (ei.kingAttackersCount[Them])
- {
- // Find the attacked squares which are defended only by our king...
- undefended = ei.attackedBy[Them][ALL_PIECES]
- & ei.attackedBy[Us][KING]
- & ~ei.attackedBy2[Us];
-
- // ... and those which are not defended at all in the larger king ring
- b = ei.attackedBy[Them][ALL_PIECES] & ~ei.attackedBy[Us][ALL_PIECES]
- & ei.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 undefended squares around our king and the quality of
- // the pawn shelter (current 'score' value).
- kingDanger = std::min(807, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them])
- + 101 * ei.kingAdjacentZoneAttacksCount[Them]
- + 235 * popcount(undefended)
- + 134 * (popcount(b) + !!pos.pinned_pieces(Us))
- - 717 * !pos.count<QUEEN>(Them)
- - 7 * mg_value(score) / 5 - 5;
-
- // Analyse the safe enemy's checks which are possible on next move
- safe = ~pos.pieces(Them);
- safe &= ~ei.attackedBy[Us][ALL_PIECES] | (undefended & ei.attackedBy2[Them]);
-
- b1 = pos.attacks_from<ROOK >(ksq);
- b2 = pos.attacks_from<BISHOP>(ksq);
-
- // Enemy queen safe checks
- if ((b1 | b2) & ei.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 |= ei.attackedBy2[Them]
- & ~(ei.attackedBy2[Us] | pos.pieces(Them))
- & ei.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 = ~( ei.attackedBy[Us][PAWN]
- | (pos.pieces(Them, PAWN) & shift<Up>(pos.pieces(PAWN))));
-
- // Enemy rooks safe and other checks
- if (b1 & ei.attackedBy[Them][ROOK] & safe)
- kingDanger += RookCheck;
-
- else if (b1 & ei.attackedBy[Them][ROOK] & other)
- score -= OtherCheck;
-
- // Enemy bishops safe and other checks
- if (b2 & ei.attackedBy[Them][BISHOP] & safe)
- kingDanger += BishopCheck;
-
- else if (b2 & ei.attackedBy[Them][BISHOP] & other)
- score -= OtherCheck;
-
- // Enemy knights safe and other checks
- b = pos.attacks_from<KNIGHT>(ksq) & ei.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(std::min(kingDanger * kingDanger / 4096, 2 * int(BishopValueMg)), 0);
- }