From eb20a87c67c1f7f8bef8895d1a848f8fa6fd9d96 Mon Sep 17 00:00:00 2001 From: Alain SAVARD Date: Sun, 3 Jul 2016 08:29:53 -0400 Subject: [PATCH] More safe checks Consider a check given by a rook or a minor to be a "safe check" also in the case where supported by another piece, and given on a square only defended by a queen Was yellow STC http://tests.stockfishchess.org/tests/view/576fcbc80ebc5972faa163e8 LLR: -2.96 (-2.94,2.94) [0.00,5.00] Total: 55453 W: 10431 L: 10315 D: 34707 Passed LTC http://tests.stockfishchess.org/tests/view/57733a0b0ebc5972faa164b7 LLR: 2.96 (-2.94,2.94) [0.00,5.00] Total: 54550 W: 7671 L: 7365 D: 39514 bench: 7398346 --- src/evaluate.cpp | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index d6af118b..9be0bada 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -77,6 +77,11 @@ namespace { // attacked by a given color and piece type (can be also ALL_PIECES). Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB]; + // attackedBy2[color] are the squares attacked by 2 pieces of a given color, + // possibly via x-ray or by one pawn and one piece. Diagonal x-ray through + // pawn or squares attacked by 2 pawns are not explicitly added. + Bitboard attackedBy2[COLOR_NB]; + // kingRing[color] is the zone around the king which is considered // by the king safety evaluation. This consists of the squares directly // adjacent to the king, and the three (or two, for a king on an edge file) @@ -227,9 +232,10 @@ namespace { const Square Down = (Us == WHITE ? DELTA_S : DELTA_N); ei.pinnedPieces[Us] = pos.pinned_pieces(Us); - Bitboard b = ei.attackedBy[Them][KING] = pos.attacks_from(pos.square(Them)); + Bitboard b = ei.attackedBy[Them][KING]; ei.attackedBy[Them][ALL_PIECES] |= b; ei.attackedBy[Us][ALL_PIECES] |= ei.attackedBy[Us][PAWN] = ei.pi->pawn_attacks(Us); + ei.attackedBy2[Us] = ei.attackedBy[Us][PAWN] & ei.attackedBy[Us][KING]; // Init king safety tables only if we are going to use them if (pos.non_pawn_material(Us) >= QueenValueMg) @@ -272,6 +278,7 @@ namespace { if (ei.pinnedPieces[Us] & s) b &= LineBB[pos.square(Us)][s]; + ei.attackedBy2[Us] |= ei.attackedBy[Us][ALL_PIECES] & b; ei.attackedBy[Us][ALL_PIECES] |= ei.attackedBy[Us][Pt] |= b; if (b & ei.kingRing[Them]) @@ -389,11 +396,9 @@ namespace { if (ei.kingAttackersCount[Them]) { // Find the attacked squares which are defended only by the king... - undefended = ei.attackedBy[Them][ALL_PIECES] - & ei.attackedBy[Us][KING] - & ~( ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] - | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK] - | ei.attackedBy[Us][QUEEN]); + 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] @@ -414,15 +419,9 @@ namespace { // Analyse the enemy's safe queen contact checks. Firstly, find the // undefended squares around the king reachable by the enemy queen... b = undefended & ei.attackedBy[Them][QUEEN] & ~pos.pieces(Them); - if (b) - { - // ...and then remove squares not supported by another enemy piece - b &= ei.attackedBy[Them][PAWN] | ei.attackedBy[Them][KNIGHT] - | ei.attackedBy[Them][BISHOP] | ei.attackedBy[Them][ROOK] - | ei.attackedBy[Them][KING]; - attackUnits += QueenContactCheck * popcount(b); - } + // ...and keep squares supported by another enemy piece + attackUnits += QueenContactCheck * popcount(b & ei.attackedBy2[Them]); // Analyse the safe enemy's checks which are possible on next move... safe = ~(ei.attackedBy[Us][ALL_PIECES] | pos.pieces(Them)); @@ -439,6 +438,12 @@ namespace { if ((b1 | b2) & ei.attackedBy[Them][QUEEN] & safe) attackUnits += QueenCheck, score -= SafeCheck; + // For other pieces, also consider the square safe if attacked twice, + // and only defended by a queen. + safe |= ei.attackedBy2[Them] + & ~(ei.attackedBy2[Us] | pos.pieces(Them)) + & ei.attackedBy[Us][QUEEN]; + // Enemy rooks safe and other checks if (b1 & ei.attackedBy[Them][ROOK] & safe) attackUnits += RookCheck, score -= SafeCheck; @@ -770,6 +775,8 @@ Value Eval::evaluate(const Position& pos) { // Initialize attack and king safety bitboards ei.attackedBy[WHITE][ALL_PIECES] = ei.attackedBy[BLACK][ALL_PIECES] = 0; + ei.attackedBy[WHITE][KING] = pos.attacks_from(pos.square(WHITE)); + ei.attackedBy[BLACK][KING] = pos.attacks_from(pos.square(BLACK)); eval_init(pos, ei); eval_init(pos, ei); -- 2.39.2