Final touches to material.cpp
authorMarco Costalba <mcostalba@gmail.com>
Sat, 1 Nov 2008 10:38:30 +0000 (11:38 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 1 Nov 2008 11:46:54 +0000 (12:46 +0100)
No functional changes, altough a bit of code reshuffle.

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

index 7b675d34533d100fa6acfe37686ae87ab86c5cd8..9d2e1ef28c080061d0562f229c569ab5b5e0dcae 100644 (file)
@@ -59,7 +59,6 @@ int main(int argc, char *argv[]) {
   init_uci_options();
   Position::init_zobrist();
   Position::init_piece_square_tables();
-  MaterialInfo::init();
   MovePicker::init_phase_table();
   init_eval(1);
   init_bitbases();
index 10daaeb53ae6df5d3507eda190ca6bb6d99b691a..9f0fb9ed295fba16038a89081a8ab92c56cab797 100644 (file)
@@ -39,29 +39,33 @@ namespace {
 
   Key KNNKMaterialKey, KKNNMaterialKey;
 
-  struct ScalingInfo
-  {
-      Color col;
-      ScalingFunction* fun;
-  };
-
 }
 
 ////
 //// Classes
 ////
 
+
+/// See header for a class description. It is declared here to avoid
+/// to include <map> in the header file.
+
 class EndgameFunctions {
 
 public:
   EndgameFunctions();
-  EndgameEvaluationFunction* getEEF(Key key);
-  ScalingInfo getESF(Key key);
+  EndgameEvaluationFunction* getEEF(Key key) const;
+  ScalingFunction* getESF(Key key, Color* c) const;
 
 private:
   void add(Key k, EndgameEvaluationFunction* f);
   void add(Key k, Color c, ScalingFunction* f);
 
+  struct ScalingInfo
+  {
+      Color col;
+      ScalingFunction* fun;
+  };
+
   std::map<Key, EndgameEvaluationFunction*> EEFmap;
   std::map<Key, ScalingInfo> ESFmap;
 };
@@ -71,19 +75,6 @@ private:
 //// Functions
 ////
 
-/// MaterialInfo::init() is called during program initialization. It
-/// precomputes material hash keys for a few basic endgames, in order
-/// to make it easy to recognize such endgames when they occur.
-
-void MaterialInfo::init() {
-
-  typedef Key ZM[2][8][16];
-  const ZM& z = Position::zobMaterial;
-
-  KNNKMaterialKey = z[WHITE][KNIGHT][1] ^ z[WHITE][KNIGHT][2];
-  KKNNMaterialKey = z[BLACK][KNIGHT][1] ^ z[BLACK][KNIGHT][2];
-}
-
 
 /// Constructor for the MaterialInfoTable class
 
@@ -126,7 +117,7 @@ void MaterialInfoTable::clear() {
 /// is stored there, so we don't have to recompute everything when the
 /// same material configuration occurs again.
 
-MaterialInfo *MaterialInfoTable::get_material_info(const Position& pos) {
+MaterialInfoMaterialInfoTable::get_material_info(const Position& pos) {
 
   Key key = pos.get_material_key();
   int index = key & (size - 1);
@@ -136,7 +127,7 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position& pos) {
   // have analysed this material configuration before, and we can simply
   // return the information we found the last time instead of recomputing it.
   if (mi->key == key)
-    return mi;
+      return mi;
 
   // Clear the MaterialInfo object, and set its key
   mi->clear();
@@ -146,8 +137,8 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position& pos) {
   // KNN vs K is a draw.
   if (key == KNNKMaterialKey || key == KKNNMaterialKey)
   {
-    mi->factor[WHITE] = mi->factor[BLACK] = 0;
-    return mi;
+      mi->factor[WHITE] = mi->factor[BLACK] = 0;
+      return mi;
   }
 
   // Let's look if we have a specialized evaluation function for this
@@ -177,10 +168,12 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position& pos) {
   // if we decide to add more special cases.  We face problems when there
   // are several conflicting applicable scaling functions and we need to
   // decide which one to use.
-  ScalingInfo si = funcs->getESF(key);
-  if (si.fun != NULL)
+  Color c;
+  ScalingFunction* sf;
+
+  if ((sf = funcs->getESF(key, &c)) != NULL)
   {
-      mi->scalingFunction[si.col] = si.fun;
+      mi->scalingFunction[c] = sf;
       return mi;
   }
 
@@ -229,7 +222,6 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position& pos) {
 
   // Evaluate the material balance
 
-  Color c;
   int sign;
   Value egValue = Value(0);
   Value mgValue = Value(0);
@@ -281,17 +273,16 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position& pos) {
         egValue -= sign * v;
     }
   }
-
   mi->mgValue = int16_t(mgValue);
   mi->egValue = int16_t(egValue);
   return mi;
 }
 
 
-/// EndgameFunctions members definition. This helper class is used to
-/// store the maps of end game and scaling functions that MaterialInfoTable
-/// will query for each key. The maps are constant, and are populated only
-/// at construction. Being per thread avoids to use locks to access them.
+/// EndgameFunctions member definitions. This class is used to store the maps
+/// of end game and scaling functions that MaterialInfoTable will query for 
+/// each key. The maps are constant and are populated only at construction,
+/// but are per-thread instead of globals to avoid expensive locks.
 
 EndgameFunctions::EndgameFunctions() {
 
@@ -343,22 +334,18 @@ void EndgameFunctions::add(Key k, Color c, ScalingFunction* f) {
   ESFmap.insert(std::pair<Key, ScalingInfo>(k, s));
 }
 
-EndgameEvaluationFunction* EndgameFunctions::getEEF(Key key) {
-
-  EndgameEvaluationFunction* f = NULL;
-  std::map<Key, EndgameEvaluationFunction*>::iterator it(EEFmap.find(key));
-  if (it != EEFmap.end())
-      f = it->second;
+EndgameEvaluationFunction* EndgameFunctions::getEEF(Key key) const {
 
-  return f;
+  std::map<Key, EndgameEvaluationFunction*>::const_iterator it(EEFmap.find(key));
+  return (it != EEFmap.end() ? it->second : NULL);
 }
 
-ScalingInfo EndgameFunctions::getESF(Key key) {
+ScalingFunction* EndgameFunctions::getESF(Key key, Color* c) const {
 
-  ScalingInfo si = {WHITE, NULL};
-  std::map<Key, ScalingInfo>::iterator it(ESFmap.find(key));
-  if (it != ESFmap.end())
-      si = it->second;
+  std::map<Key, ScalingInfo>::const_iterator it(ESFmap.find(key));
+  if (it == ESFmap.end())
+      return NULL;
 
-  return si;
+  *c = it->second.col;
+  return it->second.fun;
 }
index 4597295814240e0103c72d549c4734e60fafc4d0..4ebd78fd5bb033ddb80063db3bced3e93b82114e 100644 (file)
@@ -35,7 +35,7 @@
 ////
 
 /// MaterialInfo is a class which contains various information about a
-/// material configuration.  It contains a material balance evaluation,
+/// 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.
@@ -51,11 +51,9 @@ class MaterialInfo {
 public:
   Value mg_value() const;
   Value eg_value() const;
-  ScaleFactor scale_factor(const Position &pos, Color c) const;
+  ScaleFactor scale_factor(const Positionpos, Color c) const;
   bool specialized_eval_exists() const;
-  Value evaluate(const Position &pos) const;
-
-  static void init();
+  Value evaluate(const Position& pos) const;
 
 private:
   void clear();
@@ -64,20 +62,22 @@ private:
   int16_t mgValue;
   int16_t egValue;
   uint8_t factor[2];
-  EndgameEvaluationFunction *evaluationFunction;
-  ScalingFunction *scalingFunction[2];
+  EndgameEvaluationFunctionevaluationFunction;
+  ScalingFunctionscalingFunction[2];
 };
 
 
-/// Stores the endgame evaluation functions maps. Should be per thread
-/// because STL is not thread safe and locks are expensive.
+/// EndgameFunctions class stores the endgame evaluation functions std::map.
+/// Because STL library is not thread safe even for read access, the maps,
+/// although with identical content, are replicated for each thread. This
+/// is faster then using locks with an unique set of global maps.
 
 class EndgameFunctions;
 
 
-/// The MaterialInfoTable class represents a pawn hash table.  It is basically
+/// The MaterialInfoTable class represents a pawn hash table. It is basically
 /// just an array of MaterialInfo objects and a few methods for accessing these
-/// objects.  The most important method is get_material_info, which looks up a
+/// objects. The most important method is get_material_info, which looks up a
 /// position in the table and returns a pointer to a MaterialInfo object.
 
 class MaterialInfoTable {
@@ -86,11 +86,11 @@ public:
   MaterialInfoTable(unsigned numOfEntries);
   ~MaterialInfoTable();
   void clear();
-  MaterialInfo *get_material_info(const Position &pos);
+  MaterialInfo* get_material_info(const Position& pos);
 
 private:
   unsigned size;
-  MaterialInfo *entries;
+  MaterialInfoentries;
   EndgameFunctions* funcs;
 };
 
@@ -103,10 +103,12 @@ private:
 /// material balance evaluation for the middle game and the endgame.
 
 inline Value MaterialInfo::mg_value() const {
+
   return Value(mgValue);
 }
 
 inline Value MaterialInfo::eg_value() const {
+
   return Value(egValue);
 }
 
@@ -115,6 +117,7 @@ inline Value MaterialInfo::eg_value() const {
 /// with all slots at their default values.
 
 inline void MaterialInfo::clear() {
+
   mgValue = egValue = 0;
   factor[WHITE] = factor[BLACK] = uint8_t(SCALE_FACTOR_NORMAL);
   evaluationFunction = NULL;
@@ -125,16 +128,17 @@ inline void MaterialInfo::clear() {
 /// MaterialInfo::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
-/// 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
+/// 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 MaterialInfo::scale_factor(const Position &pos, Color c)
-  const {
-  if(scalingFunction[c] != NULL) {
-    ScaleFactor sf = scalingFunction[c]->apply(pos);
-    if(sf != SCALE_FACTOR_NONE)
-      return sf;
+inline ScaleFactor MaterialInfo::scale_factor(const Position& pos, Color c) const {
+
+  if (scalingFunction[c] != NULL)
+  {
+      ScaleFactor sf = scalingFunction[c]->apply(pos);
+      if (sf != SCALE_FACTOR_NONE)
+          return sf;
   }
   return ScaleFactor(factor[c]);
 }
@@ -145,15 +149,17 @@ inline ScaleFactor MaterialInfo::scale_factor(const Position &pos, Color c)
 /// or if the normal evaluation function should be used.
 
 inline bool MaterialInfo::specialized_eval_exists() const {
+
   return evaluationFunction != NULL;
 }
 
 
-/// MaterialInfo::evaluate applies a specialized evaluation function to a
-/// given position object.  It should only be called when
-/// this->specialized_eval_exists() returns 'true'.
+/// MaterialInfo::evaluate applies a specialized evaluation function
+/// to a given position object.  It should only be called when
+/// specialized_eval_exists() returns 'true'.
+
+inline Value MaterialInfo::evaluate(const Position& pos) const {
 
-inline Value MaterialInfo::evaluate(const Position &pos) const {
   return evaluationFunction->apply(pos);
 }