Introduce scale factor in pawn evaluation
authorMarco Costalba <mcostalba@gmail.com>
Sun, 18 Apr 2010 09:25:59 +0000 (10:25 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Mon, 19 Apr 2010 05:21:13 +0000 (06:21 +0100)
The idea is to reduce the score if we have many
pawns opposing an enemy pawn so that the draw
possibility increases.

Just introduced the logic, but no functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/evaluate.cpp
src/material.cpp
src/pawns.cpp
src/pawns.h
src/scale.h

index 9bb6c1c00516446bde294b38da18443c39da25d3..5f86227c2c5e9718e4ec76a967638167054ebff0 100644 (file)
@@ -430,6 +430,13 @@ Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) {
           factor[BLACK] = sf;
   }
 
+  // If we don't already have an unusual scale factor, use pawn
+  // evaluation ones.
+  if (factor[WHITE] == SCALE_FACTOR_NORMAL)
+      factor[WHITE] = ei.pi->scale_factor(WHITE);
+  if (factor[BLACK] == SCALE_FACTOR_NORMAL)
+      factor[BLACK] = ei.pi->scale_factor(BLACK);
+
   // Interpolate between the middle game and the endgame score
   Color stm = pos.side_to_move();
 
index 65c8c86292df1c2e12bac5336f01f8820337ce4a..f0ee5f682d02cada44957745849684613f3e4196 100644 (file)
@@ -304,7 +304,7 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) {
     {
         if (   pos.non_pawn_material(c) == pos.non_pawn_material(opposite_color(c))
             || pos.non_pawn_material(c) < RookValueMidgame)
-            mi->factor[c] = 0;
+            mi->factor[c] = SCALE_FACTOR_ZERO;
         else
         {
             switch (pos.piece_count(c, BISHOP)) {
index df7a0a2d3c507a1215b281b0a2ca6e4e4853c602..b381b5c4abc3f567cec33c1b7a68964c70e65adf 100644 (file)
@@ -70,6 +70,13 @@ namespace {
     S(34,68), S(83,166), S(0, 0), S( 0, 0)
   };
 
+  // UnpairedPawnsTable[] gives a score according to the number
+  // of panws that do not have an enemy pawn in front of them.
+  const int UnpairedPawnsTable[8] = {
+    SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL,
+    SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL
+  };
+
   // Pawn storm tables for positions with opposite castling
   const int QStormTable[64] = {
     0,  0,  0,  0, 0, 0, 0, 0,
@@ -187,6 +194,7 @@ Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
   int bonus;
   Score value = make_score(0, 0);
   const Square* ptr = pos.piece_list_begin(Us, PAWN);
+  int unpairedPawnsNum = pos.piece_count(Us, PAWN);
 
   // Initialize pawn storm scores by giving bonuses for open files
   for (f = FILE_A; f <= FILE_H; f++)
@@ -211,6 +219,10 @@ Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
       doubled  = ourPawns & squares_behind(Us, s);
       opposed  = theirPawns & squares_in_front_of(Us, s);
 
+      // Decrease number of unpaired pawns
+      if (opposed)
+          unpairedPawnsNum--;
+
       // We calculate kingside and queenside pawn storm
       // scores for both colors. These are used when evaluating
       // middle game positions with opposite side castling.
@@ -337,6 +349,9 @@ Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
           value += CandidateBonus[relative_rank(Us, s)];
   }
 
+  // Calculate a scale factor to be used to evaluate if position is drawish
+  pi->factor[Us] = UnpairedPawnsTable[unpairedPawnsNum];
+
   return value;
 }
 
index 2dc866848aa0cc3adb210ec24ef528caa7fdcc7f..5939253b5da7b0c9adc38e4eb89ec39ec16daeb0 100644 (file)
@@ -26,6 +26,7 @@
 ////
 
 #include "bitboard.h"
+#include "scale.h"
 #include "value.h"
 
 ////
@@ -52,6 +53,7 @@ public:
   Value queenside_storm_value(Color c) const;
   Bitboard pawn_attacks(Color c) const;
   Bitboard passed_pawns() const;
+  ScaleFactor scale_factor(Color c) const;
   int file_is_half_open(Color c, File f) const;
   int has_open_file_to_left(Color c, File f) const;
   int has_open_file_to_right(Color c, File f) const;
@@ -67,8 +69,7 @@ private:
   Square kingSquares[2];
   Score value;
   int16_t ksStormValue[2], qsStormValue[2];
-  uint8_t halfOpenFiles[2];
-  uint8_t kingShelters[2];
+  uint8_t halfOpenFiles[2], kingShelters[2], factor[2];
 };
 
 /// The PawnInfoTable class represents a pawn hash table.  It is basically
@@ -116,6 +117,10 @@ inline Value PawnInfo::queenside_storm_value(Color c) const {
   return Value(qsStormValue[c]);
 }
 
+inline ScaleFactor PawnInfo::scale_factor(Color c) const {
+  return ScaleFactor(factor[c]);
+}
+
 inline int PawnInfo::file_is_half_open(Color c, File f) const {
   return (halfOpenFiles[c] & (1 << int(f)));
 }
index a02cc764eaf6f10f7aa67689491f16a9d5cde137..bcf37dd4b406ce93bf8fbcb0abf133bcf93409a5 100644 (file)
 ////
 
 enum ScaleFactor {
-  SCALE_FACTOR_ZERO = 0,
+  SCALE_FACTOR_ZERO   = 0,
   SCALE_FACTOR_NORMAL = 64,
-  SCALE_FACTOR_MAX = 128,
-  SCALE_FACTOR_NONE = 255
+  SCALE_FACTOR_MAX    = 128,
+  SCALE_FACTOR_NONE   = 255
 };