]> git.sesse.net Git - stockfish/blobdiff - src/evaluate.cpp
Code style at passed pawn eval
[stockfish] / src / evaluate.cpp
index daa911e682fefaa4d2753e2077e4b0837261b58d..ada15a1615a9c015ead4668ffb494460b46bc254 100644 (file)
@@ -114,16 +114,15 @@ namespace {
        S( 37, 28), S( 42, 31), S(44, 33) },
      { S(-22,-27), S( -8,-13), S( 6,  1), S(20, 15), S(34, 29), S(48, 43), // Bishops
        S( 60, 55), S( 68, 63), S(74, 68), S(77, 72), S(80, 75), S(82, 77),
-       S( 84, 79), S( 86, 81), S(87, 82), S(87, 82) },
+       S( 84, 79), S( 86, 81) },
      { S(-17,-33), S(-11,-16), S(-5,  0), S( 1, 16), S( 7, 32), S(13, 48), // Rooks
        S( 18, 64), S( 22, 80), S(26, 96), S(29,109), S(31,115), S(33,119),
-       S( 35,122), S( 36,123), S(37,124), S(38,124) },
+       S( 35,122), S( 36,123), S(37,124) },
      { S(-12,-20), S( -8,-13), S(-5, -7), S(-2, -1), S( 1,  5), S( 4, 11), // Queens
        S(  7, 17), S( 10, 23), S(13, 29), S(16, 34), S(18, 38), S(20, 40),
        S( 22, 41), S( 23, 41), S(24, 41), S(25, 41), S(25, 41), S(25, 41),
        S( 25, 41), S( 25, 41), S(25, 41), S(25, 41), S(25, 41), S(25, 41),
-       S( 25, 41), S( 25, 41), S(25, 41), S(25, 41), S(25, 41), S(25, 41),
-       S( 25, 41), S( 25, 41) }
+       S( 25, 41), S( 25, 41), S(25, 41), S(25, 41) }
   };
 
   // Outpost[PieceType][Square] contains bonuses of knights and bishops, indexed
@@ -173,6 +172,7 @@ namespace {
   const Score RookOpenFile     = make_score(43, 21);
   const Score RookSemiopenFile = make_score(19, 10);
   const Score BishopPawns      = make_score( 8, 12);
+  const Score MinorBehindPawn  = make_score(16,  0);
   const Score UndefendedMinor  = make_score(25, 10);
   const Score TrappedRook      = make_score(90,  0);
 
@@ -186,12 +186,8 @@ namespace {
   // based on how many squares inside this area are safe and available for
   // friendly minor pieces.
   const Bitboard SpaceMask[] = {
-    (1ULL << SQ_C2) | (1ULL << SQ_D2) | (1ULL << SQ_E2) | (1ULL << SQ_F2) |
-    (1ULL << SQ_C3) | (1ULL << SQ_D3) | (1ULL << SQ_E3) | (1ULL << SQ_F3) |
-    (1ULL << SQ_C4) | (1ULL << SQ_D4) | (1ULL << SQ_E4) | (1ULL << SQ_F4),
-    (1ULL << SQ_C7) | (1ULL << SQ_D7) | (1ULL << SQ_E7) | (1ULL << SQ_F7) |
-    (1ULL << SQ_C6) | (1ULL << SQ_D6) | (1ULL << SQ_E6) | (1ULL << SQ_F6) |
-    (1ULL << SQ_C5) | (1ULL << SQ_D5) | (1ULL << SQ_E5) | (1ULL << SQ_F5)
+    (FileCBB | FileDBB | FileEBB | FileFBB) & (Rank2BB | Rank3BB | Rank4BB),
+    (FileCBB | FileDBB | FileEBB | FileFBB) & (Rank7BB | Rank6BB | Rank5BB)
   };
 
   // King danger constants and variables. The king danger scores are taken
@@ -292,7 +288,7 @@ namespace Eval {
     const int MaxSlope = 30;
     const int Peak = 1280;
 
-    for (int t = 0, i = 1; i < 100; i++)
+    for (int t = 0, i = 1; i < 100; ++i)
     {
         t = std::min(Peak, std::min(int(0.4 * i * i), t + MaxSlope));
 
@@ -536,10 +532,10 @@ Value do_evaluate(const Position& pos, Value& margin) {
             if (!(pos.pieces(Them, PAWN) & pawn_attack_span(Us, s)))
                 score += evaluate_outposts<Piece, Us>(pos, ei, s);
 
-            // Pawn in front of knight/bishop
+            // Bishop or knight behind a pawn
             if (    relative_rank(Us, s) < RANK_5
                 && (pos.pieces(PAWN) & (s + pawn_push(Us))))
-                score += make_score(16, 0);
+                score += MinorBehindPawn;
         }
 
         if (  (Piece == ROOK || Piece == QUEEN)
@@ -626,11 +622,11 @@ Value do_evaluate(const Position& pos, Value& margin) {
     // type of attacking piece, from knights to queens. Kings are not
     // considered because are already handled in king evaluation.
     if (weakEnemies)
-        for (PieceType pt1 = KNIGHT; pt1 < KING; pt1++)
+        for (PieceType pt1 = KNIGHT; pt1 < KING; ++pt1)
         {
             b = ei.attackedBy[Us][pt1] & weakEnemies;
             if (b)
-                for (PieceType pt2 = PAWN; pt2 < KING; pt2++)
+                for (PieceType pt2 = PAWN; pt2 < KING; ++pt2)
                     if (b & pos.pieces(pt2))
                         score += Threat[pt1][pt2];
         }
@@ -814,18 +810,17 @@ Value do_evaluate(const Position& pos, Value& margin) {
             Square blockSq = s + pawn_push(Us);
 
             // Adjust bonus based on kings proximity
-            ebonus += Value(square_distance(pos.king_square(Them), blockSq) * 5 * rr);
-            ebonus -= Value(square_distance(pos.king_square(Us), blockSq) * 2 * rr);
+            ebonus +=  Value(square_distance(pos.king_square(Them), blockSq) * 5 * rr)
+                     - Value(square_distance(pos.king_square(Us  ), blockSq) * 2 * rr);
 
             // If blockSq is not the queening square then consider also a second push
-            if (rank_of(blockSq) != (Us == WHITE ? RANK_8 : RANK_1))
+            if (relative_rank(Us, blockSq) != RANK_8)
                 ebonus -= Value(square_distance(pos.king_square(Us), blockSq + pawn_push(Us)) * rr);
 
             // If the pawn is free to advance, increase bonus
             if (pos.is_empty(blockSq))
             {
                 squaresToQueen = forward_bb(Us, s);
-                defendedSquares = squaresToQueen & ei.attackedBy[Us][ALL_PIECES];
 
                 // If there is an enemy rook or queen attacking the pawn from behind,
                 // add all X-ray attacks by the rook or queen. Otherwise consider only
@@ -836,6 +831,12 @@ Value do_evaluate(const Position& pos, Value& margin) {
                 else
                     unsafeSquares = squaresToQueen & (ei.attackedBy[Them][ALL_PIECES] | pos.pieces(Them));
 
+                if (    unlikely(forward_bb(Them, s) & pos.pieces(Us, ROOK, QUEEN))
+                    && (forward_bb(Them, s) & pos.pieces(Us, ROOK, QUEEN) & pos.attacks_from<ROOK>(s)))
+                    defendedSquares = squaresToQueen;
+                else
+                    defendedSquares = squaresToQueen & ei.attackedBy[Us][ALL_PIECES];
+
                 // If there aren't enemy attacks huge bonus, a bit smaller if at
                 // least block square is not attacked, otherwise smallest bonus.
                 int k = !unsafeSquares ? 15 : !(unsafeSquares & blockSq) ? 9 : 3;
@@ -871,9 +872,16 @@ Value do_evaluate(const Position& pos, Value& margin) {
         {
             if (pos.non_pawn_material(Them) <= KnightValueMg)
                 ebonus += ebonus / 4;
+
             else if (pos.pieces(Them, ROOK, QUEEN))
                 ebonus -= ebonus / 4;
         }
+
+        // Increase the bonus if we have more non-pawn pieces
+        if (pos.count<ALL_PIECES>(  Us) - pos.count<PAWN>(  Us) >
+            pos.count<ALL_PIECES>(Them) - pos.count<PAWN>(Them))
+            ebonus += ebonus / 4;
+
         score += make_score(mbonus, ebonus);
 
     }
@@ -900,7 +908,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
 
     // Step 1. Hunt for unstoppable passed pawns. If we find at least one,
     // record how many plies are required for promotion.
-    for (c = WHITE; c <= BLACK; c++)
+    for (c = WHITE; c <= BLACK; ++c)
     {
         // Skip if other side has non-pawn pieces
         if (pos.non_pawn_material(~c))
@@ -1001,19 +1009,19 @@ Value do_evaluate(const Position& pos, Value& margin) {
             {
                 b2 = supporters & in_front_bb(winnerSide, rank_of(blockSq + pawn_push(winnerSide)));
 
-                while (b2) // This while-loop could be replaced with LSB/MSB (depending on color)
+                if (b2)
                 {
-                    d = square_distance(blockSq, pop_lsb(&b2)) - 2;
+                    d = square_distance(blockSq, backmost_sq(winnerSide, b2)) - 2;
                     movesToGo = std::min(movesToGo, d);
                 }
             }
 
             // Check pawns that can be sacrificed against the blocking pawn
-            b2 = pawn_attack_span(winnerSide, blockSq) & candidates & ~(1ULL << s);
+            b2 = pawn_attack_span(winnerSide, blockSq) & candidates & ~SquareBB[s];
 
-            while (b2) // This while-loop could be replaced with LSB/MSB (depending on color)
+            if (b2)
             {
-                d = square_distance(blockSq, pop_lsb(&b2)) - 2;
+                d = square_distance(blockSq, backmost_sq(winnerSide, b2)) - 2;
                 movesToGo = std::min(movesToGo, d);
             }
 
@@ -1032,12 +1040,8 @@ Value do_evaluate(const Position& pos, Value& margin) {
             kingptg = (minKingDist + blockersCount) * 2;
         }
 
-        // Check if pawn sacrifice plan _may_ save the day
-        if (pliesToQueen[winnerSide] + 3 > pliesToGo + sacptg)
-            return SCORE_ZERO;
-
-        // Check if king capture plan _may_ save the day (contains some false positives)
-        if (pliesToQueen[winnerSide] + 3 > pliesToGo + kingptg)
+        // Check if pawn sacrifice or king capture plan _may_ save the day
+        if (pliesToQueen[winnerSide] + 3 > pliesToGo + std::min(kingptg, sacptg))
             return SCORE_ZERO;
     }
 
@@ -1088,9 +1092,9 @@ Value do_evaluate(const Position& pos, Value& margin) {
     assert(eg_value(v) > -VALUE_INFINITE && eg_value(v) < VALUE_INFINITE);
     assert(ph >= PHASE_ENDGAME && ph <= PHASE_MIDGAME);
 
-    int ev = (eg_value(v) * int(sf)) / SCALE_FACTOR_NORMAL;
-    int result = (mg_value(v) * int(ph) + ev * int(128 - ph)) / 128;
-    return Value((result / GrainSize) * GrainSize); // Sign independent
+    int e = (eg_value(v) * int(sf)) / SCALE_FACTOR_NORMAL;
+    int r = (mg_value(v) * int(ph) + e * int(PHASE_MIDGAME - ph)) / PHASE_MIDGAME;
+    return Value((r / GrainSize) * GrainSize); // Sign independent
   }
 
   // apply_weight() weights score v by score w trying to prevent overflow