]> git.sesse.net Git - stockfish/blobdiff - src/evaluate.cpp
Convert ThreatBonus to Score
[stockfish] / src / evaluate.cpp
index e84cf44ecba19151c58e9c8e71a041928e5a561c..ea2425ef0fddebbe77da1fc145018c2df8dc9234 100644 (file)
@@ -72,76 +72,48 @@ namespace {
   //
   // Visually better to define tables constants
   typedef Value V;
+  typedef Score S;
 
   // Knight mobility bonus in middle game and endgame, indexed by the number
   // of attacked squares not occupied by friendly piecess.
-  const Value MidgameKnightMobilityBonus[] = {
-  //    0       1      2     3      4      5      6      7      8
-    V(-38), V(-25),V(-12), V(0), V(12), V(25), V(31), V(38), V(38)
-  };
-
-  const Value EndgameKnightMobilityBonus[] = {
-  //    0       1      2     3      4      5      6      7      8
-    V(-33), V(-23),V(-13), V(-3), V(7), V(17), V(22), V(27), V(27)
+  const Score KnightMobilityBonus[] = {
+    S(-38,-33), S(-25,-23), S(-12,-13), S( 0,-3),
+    S( 12,  7), S( 25, 17), S( 31, 22), S(38, 27), S(38, 27)
   };
 
   // Bishop mobility bonus in middle game and endgame, indexed by the number
   // of attacked squares not occupied by friendly pieces. X-ray attacks through
   // queens are also included.
-  const Value MidgameBishopMobilityBonus[] = {
-  //    0       1      2      3      4      5      6      7
-    V(-25), V(-11),  V(3), V(17), V(31), V(45), V(57), V(65),
-  //    8       9     10     11     12     13     14     15
-    V( 71), V( 74), V(76), V(78), V(79), V(80), V(81), V(81)
-  };
-
-  const Value EndgameBishopMobilityBonus[] = {
-  //    0       1      2      3      4      5      6      7
-    V(-30), V(-16), V(-2), V(12), V(26), V(40), V(52), V(60),
-  //    8       9     10     11     12     13     14     15
-    V( 65), V( 69), V(71), V(73), V(74), V(75), V(76), V(76)
+  const Score BishopMobilityBonus[] = {
+    S(-25,-30), S(-11,-16), S( 3, -2), S(17, 12),
+    S( 31, 26), S( 45, 40), S(57, 52), S(65, 60),
+    S( 71, 65), S( 74, 69), S(76, 71), S(78, 73),
+    S( 79, 74), S( 80, 75), S(81, 76), S(81, 76)
   };
 
   // Rook mobility bonus in middle game and endgame, indexed by the number
   // of attacked squares not occupied by friendly pieces. X-ray attacks through
   // queens and rooks are also included.
-  const Value MidgameRookMobilityBonus[] = {
-  //    0       1      2      3      4      5      6      7
-    V(-20), V(-14), V(-8), V(-2),  V(4), V(10), V(14), V(19),
-  //    8       9     10     11     12     13     14     15
-    V( 23), V( 26), V(27), V(28), V(29), V(30), V(31), V(32)
-  };
-
-  const Value EndgameRookMobilityBonus[] = {
-  //    0       1      2      3      4      5      6      7
-    V(-36), V(-19), V(-3), V(13), V(29), V(46), V(62), V(79),
-  //    8       9     10     11     12     13     14     15
-    V( 95), V(106),V(111),V(114),V(116),V(117),V(118),V(118)
+  const Score RookMobilityBonus[] = {
+    S(-20,-36), S(-14,-19), S(-8, -3), S(-2, 13),
+    S(  4, 29), S( 10, 46), S(14, 62), S(19, 79),
+    S( 23, 95), S( 26,106), S(27,111), S(28,114),
+    S( 29,116), S( 30,117), S(31,118), S(32,118)
   };
 
   // Queen mobility bonus in middle game and endgame, indexed by the number
   // of attacked squares not occupied by friendly pieces.
-  const Value MidgameQueenMobilityBonus[] = {
-  //    0      1      2      3      4      5      6      7
-    V(-10), V(-8), V(-6), V(-3), V(-1), V( 1), V( 3), V( 5),
-  //    8      9     10     11     12     13     14     15
-    V(  8), V(10), V(12), V(15), V(16), V(17), V(18), V(20),
-  //   16     17     18     19     20     21     22     23
-    V( 20), V(20), V(20), V(20), V(20), V(20), V(20), V(20),
-  //   24     25     26     27     28     29     30     31
-    V( 20), V(20), V(20), V(20), V(20), V(20), V(20), V(20)
+  const Score QueenMobilityBonus[] = {
+    S(-10,-18), S(-8,-13), S(-6, -7), S(-3, -2), S(-1,  3), S( 1,  8),
+    S(  3, 13), S( 5, 19), S( 8, 23), S(10, 27), S(12, 32), S(15, 34),
+    S( 16, 35), S(17, 35), S(18, 35), S(20, 35), S(20, 35), S(20, 35),
+    S( 20, 35), S(20, 35), S(20, 35), S(20, 35), S(20, 35), S(20, 35),
+    S( 20, 35), S(20, 35), S(20, 35), S(20, 35), S(20, 35), S(20, 35),
+    S( 20, 35), S(20, 35)
   };
 
-  const Value EndgameQueenMobilityBonus[] = {
-  //    0      1      2      3      4      5      6      7
-    V(-18),V(-13), V(-7), V(-2), V( 3), V (8), V(13), V(19),
-  //    8      9     10     11     12     13     14     15
-    V( 23), V(27), V(32), V(34), V(35), V(35), V(35), V(35),
-  //   16     17     18     19     20     21     22     23
-    V( 35), V(35), V(35), V(35), V(35), V(35), V(35), V(35),
-  //   24     25     26     27     28     29     30     31
-    V( 35), V(35), V(35), V(35), V(35), V(35), V(35), V(35)
-  };
+  // Pointers table to access mobility tables through piece type
+  const Score* MobilityBonus[] = { 0, 0, KnightMobilityBonus, BishopMobilityBonus, RookMobilityBonus, QueenMobilityBonus };
 
   // Outpost bonuses for knights and bishops, indexed by square (from white's
   // point of view).
@@ -173,10 +145,8 @@ namespace {
   const Value UnstoppablePawnValue = Value(0x500);
 
   // Rooks and queens on the 7th rank (modified by Joona Kiiski)
-  const Value MidgameRookOn7thBonus  = Value(47);
-  const Value EndgameRookOn7thBonus  = Value(98);
-  const Value MidgameQueenOn7thBonus = Value(27);
-  const Value EndgameQueenOn7thBonus = Value(54);
+  const Score RookOn7thBonus  = Score(47, 98);
+  const Score QueenOn7thBonus = Score(27, 54);
 
   // Rooks on open files (modified by Joona Kiiski)
   const Value RookOpenFileBonus = Value(43);
@@ -225,12 +195,14 @@ namespace {
   /// the strength of the attack are added up into an integer, which is used
   /// as an index to SafetyTable[].
 
-  // Attack weights for each piece type
+  // Attack weights for each piece type and table indexed on piece type
   const int QueenAttackWeight  = 5;
   const int RookAttackWeight   = 3;
   const int BishopAttackWeight = 2;
   const int KnightAttackWeight = 2;
 
+  const int AttackWeight[] = { 0, 0, KnightAttackWeight, BishopAttackWeight, RookAttackWeight, QueenAttackWeight };
+
   // Bonuses for safe checks, initialized from UCI options
   int QueenContactCheckBonus, DiscoveredCheckBonus;
   int QueenCheckBonus, RookCheckBonus, BishopCheckBonus, KnightCheckBonus;
@@ -243,26 +215,17 @@ namespace {
 
   // ThreatBonus[][] contains bonus according to which piece type
   // attacks which one.
-  const Value MidgameThreatBonus[8][8] = {
-      { V(0), V(0), V(0), V(0),  V(0),  V(0), V(0), V(0) }, // not used
-      { V(0),V(18), V(0),V(37), V(55), V(55), V(0), V(0) }, // KNIGHT attacks
-      { V(0),V(18),V(37), V(0), V(55), V(55), V(0), V(0) }, // BISHOP attacks
-      { V(0), V(9),V(27),V(27),  V(0), V(37), V(0), V(0) }, // ROOK attacks
-      { V(0),V(27),V(27),V(27), V(27),  V(0), V(0), V(0) }, // QUEEN attacks
-      { V(0), V(0), V(0), V(0),  V(0),  V(0), V(0), V(0) }, // not used
-      { V(0), V(0), V(0), V(0),  V(0),  V(0), V(0), V(0) }, // not used
-      { V(0), V(0), V(0), V(0),  V(0),  V(0), V(0), V(0) }  // not used
-  };
-
-  const Value EndgameThreatBonus[8][8] = {
-      { V(0), V(0), V(0), V(0),  V(0),  V(0), V(0), V(0) }, // not used
-      { V(0),V(37), V(0),V(47), V(97), V(97), V(0), V(0) }, // KNIGHT attacks
-      { V(0),V(37),V(47), V(0), V(97), V(97), V(0), V(0) }, // BISHOP attacks
-      { V(0),V(27),V(47),V(47),  V(0), V(47), V(0), V(0) }, // ROOK attacks
-      { V(0),V(37),V(37),V(37), V(37),  V(0), V(0), V(0) }, // QUEEN attacks
-      { V(0), V(0), V(0), V(0),  V(0),  V(0), V(0), V(0) }, // not used
-      { V(0), V(0), V(0), V(0),  V(0),  V(0), V(0), V(0) }, // not used
-      { V(0), V(0), V(0), V(0),  V(0),  V(0), V(0), V(0) }  // not used
+  const Score ThreatBonus[8][8] = {
+  #define Z Score(0, 0)
+      { Z, Z, Z, Z, Z, Z, Z, Z }, // not used
+      { Z, S(18,37),       Z, S(37,47), S(55,97), S(55,97), Z, Z }, // KNIGHT attacks
+      { Z, S(18,37), S(37,47),       Z, S(55,97), S(55,97), Z, Z }, // BISHOP attacks
+      { Z, S( 9,27), S(27,47), S(27,47),       Z, S(37,47), Z, Z }, // ROOK attacks
+      { Z, S(27,37), S(27,37), S(27,37), S(27,37),       Z, Z, Z }, // QUEEN attacks
+      { Z, Z, Z, Z, Z, Z, Z, Z }, // not used
+      { Z, Z, Z, Z, Z, Z, Z, Z }, // not used
+      { Z, Z, Z, Z, Z, Z, Z, Z }  // not used
+  #undef Z
   };
 
   // ThreatedByPawnPenalty[] contains a penalty according to which piece
@@ -319,7 +282,6 @@ namespace {
   void evaluate_passed_pawns(const Position& pos, EvalInfo& ei);
   void evaluate_trapped_bishop_a7h7(const Position& pos, Square s, Color us, EvalInfo& ei);
   void evaluate_trapped_bishop_a1h1(const Position& pos, Square s, Color us, EvalInfo& ei);
-  inline Value apply_weight(Value v, int w);
   inline Score apply_weight(Score v, int wmg, int weg);
   Value scale_by_game_phase(const Score& v, Phase ph, const ScaleFactor sf[]);
   int weight_option(const std::string& opt, int weight);
@@ -436,7 +398,7 @@ Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) {
   }
 
   // Mobility
-  ei.value += apply_weight(Score(ei.mgMobility, ei.egMobility), WeightMobilityMidgame, WeightMobilityEndgame);
+  ei.value += apply_weight(ei.mobility, WeightMobilityMidgame, WeightMobilityEndgame);
 
   // If we don't already have an unusual scale factor, check for opposite
   // colored bishop endgames, and use a lower scale for those
@@ -568,9 +530,6 @@ namespace {
   int evaluate_mobility(Bitboard b, Bitboard mob_area, EvalInfo& ei) {
 
     const Color Them = (Us == WHITE ? BLACK : WHITE);
-    static const int AttackWeight[] = { 0, 0, KnightAttackWeight, BishopAttackWeight, RookAttackWeight, QueenAttackWeight };
-    static const Value* MgBonus[] = { 0, 0, MidgameKnightMobilityBonus, MidgameBishopMobilityBonus, MidgameRookMobilityBonus, MidgameQueenMobilityBonus };
-    static const Value* EgBonus[] = { 0, 0, EndgameKnightMobilityBonus, EndgameBishopMobilityBonus, EndgameRookMobilityBonus, EndgameQueenMobilityBonus };
 
     // Update attack info
     ei.attackedBy[Us][Piece] |= b;
@@ -589,8 +548,7 @@ namespace {
     int mob = (Piece != QUEEN ? count_1s_max_15<HasPopCnt>(b & mob_area)
                               : count_1s<HasPopCnt>(b & mob_area));
 
-    ei.mgMobility += Sign[Us] * MgBonus[Piece][mob];
-    ei.egMobility += Sign[Us] * EgBonus[Piece][mob];
+    ei.mobility += Sign[Us] * MobilityBonus[Piece][mob];
     return mob;
   }
 
@@ -676,8 +634,7 @@ namespace {
             if (   relative_rank(Us, s) == RANK_7
                 && relative_rank(Us, pos.king_square(Them)) == RANK_8)
             {
-                ei.value += Sign[Us] * (Piece == ROOK ? Score(MidgameRookOn7thBonus, EndgameRookOn7thBonus)
-                                                      : Score(MidgameQueenOn7thBonus, EndgameQueenOn7thBonus));
+                ei.value += Sign[Us] * (Piece == ROOK ? RookOn7thBonus : QueenOn7thBonus);
             }
         }
 
@@ -751,7 +708,7 @@ namespace {
         if (b)
             for (PieceType pt2 = PAWN; pt2 < KING; pt2++)
                 if (b & pos.pieces(pt2))
-                    bonus += Score(MidgameThreatBonus[pt1][pt2], EndgameThreatBonus[pt1][pt2]);
+                    bonus += ThreatBonus[pt1][pt2];
     }
     ei.value += Sign[Us] * bonus;
   }
@@ -935,12 +892,12 @@ namespace {
       // that the king safety scores can sometimes be very big, and that
       // capturing a single attacking piece can therefore result in a score
       // change far bigger than the value of the captured piece.
-      Value v = apply_weight(SafetyTable[attackUnits], WeightKingSafety[Us]);
+      Score v = apply_weight(Score(SafetyTable[attackUnits], 0), WeightKingSafety[Us], 0);
 
-      ei.value -= Sign[Us] * Score(v, 0);
+      ei.value -= Sign[Us] * v;
 
       if (Us == pos.side_to_move())
-          ei.futilityMargin += v;
+          ei.futilityMargin += v.mg();
     }
   }
 
@@ -1068,8 +1025,7 @@ namespace {
         }
 
         // Add the scores for this pawn to the middle game and endgame eval.
-        ei.value += Score(apply_weight(Sign[Us] * mbonus, WeightPassedPawnsMidgame),
-                          apply_weight(Sign[Us] * ebonus, WeightPassedPawnsEndgame));
+        ei.value += Sign[Us] * apply_weight(Score(mbonus, ebonus), WeightPassedPawnsMidgame, WeightPassedPawnsEndgame);
 
     } // while
   }
@@ -1229,18 +1185,14 @@ namespace {
     int space =  count_1s_max_15<HasPopCnt>(safeSquares)
                + count_1s_max_15<HasPopCnt>(behindFriendlyPawns & safeSquares);
 
-    ei.value += Sign[Us] * Score(apply_weight(Value(space * ei.mi->space_weight()), WeightSpace), 0);
+    ei.value += Sign[Us] * apply_weight(Score(space * ei.mi->space_weight(), 0), WeightSpace, 0);
   }
 
 
   // apply_weight() applies an evaluation weight to a value
 
-  inline Value apply_weight(Value v, int w) {
-    return (v*w) / 0x100;
-  }
-
   inline Score apply_weight(Score v, int wmg, int weg) {
-      return Score(v.mg()*wmg, v.eg()*weg) / 0x100;
+      return Score(v.mg() * wmg, v.eg() * weg) / 0x100;
   }