From b5d5646c840d63710552fdaf2521a054dd3b8a18 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Mon, 11 Apr 2011 18:12:41 +0200 Subject: [PATCH 1/1] Move EndgameFunctions to endgame.cpp And cleanup code while there. No functional change. Signed-off-by: Marco Costalba --- src/endgame.cpp | 129 ++++++++++++++++++++++++++++++++------ src/endgame.h | 106 +++++++++++++++++++------------- src/material.cpp | 157 +++++++---------------------------------------- src/material.h | 15 +++-- src/position.h | 3 - 5 files changed, 201 insertions(+), 209 deletions(-) diff --git a/src/endgame.cpp b/src/endgame.cpp index 167a9ed4..44a34d60 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -23,6 +23,8 @@ #include "endgame.h" #include "pawns.h" +using std::string; + extern uint32_t probe_kpk_bitbase(Square wksq, Square wpsq, Square bksq, Color stm); namespace { @@ -78,15 +80,102 @@ namespace { return Value(KRKNKingKnightDistancePenalty[d]); } + // Build corresponding key for the opposite color: "KBPKN" -> "KNKBP" + const string swapColors(const string& keyCode) { + + size_t idx = keyCode.find('K', 1); + return keyCode.substr(idx) + keyCode.substr(0, idx); + } + + // Build up a fen string with the given pieces, note that the fen string + // could be of an illegal position. + Key buildKey(const string& keyCode) { + + assert(keyCode.length() > 0 && keyCode.length() < 8); + assert(keyCode[0] == 'K'); + + string fen; + bool upcase = false; + + for (size_t i = 0; i < keyCode.length(); i++) + { + if (keyCode[i] == 'K') + upcase = !upcase; + + fen += char(upcase ? toupper(keyCode[i]) : tolower(keyCode[i])); + } + fen += char(8 - keyCode.length() + '0'); + fen += "/8/8/8/8/8/8/8 w - -"; + return Position(fen, false, 0).get_material_key(); + } + + typedef EndgameBase EF; + typedef EndgameBase SF; + +} // namespace + + +/// Endgames member definitions + +template<> const Endgames::EFMap& Endgames::get() const { return maps.first; } +template<> const Endgames::SFMap& Endgames::get() const { return maps.second; } + +Endgames::Endgames() { + + add >("KNNK"); + add >("KPK"); + add >("KBNK"); + add >("KRKP"); + add >("KRKB"); + add >("KRKN"); + add >("KQKR"); + add >("KBBKN"); + + add >("KNPK"); + add >("KRPKR"); + add >("KBPKB"); + add >("KBPPKB"); + add >("KBPKN"); + add >("KRPPKRP"); +} + +Endgames::~Endgames() { + + for (EFMap::const_iterator it = get().begin(); it != get().end(); ++it) + delete it->second; + + for (SFMap::const_iterator it = get().begin(); it != get().end(); ++it) + delete it->second; +} + +template +void Endgames::add(const string& keyCode) { + + typedef typename T::Base F; + typedef std::map M; + + const_cast(get()).insert(std::pair(buildKey(keyCode), new T(WHITE))); + const_cast(get()).insert(std::pair(buildKey(swapColors(keyCode)), new T(BLACK))); } +template +T* Endgames::get(Key key) const { + + typename std::map::const_iterator it = get().find(key); + return it != get().end() ? it->second : NULL; +} + +// Explicit template instantiations +template EF* Endgames::get(Key key) const; +template SF* Endgames::get(Key key) const; + /// Mate with KX vs K. This function is used to evaluate positions with /// King and plenty of material vs a lone king. It simply gives the /// attacking side a bonus for driving the defending king towards the edge /// of the board, and for keeping the distance between the two kings small. template<> -Value EvaluationFunction::apply(const Position& pos) const { +Value Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); assert(pos.piece_count(weakerSide, PAWN) == VALUE_ZERO); @@ -112,7 +201,7 @@ Value EvaluationFunction::apply(const Position& pos) const { /// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the /// defending king towards a corner square of the right color. template<> -Value EvaluationFunction::apply(const Position& pos) const { +Value Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); assert(pos.piece_count(weakerSide, PAWN) == VALUE_ZERO); @@ -144,7 +233,7 @@ Value EvaluationFunction::apply(const Position& pos) const { /// KP vs K. This endgame is evaluated with the help of a bitbase. template<> -Value EvaluationFunction::apply(const Position& pos) const { +Value Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO); assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); @@ -192,7 +281,7 @@ Value EvaluationFunction::apply(const Position& pos) const { /// far advanced with support of the king, while the attacking king is far /// away. template<> -Value EvaluationFunction::apply(const Position& pos) const { +Value Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 0); @@ -249,7 +338,7 @@ Value EvaluationFunction::apply(const Position& pos) const { /// KR vs KB. This is very simple, and always returns drawish scores. The /// score is slightly bigger when the defending king is close to the edge. template<> -Value EvaluationFunction::apply(const Position& pos) const { +Value Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 0); @@ -265,7 +354,7 @@ Value EvaluationFunction::apply(const Position& pos) const { /// KR vs KN. The attacking side has slightly better winning chances than /// in KR vs KB, particularly if the king and the knight are far apart. template<> -Value EvaluationFunction::apply(const Position& pos) const { +Value Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 0); @@ -291,7 +380,7 @@ Value EvaluationFunction::apply(const Position& pos) const { /// for the defending side in the search, this is usually sufficient to be /// able to win KQ vs KR. template<> -Value EvaluationFunction::apply(const Position& pos) const { +Value Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 0); @@ -310,7 +399,7 @@ Value EvaluationFunction::apply(const Position& pos) const { } template<> -Value EvaluationFunction::apply(const Position& pos) const { +Value Endgame::apply(const Position& pos) const { assert(pos.piece_count(strongerSide, BISHOP) == 2); assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame); @@ -339,12 +428,12 @@ Value EvaluationFunction::apply(const Position& pos) const { /// K and two minors vs K and one or two minors or K and two knights against /// king alone are always draw. template<> -Value EvaluationFunction::apply(const Position&) const { +Value Endgame::apply(const Position&) const { return VALUE_DRAW; } template<> -Value EvaluationFunction::apply(const Position&) const { +Value Endgame::apply(const Position&) const { return VALUE_DRAW; } @@ -354,7 +443,7 @@ Value EvaluationFunction::apply(const Position&) const { /// returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling /// will be used. template<> -ScaleFactor ScalingFunction::apply(const Position& pos) const { +ScaleFactor Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame); assert(pos.piece_count(strongerSide, BISHOP) == 1); @@ -408,7 +497,7 @@ ScaleFactor ScalingFunction::apply(const Position& pos) const { /// It tests for fortress draws with a rook on the third rank defended by /// a pawn. template<> -ScaleFactor ScalingFunction::apply(const Position& pos) const { +ScaleFactor Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame); assert(pos.piece_count(strongerSide, QUEEN) == 1); @@ -439,7 +528,7 @@ ScaleFactor ScalingFunction::apply(const Position& pos) const { /// It would also be nice to rewrite the actual code for this function, /// which is mostly copied from Glaurung 1.x, and not very pretty. template<> -ScaleFactor ScalingFunction::apply(const Position& pos) const { +ScaleFactor Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 1); @@ -557,7 +646,7 @@ ScaleFactor ScalingFunction::apply(const Position& pos) const { /// single pattern: If the stronger side has no pawns and the defending king /// is actively placed, the position is drawish. template<> -ScaleFactor ScalingFunction::apply(const Position& pos) const { +ScaleFactor Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 2); @@ -596,7 +685,7 @@ ScaleFactor ScalingFunction::apply(const Position& pos) const { /// against king. There is just a single rule here: If all pawns are on /// the same rook file and are blocked by the defending king, it's a draw. template<> -ScaleFactor ScalingFunction::apply(const Position& pos) const { +ScaleFactor Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO); assert(pos.piece_count(strongerSide, PAWN) >= 2); @@ -634,7 +723,7 @@ ScaleFactor ScalingFunction::apply(const Position& pos) const { /// it's a draw. If the two bishops have opposite color, it's almost always /// a draw. template<> -ScaleFactor ScalingFunction::apply(const Position& pos) const { +ScaleFactor Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame); assert(pos.piece_count(strongerSide, BISHOP) == 1); @@ -689,7 +778,7 @@ ScaleFactor ScalingFunction::apply(const Position& pos) const { /// KBPPKBScalingFunction scales KBPP vs KB endgames. It detects a few basic /// draws with opposite-colored bishops. template<> -ScaleFactor ScalingFunction::apply(const Position& pos) const { +ScaleFactor Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame); assert(pos.piece_count(strongerSide, BISHOP) == 1); @@ -765,7 +854,7 @@ ScaleFactor ScalingFunction::apply(const Position& pos) const { /// square of the king is not of the same color as the stronger side's bishop, /// it's a draw. template<> -ScaleFactor ScalingFunction::apply(const Position& pos) const { +ScaleFactor Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame); assert(pos.piece_count(strongerSide, BISHOP) == 1); @@ -792,7 +881,7 @@ ScaleFactor ScalingFunction::apply(const Position& pos) const { /// If the pawn is a rook pawn on the 7th rank and the defending king prevents /// the pawn from advancing, the position is drawn. template<> -ScaleFactor ScalingFunction::apply(const Position& pos) const { +ScaleFactor Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame); assert(pos.piece_count(strongerSide, KNIGHT) == 1); @@ -822,7 +911,7 @@ ScaleFactor ScalingFunction::apply(const Position& pos) const { /// advanced and not on a rook file; in this case it is often possible to win /// (e.g. 8/4k3/3p4/3P4/6K1/8/8/8 w - - 0 1). template<> -ScaleFactor ScalingFunction::apply(const Position& pos) const { +ScaleFactor Endgame::apply(const Position& pos) const { assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO); assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); diff --git a/src/endgame.h b/src/endgame.h index ceb93efa..e40b4050 100644 --- a/src/endgame.h +++ b/src/endgame.h @@ -20,43 +20,52 @@ #if !defined(ENDGAME_H_INCLUDED) #define ENDGAME_H_INCLUDED +#include +#include + #include "position.h" #include "types.h" + +/// EndgameType lists all supported endgames + enum EndgameType { - // Evaluation functions - KXK, // Generic "mate lone king" eval - KBNK, // KBN vs K - KPK, // KP vs K - KRKP, // KR vs KP - KRKB, // KR vs KB - KRKN, // KR vs KN - KQKR, // KQ vs KR - KBBKN, // KBB vs KN - KNNK, // KNN vs K - KmmKm, // K and two minors vs K and one or two minors - - // Scaling functions - KBPsK, // KB+pawns vs K - KQKRPs, // KQ vs KR+pawns - KRPKR, // KRP vs KR - KRPPKRP, // KRPP vs KRP - KPsK, // King and pawns vs king - KBPKB, // KBP vs KB - KBPPKB, // KBPP vs KB - KBPKN, // KBP vs KN - KNPK, // KNP vs K - KPKP // KP vs KP + // Evaluation functions + KXK, // Generic "mate lone king" eval + KBNK, // KBN vs K + KPK, // KP vs K + KRKP, // KR vs KP + KRKB, // KR vs KB + KRKN, // KR vs KN + KQKR, // KQ vs KR + KBBKN, // KBB vs KN + KNNK, // KNN vs K + KmmKm, // K and two minors vs K and one or two minors + + // Scaling functions + KBPsK, // KB+pawns vs K + KQKRPs, // KQ vs KR+pawns + KRPKR, // KRP vs KR + KRPPKRP, // KRPP vs KRP + KPsK, // King and pawns vs king + KBPKB, // KBP vs KB + KBPPKB, // KBPP vs KB + KBPKN, // KBP vs KN + KNPK, // KNP vs K + KPKP // KP vs KP }; -/// Template abstract base class for all special endgame functions + +/// Base and derived template class for endgame evaluation and scaling functions template -class EndgameFunctionBase { -public: - EndgameFunctionBase(Color c) : strongerSide(c), weakerSide(opposite_color(c)) {} - virtual ~EndgameFunctionBase() {} +struct EndgameBase { + + typedef EndgameBase Base; + + EndgameBase(Color c) : strongerSide(c), weakerSide(opposite_color(c)) {} + virtual ~EndgameBase() {} virtual T apply(const Position&) const = 0; Color color() const { return strongerSide; } @@ -64,24 +73,37 @@ protected: Color strongerSide, weakerSide; }; -typedef EndgameFunctionBase EndgameEvaluationFunctionBase; -typedef EndgameFunctionBase EndgameScalingFunctionBase; - -/// Templates subclass for various concrete endgames +template +struct Endgame : public EndgameBase { -template -struct EvaluationFunction : public EndgameEvaluationFunctionBase { - typedef EndgameEvaluationFunctionBase Base; - explicit EvaluationFunction(Color c): EndgameEvaluationFunctionBase(c) {} - Value apply(const Position&) const; + explicit Endgame(Color c): EndgameBase(c) {} + T apply(const Position&) const; }; -template -struct ScalingFunction : public EndgameScalingFunctionBase { - typedef EndgameScalingFunctionBase Base; - explicit ScalingFunction(Color c) : EndgameScalingFunctionBase(c) {} - ScaleFactor apply(const Position&) const; + +/// Endgames class stores in two std::map the pointers to endgame evaluation +/// and scaling base objects. Then we use polymorphism to invoke the actual +/// endgame function calling its apply() method that is virtual. + +class Endgames { + + typedef std::map*> EFMap; + typedef std::map*> SFMap; + +public: + Endgames(); + ~Endgames(); + template T* get(Key key) const; + +private: + template void add(const std::string& keyCode); + + // Here we store two maps, for evaluate and scaling functions... + std::pair maps; + + // ...and here is the accessing template function + template const std::map& get() const; }; #endif // !defined(ENDGAME_H_INCLUDED) diff --git a/src/material.cpp b/src/material.cpp index 31550720..f5001c99 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -19,7 +19,6 @@ #include #include -#include #include "material.h" @@ -48,19 +47,15 @@ namespace { { 41, 41, 41, 41, 41, 41 }, { 37, 41, 41, 41, 41, 41 }, { 10, 62, 41, 41, 41, 41 }, { 57, 64, 39, 41, 41, 41 }, { 50, 40, 23, -22, 41, 41 }, { 106, 101, 3, 151, 171, 41 } }; - typedef EndgameEvaluationFunctionBase EF; - typedef EndgameScalingFunctionBase SF; - typedef map EFMap; - typedef map SFMap; - // Endgame evaluation and scaling functions accessed direcly and not through // the function maps because correspond to more then one material hash key. - EvaluationFunction EvaluateKmmKm[] = { EvaluationFunction(WHITE), EvaluationFunction(BLACK) }; - EvaluationFunction EvaluateKXK[] = { EvaluationFunction(WHITE), EvaluationFunction(BLACK) }; - ScalingFunction ScaleKBPsK[] = { ScalingFunction(WHITE), ScalingFunction(BLACK) }; - ScalingFunction ScaleKQKRPs[] = { ScalingFunction(WHITE), ScalingFunction(BLACK) }; - ScalingFunction ScaleKPsK[] = { ScalingFunction(WHITE), ScalingFunction(BLACK) }; - ScalingFunction ScaleKPKP[] = { ScalingFunction(WHITE), ScalingFunction(BLACK) }; + Endgame EvaluateKmmKm[] = { Endgame(WHITE), Endgame(BLACK) }; + Endgame EvaluateKXK[] = { Endgame(WHITE), Endgame(BLACK) }; + + Endgame ScaleKBPsK[] = { Endgame(WHITE), Endgame(BLACK) }; + Endgame ScaleKQKRPs[] = { Endgame(WHITE), Endgame(BLACK) }; + Endgame ScaleKPsK[] = { Endgame(WHITE), Endgame(BLACK) }; + Endgame ScaleKPKP[] = { Endgame(WHITE), Endgame(BLACK) }; // Helper templates used to detect a given material distribution template bool is_KXK(const Position& pos) { @@ -84,42 +79,13 @@ namespace { && pos.piece_count(Them, ROOK) == 1 && pos.piece_count(Them, PAWN) >= 1; } -} - - -/// EndgameFunctions class stores endgame evaluation and scaling functions -/// in two std::map. Because STL library is not guaranteed to be thread -/// safe even for read access, the maps, although with identical content, -/// are replicated for each thread. This is faster then using locks. - -class EndgameFunctions { -public: - EndgameFunctions(); - ~EndgameFunctions(); - template T* get(Key key) const; - -private: - template void add(const string& keyCode); - - static Key buildKey(const string& keyCode); - static const string swapColors(const string& keyCode); - - // Here we store two maps, for evaluate and scaling functions... - pair maps; - - // ...and here is the accessing template function - template const map& get() const; -}; -// Explicit specializations of a member function shall be declared in -// the namespace of which the class template is a member. -template<> const EFMap& EndgameFunctions::get() const { return maps.first; } -template<> const SFMap& EndgameFunctions::get() const { return maps.second; } +} // namespace -/// MaterialInfoTable c'tor and d'tor allocate and free the space for EndgameFunctions +/// MaterialInfoTable c'tor and d'tor allocate and free the space for Endgames -MaterialInfoTable::MaterialInfoTable() { funcs = new EndgameFunctions(); } +MaterialInfoTable::MaterialInfoTable() { funcs = new Endgames(); } MaterialInfoTable::~MaterialInfoTable() { delete funcs; } @@ -151,7 +117,7 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) const { // Let's look if we have a specialized evaluation function for this // particular material configuration. First we look for a fixed // configuration one, then a generic one if previous search failed. - if ((mi->evaluationFunction = funcs->get(key)) != NULL) + if ((mi->evaluationFunction = funcs->get >(key)) != NULL) return mi; if (is_KXK(pos)) @@ -186,9 +152,9 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) const { // // We face problems when there are several conflicting applicable // scaling functions and we need to decide which one to use. - SF* sf; + EndgameBase* sf; - if ((sf = funcs->get(key)) != NULL) + if ((sf = funcs->get >(key)) != NULL) { mi->scalingFunction[sf->color()] = sf; return mi; @@ -277,7 +243,7 @@ int MaterialInfoTable::imbalance(const int pieceCount[][8]) { const Color Them = (Us == WHITE ? BLACK : WHITE); - int pt1, pt2, pc, vv; + int pt1, pt2, pc, v; int value = 0; // Redundancy of major pieces, formula based on Kaufman's paper @@ -293,13 +259,13 @@ int MaterialInfoTable::imbalance(const int pieceCount[][8]) { if (!pc) continue; - vv = LinearCoefficients[pt1]; + v = LinearCoefficients[pt1]; for (pt2 = PIECE_TYPE_NONE; pt2 <= pt1; pt2++) - vv += QuadraticCoefficientsSameColor[pt1][pt2] * pieceCount[Us][pt2] - + QuadraticCoefficientsOppositeColor[pt1][pt2] * pieceCount[Them][pt2]; + v += QuadraticCoefficientsSameColor[pt1][pt2] * pieceCount[Us][pt2] + + QuadraticCoefficientsOppositeColor[pt1][pt2] * pieceCount[Them][pt2]; - value += pc * vv; + value += pc * v; } return value; } @@ -313,88 +279,7 @@ Phase MaterialInfoTable::game_phase(const Position& pos) { Value npm = pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK); - if (npm >= MidgameLimit) - return PHASE_MIDGAME; - - if (npm <= EndgameLimit) - return PHASE_ENDGAME; - - return Phase(((npm - EndgameLimit) * 128) / (MidgameLimit - EndgameLimit)); -} - - -/// EndgameFunctions member definitions - -EndgameFunctions::EndgameFunctions() { - - add >("KNNK"); - add >("KPK"); - add >("KBNK"); - add >("KRKP"); - add >("KRKB"); - add >("KRKN"); - add >("KQKR"); - add >("KBBKN"); - - add >("KNPK"); - add >("KRPKR"); - add >("KBPKB"); - add >("KBPPKB"); - add >("KBPKN"); - add >("KRPPKRP"); -} - -EndgameFunctions::~EndgameFunctions() { - - for (EFMap::const_iterator it = maps.first.begin(); it != maps.first.end(); ++it) - delete it->second; - - for (SFMap::const_iterator it = maps.second.begin(); it != maps.second.end(); ++it) - delete it->second; -} - -Key EndgameFunctions::buildKey(const string& keyCode) { - - assert(keyCode.length() > 0 && keyCode.length() < 8); - assert(keyCode[0] == 'K'); - - string fen; - bool upcase = false; - - // Build up a fen string with the given pieces, note that - // the fen string could be of an illegal position. - for (size_t i = 0; i < keyCode.length(); i++) - { - if (keyCode[i] == 'K') - upcase = !upcase; - - fen += char(upcase ? toupper(keyCode[i]) : tolower(keyCode[i])); - } - fen += char(8 - keyCode.length() + '0'); - fen += "/8/8/8/8/8/8/8 w - -"; - return Position(fen, false, 0).get_material_key(); -} - -const string EndgameFunctions::swapColors(const string& keyCode) { - - // Build corresponding key for the opposite color: "KBPKN" -> "KNKBP" - size_t idx = keyCode.find('K', 1); - return keyCode.substr(idx) + keyCode.substr(0, idx); -} - -template -void EndgameFunctions::add(const string& keyCode) { - - typedef typename T::Base F; - typedef map M; - - const_cast(get()).insert(pair(buildKey(keyCode), new T(WHITE))); - const_cast(get()).insert(pair(buildKey(swapColors(keyCode)), new T(BLACK))); -} - -template -T* EndgameFunctions::get(Key key) const { - - typename map::const_iterator it = get().find(key); - return it != get().end() ? it->second : NULL; + return npm >= MidgameLimit ? PHASE_MIDGAME + : npm <= EndgameLimit ? PHASE_ENDGAME + : Phase(((npm - EndgameLimit) * 128) / (MidgameLimit - EndgameLimit)); } diff --git a/src/material.h b/src/material.h index 08752572..18c0f944 100644 --- a/src/material.h +++ b/src/material.h @@ -53,8 +53,8 @@ private: Key key; int16_t value; uint8_t factor[2]; - EndgameEvaluationFunctionBase* evaluationFunction; - EndgameScalingFunctionBase* scalingFunction[2]; + EndgameBase* evaluationFunction; + EndgameBase* scalingFunction[2]; int spaceWeight; Phase gamePhase; }; @@ -62,7 +62,6 @@ private: /// The MaterialInfoTable class represents a pawn hash table. The most important /// method is get_material_info, which returns a pointer to a MaterialInfo object. -class EndgameFunctions; class MaterialInfoTable : public SimpleHash { public: @@ -75,7 +74,7 @@ private: template static int imbalance(const int pieceCount[][8]); - EndgameFunctions* funcs; + Endgames* funcs; }; @@ -95,6 +94,10 @@ inline ScaleFactor MaterialInfo::scale_factor(const Position& pos, Color c) cons return sf == SCALE_FACTOR_NONE ? ScaleFactor(factor[c]) : sf; } +inline Value MaterialInfo::evaluate(const Position& pos) const { + return evaluationFunction->apply(pos); +} + inline Score MaterialInfo::material_value() const { return make_score(value, value); } @@ -111,8 +114,4 @@ inline bool MaterialInfo::specialized_eval_exists() const { return evaluationFunction != NULL; } -inline Value MaterialInfo::evaluate(const Position& pos) const { - return evaluationFunction->apply(pos); -} - #endif // !defined(MATERIAL_H_INCLUDED) diff --git a/src/position.h b/src/position.h index 80e42aa8..c0c7e929 100644 --- a/src/position.h +++ b/src/position.h @@ -104,9 +104,6 @@ struct StateInfo { class Position { - friend class MaterialInfo; - friend class EndgameFunctions; - Position(); // No default or copy c'tor allowed Position(const Position& pos); -- 2.39.2