- // King safety. This is quite complicated, and is almost certainly far
- // from optimally tuned.
- Color them = opposite_color(us);
- if(p.queen_count(them) >= 1 && ei.attackCount[them] >= 2
- && p.non_pawn_material(them) >= QueenValueMidgame + RookValueMidgame
- && ei.attacked[them]) {
-
- // Is it the attackers turn to move?
- bool sente = (them == p.side_to_move());
-
- // Find the attacked squares around the king which has no defenders
- // apart from the king itself:
- Bitboard undefended =
- ei.attacked_by(them) & ~ei.attacked_by(us, PAWN)
- & ~ei.attacked_by(us, KNIGHT) & ~ei.attacked_by(us, BISHOP)
- & ~ei.attacked_by(us, ROOK) & ~ei.attacked_by(us, QUEEN)
- & ei.attacked_by(us, KING);
- Bitboard occ = p.occupied_squares(), b, b2;
-
- // Initialize the 'attackUnits' variable, which is used later on as an
- // index to the SafetyTable[] array. The initial is based on the number
- // and types of the attacking pieces, the number of attacked and
- // undefended squares around the king, the square of the king, and the
- // quality of the pawn shelter.
- int attackUnits =
- Min((ei.attackCount[them] * ei.attackWeight[them]) / 2, 25)
- + (ei.attacked[them] + count_1s_max_15(undefended)) * 3
- + InitKingDanger[relative_square(us, s)] - shelter / 32;
-
- // Analyse safe queen contact checks:
- b = undefended & ei.attacked_by(them, QUEEN) & ~p.pieces_of_color(them);
- if(b) {
- Bitboard attackedByOthers =
- ei.attacked_by(them, PAWN) | ei.attacked_by(them, KNIGHT)
- | ei.attacked_by(them, BISHOP) | ei.attacked_by(them, ROOK);
- b &= attackedByOthers;
- if(b) {
- // The bitboard b now contains the squares available for safe queen
- // contact checks.
- int count = count_1s_max_15(b);
- attackUnits += QueenContactCheckBonus * count * (sente? 2 : 1);
-
- // Is there a mate threat?
- if(QueenContactMates && !p.is_check()) {
- Bitboard escapeSquares =
- p.king_attacks(s) & ~p.pieces_of_color(us) & ~attackedByOthers;
- while(b) {
- Square from, to = pop_1st_bit(&b);
- if(!(escapeSquares
- & ~queen_attacks_bb(to, occ & clear_mask_bb(s)))) {
- // We have a mate, unless the queen is pinned or there
- // is an X-ray attack through the queen.
- for(int i = 0; i < p.queen_count(them); i++) {
- from = p.queen_list(them, i);
- if(bit_is_set(p.queen_attacks(from), to)
- && !bit_is_set(p.pinned_pieces(them), from)
- && !(rook_attacks_bb(to, occ & clear_mask_bb(from))
- & p.rooks_and_queens(us))
- && !(rook_attacks_bb(to, occ & clear_mask_bb(from))
- & p.rooks_and_queens(us)))
- ei.mateThreat[them] = make_move(from, to);
+ // King safety. This is quite complicated, and is almost certainly far
+ // from optimally tuned.
+ if ( pos.piece_count(Them, QUEEN) >= 1
+ && ei.kingAttackersCount[Them] >= 2
+ && pos.non_pawn_material(Them) >= QueenValueMidgame + RookValueMidgame
+ && ei.kingAdjacentZoneAttacksCount[Them])
+ {
+ // Is it the attackers turn to move?
+ sente = (Them == pos.side_to_move());
+
+ // Find the attacked squares around the king which has no defenders
+ // apart from the king itself
+ undefended = ei.attacked_by(Them) & ei.attacked_by(Us, KING);
+ undefended &= ~( ei.attacked_by(Us, PAWN) | ei.attacked_by(Us, KNIGHT)
+ | ei.attacked_by(Us, BISHOP) | ei.attacked_by(Us, ROOK)
+ | ei.attacked_by(Us, QUEEN));
+
+ // Initialize the 'attackUnits' variable, which is used later on as an
+ // index to the KingDangerTable[] array. 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, the square of the
+ // king, and the quality of the pawn shelter.
+ attackUnits = Min(25, (ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them]) / 2)
+ + 3 * (ei.kingAdjacentZoneAttacksCount[Them] + count_1s_max_15<HasPopCnt>(undefended))
+ + InitKingDanger[relative_square(Us, ksq)]
+ - shelter / 32;
+
+ // Analyse safe queen contact checks
+ b = undefended & ei.attacked_by(Them, QUEEN) & ~pos.pieces_of_color(Them);
+ if (b)
+ {
+ attackedByOthers = ei.attacked_by(Them, PAWN) | ei.attacked_by(Them, KNIGHT)
+ | ei.attacked_by(Them, BISHOP) | ei.attacked_by(Them, ROOK);
+
+ b &= attackedByOthers;
+
+ // Squares attacked by the queen and supported by another enemy piece and
+ // not defended by other pieces but our king.
+ if (b)
+ {
+ // The bitboard b now contains the squares available for safe queen
+ // contact checks.
+ attackUnits += QueenContactCheckBonus * count_1s_max_15<HasPopCnt>(b) * (sente ? 2 : 1);
+
+ // Is there a mate threat?
+ if (QueenContactMates && !pos.is_check())
+ {
+ escapeSquares = pos.attacks_from<KING>(ksq) & ~pos.pieces_of_color(Us) & ~attackedByOthers;
+ occ = pos.occupied_squares();
+ while (b)
+ {
+ to = pop_1st_bit(&b);
+
+ // Do we have escape squares from queen contact check attack ?
+ if (!(escapeSquares & ~queen_attacks_bb(to, occ & ClearMaskBB[ksq])))
+ {
+ // We have a mate, unless the queen is pinned or there
+ // is an X-ray attack through the queen.
+ for (int i = 0; i < pos.piece_count(Them, QUEEN); i++)
+ {
+ from = pos.piece_list(Them, QUEEN, i);
+ if ( bit_is_set(pos.attacks_from<QUEEN>(from), to)
+ && !bit_is_set(pos.pinned_pieces(Them), from)
+ && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & pos.pieces(ROOK, QUEEN, Us))
+ && !(bishop_attacks_bb(to, occ & ClearMaskBB[from]) & pos.pieces(BISHOP, QUEEN, Us)))
+
+ // Set the mate threat move
+ ei.mateThreat[Them] = make_move(from, to);
+ }
+ }
+ }