]> git.sesse.net Git - stockfish/blobdiff - src/evaluate.cpp
Lazy SMP
[stockfish] / src / evaluate.cpp
index 8fd405d0036fe9e41c7632b2fa108bdf77a8db25..bbca9964f4337d9506c23d0d49353af9f0e2e9d3 100644 (file)
@@ -220,9 +220,8 @@ namespace {
 
   // Penalties for enemy's safe checks
   const int QueenContactCheck = 89;
-  const int RookContactCheck  = 71;
   const int QueenCheck        = 50;
-  const int RookCheck         = 37;
+  const int RookCheck         = 45;
   const int BishopCheck       = 6;
   const int KnightCheck       = 14;
 
@@ -421,23 +420,6 @@ namespace {
                 attackUnits += QueenContactCheck * popcount<Max15>(b);
         }
 
-        // Analyse the enemy's safe rook contact checks. Firstly, find the
-        // undefended squares around the king reachable by the enemy rooks...
-        b = undefended & ei.attackedBy[Them][ROOK] & ~pos.pieces(Them);
-
-        // Consider only squares where the enemy's rook gives check
-        b &= PseudoAttacks[ROOK][ksq];
-
-        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]);
-
-            if (b)
-                attackUnits += RookContactCheck * popcount<Max15>(b);
-        }
-
         // Analyse the enemy's safe distance checks for sliders and knights
         safe = ~(ei.attackedBy[Us][ALL_PIECES] | pos.pieces(Them));
 
@@ -704,6 +686,27 @@ namespace {
     return make_score(bonus * weight * weight, 0);
   }
 
+
+  // evaluate_initiative() computes the initiative correction value for the position, i.e. 
+  // second order bonus/malus based on the known attacking/defending status of the players. 
+  Score evaluate_initiative(const Position& pos, const EvalInfo& ei, const Score positional_score) {
+
+    int pawns           =  pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK);
+    int king_separation =  distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
+    int asymmetry       =  ei.pi->pawn_asymmetry();
+
+    // Compute the initiative bonus for the attacking side
+    int attacker_bonus =   8 * (pawns + asymmetry + king_separation) - 120;
+
+    // Now apply the bonus: note that we find the attacking side by extracting the sign 
+    // of the endgame value of "positional_score", and that we carefully cap the bonus so
+    // that the endgame score with the correction will never be divided by more than two.
+    int eg = eg_value(positional_score);
+    int value = ((eg > 0) - (eg < 0)) * std::max( attacker_bonus , -abs( eg / 2 ) );
+
+    return make_score( 0 , value ) ; 
+  }
+
 } // namespace
 
 
@@ -785,6 +788,9 @@ Value Eval::evaluate(const Position& pos) {
   // Evaluate space for both sides, only during opening
   if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 12222)
       score += (evaluate_space<WHITE>(pos, ei) - evaluate_space<BLACK>(pos, ei)) * Weights[Space];
+  
+  // Evaluate initiative
+  score += evaluate_initiative(pos, ei, score);
 
   // Scale winning side if position is more drawish than it appears
   Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK;
@@ -816,11 +822,6 @@ Value Eval::evaluate(const Position& pos) {
           sf = ei.pi->pawn_span(strongSide) ? ScaleFactor(51) : ScaleFactor(37);
   }
 
-  // Scale endgame by number of pawns
-  int p = pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK);
-  int v_eg = 1 + abs(int(eg_value(score)));
-  sf = ScaleFactor(std::max(sf / 2, sf - 8 * SCALE_FACTOR_NORMAL * (12 - p) / v_eg));
-
   // Interpolate between a middlegame and a (scaled by 'sf') endgame score
   Value v =  mg_value(score) * int(me->game_phase())
            + eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;