]> git.sesse.net Git - stockfish/blobdiff - src/evaluate.cpp
Knight threats on Queen
[stockfish] / src / evaluate.cpp
index 8e6d827eef25f27537cfc4a6e55615e054b03ce6..1e5c588a31eb8a357bdf4e54591e8484cc97f1df 100644 (file)
@@ -167,6 +167,7 @@ namespace {
   const Score CloseEnemies      = S(  7,  0);
   const Score Hanging           = S( 52, 30);
   const Score HinderPassedPawn  = S(  8,  1);
   const Score CloseEnemies      = S(  7,  0);
   const Score Hanging           = S( 52, 30);
   const Score HinderPassedPawn  = S(  8,  1);
+  const Score KnightOnQueen     = S( 21, 11);
   const Score LongRangedBishop  = S( 22,  0);
   const Score MinorBehindPawn   = S( 16,  0);
   const Score PawnlessFlank     = S( 20, 80);
   const Score LongRangedBishop  = S( 22,  0);
   const Score MinorBehindPawn   = S( 16,  0);
   const Score PawnlessFlank     = S( 20, 80);
@@ -482,22 +483,20 @@ namespace {
             score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
         }
     }
             score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
         }
     }
-    // Penalty when our king is on a pawnless flank
-    if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
-        score -= PawnlessFlank;
 
 
-    // King tropism: firstly, find attacked squares in our king flank
-    b = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
+    Bitboard kf = KingFlank[file_of(ksq)];
 
 
-    assert(((Us == WHITE ? b << 4 : b >> 4) & b) == 0);
-    assert(popcount(Us == WHITE ? b << 4 : b >> 4) == popcount(b));
+    // Penalty when our king is on a pawnless flank
+    if (!(pos.pieces(PAWN) & kf))
+        score -= PawnlessFlank;
 
 
-    // Secondly, add the squares which are attacked twice in that flank and
-    // which are not defended by our pawns.
-    b =  (Us == WHITE ? b << 4 : b >> 4)
-       | (b & attackedBy2[Them] & ~attackedBy[Us][PAWN]);
+    // Find the squares that opponent attacks in our king flank, and the squares
+    // which are attacked twice in that flank but not defended by our pawns.
+    b1 = attackedBy[Them][ALL_PIECES] & kf & Camp;
+    b2 = b1 & attackedBy2[Them] & ~attackedBy[Us][PAWN];
 
 
-    score -= CloseEnemies * popcount(b);
+    // King tropism, to anticipate slow motion attacks on our king
+    score -= CloseEnemies * (popcount(b1) + popcount(b2));
 
     if (T)
         Trace::add(KING, Us, score);
 
     if (T)
         Trace::add(KING, Us, score);
@@ -597,6 +596,17 @@ namespace {
 
     score += ThreatOnQueen * popcount(b & safeThreats);
 
 
     score += ThreatOnQueen * popcount(b & safeThreats);
 
+    // Bonus for knight threats on the next moves against enemy queen
+    if (pos.count<QUEEN>(Them) == 1)
+    {
+        b =   pos.attacks_from<KNIGHT>(pos.square<QUEEN>(Them))
+           &  attackedBy[Us][KNIGHT]
+           & ~pos.pieces(Us, PAWN, KING)
+           & ~stronglyProtected;
+
+        score += KnightOnQueen * popcount(b);
+    }
+
     if (T)
         Trace::add(THREAT, Us, score);
 
     if (T)
         Trace::add(THREAT, Us, score);
 
@@ -728,12 +738,9 @@ namespace {
     behind |= (Us == WHITE ? behind >>  8 : behind <<  8);
     behind |= (Us == WHITE ? behind >> 16 : behind << 16);
 
     behind |= (Us == WHITE ? behind >>  8 : behind <<  8);
     behind |= (Us == WHITE ? behind >> 16 : behind << 16);
 
-    // Since SpaceMask[Us] is fully on our half of the board...
-    assert(unsigned(safe >> (Us == WHITE ? 32 : 0)) == 0);
-
-    // ...count safe + (behind & safe) with a single popcount.
-    int bonus = popcount((Us == WHITE ? safe << 32 : safe >> 32) | (behind & safe));
+    int bonus = popcount(safe) + popcount(behind & safe);
     int weight = pos.count<ALL_PIECES>(Us) - 2 * pe->open_files();
     int weight = pos.count<ALL_PIECES>(Us) - 2 * pe->open_files();
+
     Score score = make_score(bonus * weight * weight / 16, 0);
 
     if (T)
     Score score = make_score(bonus * weight * weight / 16, 0);
 
     if (T)