Score unopposed weak pawns only if majors
authorSt├ęphane Nicolet <cassio@free.fr>
Sat, 16 Sep 2017 12:07:41 +0000 (14:07 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 17 Sep 2017 07:52:27 +0000 (09:52 +0200)
Do not use the opposed flag for scoring backward and isolated pawns
in pawns.cpp, instead give a S(5,25) bonus for each opponent unopposed
weak pawns when we have a rook or a queen on the board.

STC run stopped after 113188 games:
LLR: 1.63 (-2.94,2.94) [0.00,5.00]
Total: 113188 W: 20804 L: 20251 D: 72133
http://tests.stockfishchess.org/tests/view/59b58e4d0ebc5916ff64b12e

LTC:
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 66673 W: 8672 L: 8341 D: 49660
http://tests.stockfishchess.org/tests/view/59b902580ebc5916ff64b231

This is Alain Savard's idea, just with a different bonus.
Original patch there:

green STC, http://tests.stockfishchess.org/tests/view/597dcd2b0ebc5916ff64a09b
yellow LTC, http://tests.stockfishchess.org/tests/view/597ea69e0ebc5916ff64a0e6

Bench: 6259498

src/evaluate.cpp
src/pawns.cpp
src/pawns.h
src/thread.cpp

index 7ee3652b1b40c22d273f374e35e862c638269b4b..031b803417c4c4832f7b6fe5bdb2a3d26618f724 100644 (file)
@@ -162,8 +162,8 @@ namespace {
   // supported by a pawn. If the minor piece occupies an outpost square
   // then score is doubled.
   const Score Outpost[][2] = {
-    { S(22, 6), S(33, 9) }, // Knight
-    { S( 9, 2), S(14, 4) }  // Bishop
+    { S(22, 6), S(36,12) }, // Knight
+    { S( 9, 2), S(15, 5) }  // Bishop
   };
 
   // RookOnFile[semiopen/open] contains bonuses for each rook when there is no
@@ -214,6 +214,7 @@ namespace {
   const Score ThreatBySafePawn    = S(182,175);
   const Score ThreatByRank        = S( 16,  3);
   const Score Hanging             = S( 48, 27);
+  const Score WeakUnopposedPawn   = S(  5, 25);
   const Score ThreatByPawnPush    = S( 38, 22);
   const Score HinderPassedPawn    = S(  7,  0);
   const Score TrappedBishopA1H1   = S( 50, 50);
@@ -593,6 +594,10 @@ namespace {
             score += ThreatByKing[more_than_one(b)];
     }
 
+    // Bonus for opponent unopposed weak pawns
+    if (pos.pieces(Us, ROOK, QUEEN))
+        score += WeakUnopposedPawn * pe->weak_unopposed(Them);
+
     // Find squares where our pawns can push on the next move
     b  = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
     b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
index aa36b1e6f8d1e043b8aa844ea0c7f1ef28aacb44..9099875420f821bd73b795cd76e4f449a02df9ec 100644 (file)
@@ -31,11 +31,11 @@ namespace {
   #define V Value
   #define S(mg, eg) make_score(mg, eg)
 
-  // Isolated pawn penalty by opposed flag
-  const Score Isolated[] = { S(27, 30), S(13, 18) };
+  // Isolated pawn penalty
+  const Score Isolated = S(13, 18);
 
-  // Backward pawn penalty by opposed flag
-  const Score Backward[] = { S(40, 26), S(24, 12) };
+  // Backward pawn penalty
+  const Score Backward = S(24, 12);
 
   // Connected pawn bonus by opposed, phalanx, #support and rank
   Score Connected[2][2][3][RANK_NB];
@@ -109,7 +109,7 @@ namespace {
     Bitboard ourPawns   = pos.pieces(  Us, PAWN);
     Bitboard theirPawns = pos.pieces(Them, PAWN);
 
-    e->passedPawns[Us]   = e->pawnAttacksSpan[Us] = 0;
+    e->passedPawns[Us] = e->pawnAttacksSpan[Us] = e->weakUnopposed[Us] = 0;
     e->semiopenFiles[Us] = 0xFF;
     e->kingSquares[Us]   = SQ_NONE;
     e->pawnAttacks[Us]   = shift<Right>(ourPawns) | shift<Left>(ourPawns);
@@ -177,10 +177,10 @@ namespace {
             score += Connected[opposed][!!phalanx][popcount(supported)][relative_rank(Us, s)];
 
         else if (!neighbours)
-            score -= Isolated[opposed];
+            score -= Isolated, e->weakUnopposed[Us] += !opposed;
 
         else if (backward)
-            score -= Backward[opposed];
+            score -= Backward, e->weakUnopposed[Us] += !opposed;
 
         if (doubled && !supported)
             score -= Doubled;
index 15b0b7768ab496f4e31d3c13f10ac7cb60abf2e3..1981529337c5627d3770ced65e98c213c7f69124 100644 (file)
@@ -37,6 +37,7 @@ struct Entry {
   Bitboard pawn_attacks(Color c) const { return pawnAttacks[c]; }
   Bitboard passed_pawns(Color c) const { return passedPawns[c]; }
   Bitboard pawn_attacks_span(Color c) const { return pawnAttacksSpan[c]; }
+  int weak_unopposed(Color c) const { return weakUnopposed[c]; }
   int pawn_asymmetry() const { return asymmetry; }
   int open_files() const { return openFiles; }
 
@@ -71,6 +72,7 @@ struct Entry {
   Bitboard pawnAttacksSpan[COLOR_NB];
   Square kingSquares[COLOR_NB];
   Score kingSafety[COLOR_NB];
+  int weakUnopposed[COLOR_NB];
   int castlingRights[COLOR_NB];
   int semiopenFiles[COLOR_NB];
   int pawnsOnSquares[COLOR_NB][COLOR_NB]; // [color][light/dark squares]
index d095aefeb6a6f875746a67ab68d782e32d031e28..eb360869b53380510513ff134938f0ba515e5cb8 100644 (file)
@@ -111,7 +111,7 @@ void Thread::idle_loop() {
 
 
 /// ThreadPool::init() creates and launches the threads that will go
-/// immediately to sleep in idle_loop. We cannot use the c'tor because
+/// immediately to sleep in idle_loop. We cannot use the constructor because
 /// Threads is a static object and we need a fully initialized engine at
 /// this point due to allocation of Endgames in the Thread constructor.