Introduce namespace Material
authorMarco Costalba <mcostalba@gmail.com>
Sun, 16 Dec 2012 11:00:54 +0000 (12:00 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 16 Dec 2012 11:58:39 +0000 (12:58 +0100)
And retire old struct MaterialTable simplifying the code.

No functional change.

src/evaluate.cpp
src/material.cpp
src/material.h
src/position.cpp
src/search.cpp
src/thread.h

index f27c04ec834ae4ef3b870b6a56739382b556ad2f..4765094a2c4c237d95afee9459e743bc60cd4bcc 100644 (file)
@@ -36,7 +36,7 @@ namespace {
   struct EvalInfo {
 
     // Pointers to material and pawn hash table entries
-    MaterialEntry* mi;
+    Material::Entry* mi;
     PawnEntry* pi;
 
     // attackedBy[color][piece type] is a bitboard representing all squares
@@ -367,7 +367,8 @@ Value do_evaluate(const Position& pos, Value& margin) {
   Score score, mobilityWhite, mobilityBlack;
 
   Key key = pos.key();
-  Eval::Entry* e = pos.this_thread()->evalTable[key];
+  Thread* th = pos.this_thread();
+  Eval::Entry* e = th->evalTable[key];
 
   // If e->key matches the position's hash key, it means that we have analysed
   // this node before, and we can simply return the information we found the last
@@ -391,7 +392,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
   score = pos.psq_score() + (pos.side_to_move() == WHITE ? Tempo : -Tempo);
 
   // Probe the material hash table
-  ei.mi = pos.this_thread()->materialTable.probe(pos);
+  ei.mi = Material::probe(pos, th->materialTable, th->endgames);
   score += ei.mi->material_value();
 
   // If we have a specialized evaluation function for the current material
index 073bef81d98e968da6f2bc8e38635a1bdc5df9a3..72240867372b25977d7ab290948053cc96521e28 100644 (file)
@@ -17,7 +17,7 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <algorithm>
+#include <algorithm>  // For std::min
 #include <cassert>
 #include <cstring>
 
@@ -81,18 +81,54 @@ namespace {
           && pos.piece_count(Them, PAWN)  >= 1;
   }
 
+  /// imbalance() calculates imbalance comparing piece count of each
+  /// piece type for both colors.
+
+  template<Color Us>
+  int imbalance(const int pieceCount[][PIECE_TYPE_NB]) {
+
+    const Color Them = (Us == WHITE ? BLACK : WHITE);
+
+    int pt1, pt2, pc, v;
+    int value = 0;
+
+    // Redundancy of major pieces, formula based on Kaufman's paper
+    // "The Evaluation of Material Imbalances in Chess"
+    if (pieceCount[Us][ROOK] > 0)
+        value -=  RedundantRookPenalty * (pieceCount[Us][ROOK] - 1)
+                + RedundantQueenPenalty * pieceCount[Us][QUEEN];
+
+    // Second-degree polynomial material imbalance by Tord Romstad
+    for (pt1 = NO_PIECE_TYPE; pt1 <= QUEEN; pt1++)
+    {
+        pc = pieceCount[Us][pt1];
+        if (!pc)
+            continue;
+
+        v = LinearCoefficients[pt1];
+
+        for (pt2 = NO_PIECE_TYPE; pt2 <= pt1; pt2++)
+            v +=  QuadraticCoefficientsSameColor[pt1][pt2] * pieceCount[Us][pt2]
+                + QuadraticCoefficientsOppositeColor[pt1][pt2] * pieceCount[Them][pt2];
+
+        value += pc * v;
+    }
+    return value;
+  }
+
 } // namespace
 
+namespace Material {
 
-/// MaterialTable::probe() takes a position object as input, looks up a MaterialEntry
+/// Material::probe() takes a position object as input, looks up a MaterialEntry
 /// object, and returns a pointer to it. If the material configuration is not
 /// already present in the table, it is computed and stored there, so we don't
 /// have to recompute everything when the same material configuration occurs again.
 
-MaterialEntry* MaterialTable::probe(const Position& pos) {
+Entry* probe(const Position& pos, Table& entries, Endgames& endgames) {
 
   Key key = pos.material_key();
-  MaterialEntry* e = entries[key];
+  Entry* e = entries[key];
 
   // If e->key matches the position's material hash key, it means that we
   // have analysed this material configuration before, and we can simply
@@ -100,10 +136,10 @@ MaterialEntry* MaterialTable::probe(const Position& pos) {
   if (e->key == key)
       return e;
 
-  memset(e, 0, sizeof(MaterialEntry));
+  memset(e, 0, sizeof(Entry));
   e->key = key;
   e->factor[WHITE] = e->factor[BLACK] = (uint8_t)SCALE_FACTOR_NORMAL;
-  e->gamePhase = MaterialTable::game_phase(pos);
+  e->gamePhase = game_phase(pos);
 
   // Let's look if we have a specialized evaluation function for this
   // particular material configuration. First we look for a fixed
@@ -226,47 +262,11 @@ MaterialEntry* MaterialTable::probe(const Position& pos) {
 }
 
 
-/// MaterialTable::imbalance() calculates imbalance comparing piece count of each
-/// piece type for both colors.
-
-template<Color Us>
-int MaterialTable::imbalance(const int pieceCount[][PIECE_TYPE_NB]) {
-
-  const Color Them = (Us == WHITE ? BLACK : WHITE);
-
-  int pt1, pt2, pc, v;
-  int value = 0;
-
-  // Redundancy of major pieces, formula based on Kaufman's paper
-  // "The Evaluation of Material Imbalances in Chess"
-  if (pieceCount[Us][ROOK] > 0)
-      value -=  RedundantRookPenalty * (pieceCount[Us][ROOK] - 1)
-              + RedundantQueenPenalty * pieceCount[Us][QUEEN];
-
-  // Second-degree polynomial material imbalance by Tord Romstad
-  for (pt1 = NO_PIECE_TYPE; pt1 <= QUEEN; pt1++)
-  {
-      pc = pieceCount[Us][pt1];
-      if (!pc)
-          continue;
-
-      v = LinearCoefficients[pt1];
-
-      for (pt2 = NO_PIECE_TYPE; pt2 <= pt1; pt2++)
-          v +=  QuadraticCoefficientsSameColor[pt1][pt2] * pieceCount[Us][pt2]
-              + QuadraticCoefficientsOppositeColor[pt1][pt2] * pieceCount[Them][pt2];
-
-      value += pc * v;
-  }
-  return value;
-}
-
-
-/// MaterialTable::game_phase() calculates the phase given the current
+/// Material::game_phase() calculates the phase given the current
 /// position. Because the phase is strictly a function of the material, it
 /// is stored in MaterialEntry.
 
-Phase MaterialTable::game_phase(const Position& pos) {
+Phase game_phase(const Position& pos) {
 
   Value npm = pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK);
 
@@ -274,3 +274,5 @@ Phase MaterialTable::game_phase(const Position& pos) {
         : npm <= EndgameLimit ? PHASE_ENDGAME
         : Phase(((npm - EndgameLimit) * 128) / (MidgameLimit - EndgameLimit));
 }
+
+} // namespace Material
index 89f8f55685d0979b1cf6f07d748e897ee9df6c08..c88094cf2d89fe8765ff27240170041b79bbe0d3 100644 (file)
 #include "position.h"
 #include "types.h"
 
-const int MaterialTableSize = 8192;
+namespace Material {
 
-/// MaterialEntry is a class which contains various information about a
-/// material configuration. It contains a material balance evaluation,
-/// a function pointer to a special endgame evaluation function (which in
-/// most cases is NULL, meaning that the standard evaluation function will
-/// be used), and "scale factors" for black and white.
+/// Material::Entry contains various information about a material configuration.
+/// It contains a material balance evaluation, a function pointer to a special
+/// endgame evaluation function (which in most cases is NULL, meaning that the
+/// standard evaluation function will be used), and "scale factors".
 ///
 /// The scale factors are used to scale the evaluation score up or down.
 /// For instance, in KRB vs KR endgames, the score is scaled down by a factor
 /// of 4, which will result in scores of absolute value less than one pawn.
 
-class MaterialEntry {
+struct Entry {
 
-  friend struct MaterialTable;
-
-public:
-  Score material_value() const;
+  Score material_value() const { return make_score(value, value); }
+  int space_weight() const { return spaceWeight; }
+  Phase game_phase() const { return gamePhase; }
+  bool specialized_eval_exists() const { return evaluationFunction != NULL; }
+  Value evaluate(const Position& p) const { return (*evaluationFunction)(p); }
   ScaleFactor scale_factor(const Position& pos, Color c) const;
-  int space_weight() const;
-  Phase game_phase() const;
-  bool specialized_eval_exists() const;
-  Value evaluate(const Position& pos) const;
 
-private:
   Key key;
   int16_t value;
   uint8_t factor[COLOR_NB];
@@ -59,55 +54,24 @@ private:
   Phase gamePhase;
 };
 
+typedef HashTable<Entry, 8192> Table;
 
-/// The MaterialTable class represents a material hash table. The most important
-/// method is probe(), which returns a pointer to a MaterialEntry object.
-
-struct MaterialTable {
-
-  MaterialEntry* probe(const Position& pos);
-  static Phase game_phase(const Position& pos);
-  template<Color Us> static int imbalance(const int pieceCount[][PIECE_TYPE_NB]);
-
-  HashTable<MaterialEntry, MaterialTableSize> entries;
-  Endgames endgames;
-};
-
+Entry* probe(const Position& pos, Table& entries, Endgames& endgames);
+Phase game_phase(const Position& pos);
 
-/// MaterialEntry::scale_factor takes a position and a color as input, and
+/// Material::scale_factor takes a position and a color as input, and
 /// returns a scale factor for the given color. We have to provide the
 /// position in addition to the color, because the scale factor need not
 /// to be a constant: It can also be a function which should be applied to
 /// the position. For instance, in KBP vs K endgames, a scaling function
 /// which checks for draws with rook pawns and wrong-colored bishops.
 
-inline ScaleFactor MaterialEntry::scale_factor(const Position& pos, Color c) const {
-
-  if (!scalingFunction[c])
-      return ScaleFactor(factor[c]);
-
-  ScaleFactor sf = (*scalingFunction[c])(pos);
-  return sf == SCALE_FACTOR_NONE ? ScaleFactor(factor[c]) : sf;
-}
-
-inline Value MaterialEntry::evaluate(const Position& pos) const {
-  return (*evaluationFunction)(pos);
-}
-
-inline Score MaterialEntry::material_value() const {
-  return make_score(value, value);
-}
-
-inline int MaterialEntry::space_weight() const {
-  return spaceWeight;
-}
+inline ScaleFactor Entry::scale_factor(const Position& pos, Color c) const {
 
-inline Phase MaterialEntry::game_phase() const {
-  return gamePhase;
+  return !scalingFunction[c] || (*scalingFunction[c])(pos) == SCALE_FACTOR_NONE
+        ? ScaleFactor(factor[c]) : (*scalingFunction[c])(pos);
 }
 
-inline bool MaterialEntry::specialized_eval_exists() const {
-  return evaluationFunction != NULL;
 }
 
 #endif // !defined(MATERIAL_H_INCLUDED)
index 37b5c049cadd2152b6fdccaee44a87d0f57df315..0c19d820b5e8c80656e8340a2e312c7645caecae 100644 (file)
@@ -919,7 +919,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
 
   // Prefetch pawn and material hash tables
   prefetch((char*)thisThread->pawnTable.entries[st->pawnKey]);
-  prefetch((char*)thisThread->materialTable.entries[st->materialKey]);
+  prefetch((char*)thisThread->materialTable[st->materialKey]);
 
   // Update incremental scores
   st->psqScore += psq_delta(piece, from, to);
index 654efb3265f453caf9e8cfe398e04c625abc0b08..292faf0412a35e01f18320b275fed883c5efe56b 100644 (file)
@@ -208,7 +208,7 @@ void Search::think() {
   if (Options["Contempt Factor"] && !Options["UCI_AnalyseMode"])
   {
       int cf = Options["Contempt Factor"] * PawnValueMg / 100; // From centipawns
-      cf = cf * MaterialTable::game_phase(RootPos) / PHASE_MIDGAME; // Scale down with phase
+      cf = cf * Material::game_phase(RootPos) / PHASE_MIDGAME; // Scale down with phase
       DrawValue[ RootColor] = VALUE_DRAW - Value(cf);
       DrawValue[~RootColor] = VALUE_DRAW + Value(cf);
   }
index 6c3c18affdb0a134b08f4f23cbb87a5a87a40dd6..64a56ccb7ab62b75773d9f8a002e6d3a2806cb40 100644 (file)
@@ -110,7 +110,8 @@ public:
 
   SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD];
   Eval::Table evalTable;
-  MaterialTable materialTable;
+  Material::Table materialTable;
+  Endgames endgames;
   PawnTable pawnTable;
   size_t idx;
   int maxPly;