Exclude passed pawns from Attacked2Unsupported
author31m059 <37052095+31m059@users.noreply.github.com>
Thu, 11 Jul 2019 13:14:57 +0000 (09:14 -0400)
committerStéphane Nicolet <cassio@free.fr>
Thu, 11 Jul 2019 21:05:28 +0000 (23:05 +0200)
We recently added a bonus for double pawn attacks on unsupported enemy pawns,
on June 27. However, it is possible that the unsupported pawn may become a passer
by simply pushing forward out of the double attack. By rewarding double attacks,
we may inadvertently reward the creation of enemy passers, by encouraging both of
our would-be stoppers to attack the enemy pawn even if there is no opposing
friendly pawn on the same file.

Here, we revise this term to exclude passed pawns. In order to simplify the code
with this change included, we non-functionally rewrite Attacked2Unsupported to
be a penalty for enemy attacks on friendly pawns, rather than a bonus for our
attacks on enemy pawns. This allows us to exclude passed pawns with a simple
& ~e->passedPawns[Us], while passedPawns[Them] is not yet defined in this part
of the code.

This dramatically reduces the proportion of positions in which Attacked2Unsupported
is applied, to about a third of the original. To compensate, maintaining the same
average effect across our bench positions, we nearly triple Attacked2Unsupported
from S(0, 20) to S(0, 56). Although this pawn formation is rare, it is worth more
than half a pawn in the endgame!

STC: (stopped automatically by fishtest after 250,000 games)
LLR: -0.87 (-2.94,2.94) [0.50,4.50]
Total: 250000 W: 56585 L: 55383 D: 138032
http://tests.stockfishchess.org/tests/view/5d25795e0ebc5925cf0cfb51

LTC:
LLR: 2.96 (-2.94,2.94) [0.00,3.50]
Total: 81038 W: 13965 L: 13558 D: 53515
http://tests.stockfishchess.org/tests/view/5d25f3920ebc5925cf0d10dd

Closes https://github.com/official-stockfish/Stockfish/pull/2233

Bench: 3765158

src/evaluate.cpp
src/pawns.cpp

index c4e02e4ea66fd39b1948efc490d1204d680027ff..a52cdf0928ab5cdc72800eb4439464979cd57110 100644 (file)
@@ -655,7 +655,7 @@ namespace {
                         !(unsafeSquares & blockSq)        ?  9 :
                                                              0 ;
 
-                // Assign a larger bonus if the block square is defended.
+                // Assign a larger bonus if the block square is defended
                 if (defendedSquares & blockSq)
                     k += 5;
 
index 45c404712a200b949dbc0e3b515ebc81f4475bae..0d3a57bfa6eabb2866ad6c6a6f60a36d6acdc10f 100644 (file)
@@ -35,8 +35,8 @@ namespace {
   constexpr Score Backward      = S( 9, 24);
   constexpr Score Doubled       = S(11, 56);
   constexpr Score Isolated      = S( 5, 15);
-  constexpr Score WeakUnopposed = S( 13, 27);
-  constexpr Score Attacked2Unsupported = S( 0, 20);
+  constexpr Score WeakUnopposed = S(13, 27);
+  constexpr Score Attacked2Unsupported = S(0, 56);
 
   // Connected pawn bonus
   constexpr int Connected[RANK_NB] = { 0, 7, 8, 12, 29, 48, 86 };
@@ -84,11 +84,6 @@ namespace {
     e->kingSquares[Us] = SQ_NONE;
     e->pawnAttacks[Us] = pawn_attacks_bb<Us>(ourPawns);
 
-    // Unsupported enemy pawns attacked twice by us
-    score += Attacked2Unsupported * popcount(  theirPawns
-                                             & pawn_double_attacks_bb<Us>(ourPawns)
-                                             & ~pawn_attacks_bb<Them>(theirPawns));
-
     // Loop through all pawns of the current color and score each pawn
     while ((s = *pl++) != SQ_NONE)
     {
@@ -116,8 +111,8 @@ namespace {
 
         // Passed pawns will be properly scored in evaluation because we need
         // full attack info to evaluate them. Include also not passed pawns
-        // which could become passed after one or two pawn pushes when are
-        // not attacked more times than defended.
+        // which could become passed after one or two pawn pushes when they
+        // are not attacked more times than defended.
         if ( !(stoppers ^ lever) ||
             (!(stoppers ^ leverPush) && popcount(phalanx) >= popcount(leverPush)))
             e->passedPawns[Us] |= s;
@@ -149,6 +144,12 @@ namespace {
             score -= Doubled;
     }
 
+    // Unsupported friendly pawns attacked twice by the enemy
+    score -= Attacked2Unsupported * popcount(  ourPawns
+                                             & pawn_double_attacks_bb<Them>(theirPawns)
+                                             & ~pawn_attacks_bb<Us>(ourPawns)
+                                             & ~e->passedPawns[Us]);
+
     return score;
   }