1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-02 01:29:36 +00:00

Remove even more redundancy in endgame functions handling

Push on the templatization even more to chip out some code
and take the opportunity to show some neat template trick ;-)

Ok. I would say we can stop here now....it is quickly becoming
a style exercise but we are not boost developers so give it a stop.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2009-07-17 14:32:27 +02:00
parent 342c8c883c
commit 0d69ac33ff
2 changed files with 44 additions and 59 deletions

View file

@ -68,6 +68,7 @@ public:
EndgameFunctionBase(Color c) : strongerSide(c), weakerSide(opposite_color(c)) {} EndgameFunctionBase(Color c) : strongerSide(c), weakerSide(opposite_color(c)) {}
virtual ~EndgameFunctionBase() {} virtual ~EndgameFunctionBase() {}
virtual T apply(const Position&) = 0; virtual T apply(const Position&) = 0;
Color color() const { return strongerSide; }
protected: protected:
Color strongerSide, weakerSide; Color strongerSide, weakerSide;
@ -81,12 +82,14 @@ typedef EndgameFunctionBase<ScaleFactor> EndgameScalingFunctionBase;
template<EndgameType> template<EndgameType>
struct EvaluationFunction : public EndgameEvaluationFunctionBase { struct EvaluationFunction : public EndgameEvaluationFunctionBase {
typedef EndgameEvaluationFunctionBase Base;
explicit EvaluationFunction(Color c): EndgameEvaluationFunctionBase(c) {} explicit EvaluationFunction(Color c): EndgameEvaluationFunctionBase(c) {}
Value apply(const Position&); Value apply(const Position&);
}; };
template<EndgameType> template<EndgameType>
struct ScalingFunction : public EndgameScalingFunctionBase { struct ScalingFunction : public EndgameScalingFunctionBase {
typedef EndgameScalingFunctionBase Base;
explicit ScalingFunction(Color c) : EndgameScalingFunctionBase(c) {} explicit ScalingFunction(Color c) : EndgameScalingFunctionBase(c) {}
ScaleFactor apply(const Position&); ScaleFactor apply(const Position&);
}; };

View file

@ -69,23 +69,22 @@ class EndgameFunctions {
public: public:
EndgameFunctions(); EndgameFunctions();
~EndgameFunctions(); ~EndgameFunctions();
EF* getEEF(Key key) const; template<class T> T* get(Key key) const;
SF* getESF(Key key, Color* c) const;
private: private:
Key buildKey(const string& keyCode); template<class T> void add(const string& keyCode);
const string swapColors(const string& keyCode);
template<EndgameType> void add_ef(const string& keyCode);
template<EndgameType> void add_sf(const string& keyCode);
struct ScalingInfo static Key buildKey(const string& keyCode);
{ static const string swapColors(const string& keyCode);
Color col;
SF* fun;
};
std::map<Key, EF*> EEFmap; std::map<Key, EF*> EEFmap;
std::map<Key, ScalingInfo> ESFmap; std::map<Key, SF*> ESFmap;
// Maps accessing functions for const and non-const references
template<typename T> const std::map<Key, T*>& map() const { return EEFmap; }
template<> const std::map<Key, SF*>& map<SF>() const { return ESFmap; }
template<typename T> std::map<Key, T*>& map() { return EEFmap; }
template<> std::map<Key, SF*>& map<SF>() { return ESFmap; }
}; };
@ -152,7 +151,7 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) {
// Let's look if we have a specialized evaluation function for this // Let's look if we have a specialized evaluation function for this
// particular material configuration. First we look for a fixed // particular material configuration. First we look for a fixed
// configuration one, then a generic one if previous search failed. // configuration one, then a generic one if previous search failed.
if ((mi->evaluationFunction = funcs->getEEF(key)) != NULL) if ((mi->evaluationFunction = funcs->get<EndgameEvaluationFunctionBase>(key)) != NULL)
return mi; return mi;
else if ( pos.non_pawn_material(BLACK) == Value(0) else if ( pos.non_pawn_material(BLACK) == Value(0)
@ -193,12 +192,11 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) {
// if we decide to add more special cases. We face problems when there // if we decide to add more special cases. We face problems when there
// are several conflicting applicable scaling functions and we need to // are several conflicting applicable scaling functions and we need to
// decide which one to use. // decide which one to use.
Color c;
EndgameScalingFunctionBase* sf; EndgameScalingFunctionBase* sf;
if ((sf = funcs->getESF(key, &c)) != NULL) if ((sf = funcs->get<EndgameScalingFunctionBase>(key)) != NULL)
{ {
mi->scalingFunction[c] = sf; mi->scalingFunction[sf->color()] = sf;
return mi; return mi;
} }
@ -259,6 +257,7 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) {
// Evaluate the material balance // Evaluate the material balance
Color c;
int sign; int sign;
Value egValue = Value(0); Value egValue = Value(0);
Value mgValue = Value(0); Value mgValue = Value(0);
@ -328,21 +327,21 @@ EndgameFunctions::EndgameFunctions() {
KNNKMaterialKey = buildKey("KNNK"); KNNKMaterialKey = buildKey("KNNK");
KKNNMaterialKey = buildKey("KKNN"); KKNNMaterialKey = buildKey("KKNN");
add_ef<KPK>("KPK"); add<EvaluationFunction<KPK> >("KPK");
add_ef<KBNK>("KBNK"); add<EvaluationFunction<KBNK> >("KBNK");
add_ef<KRKP>("KRKP"); add<EvaluationFunction<KRKP> >("KRKP");
add_ef<KRKB>("KRKB"); add<EvaluationFunction<KRKB> >("KRKB");
add_ef<KRKN>("KRKN"); add<EvaluationFunction<KRKN> >("KRKN");
add_ef<KQKR>("KQKR"); add<EvaluationFunction<KQKR> >("KQKR");
add_ef<KBBKN>("KBBKN"); add<EvaluationFunction<KBBKN> >("KBBKN");
add_sf<KNPK>("KNPK"); add<ScalingFunction<KNPK> >("KNPK");
add_sf<KRPKR>("KRPKR"); add<ScalingFunction<KRPKR> >("KRPKR");
add_sf<KBPKB>("KBPKB"); add<ScalingFunction<KBPKB> >("KBPKB");
add_sf<KBPPKB>("KBPPKB"); add<ScalingFunction<KBPPKB> >("KBPPKB");
add_sf<KBPKN>("KBPKN"); add<ScalingFunction<KBPKN> >("KBPKN");
add_sf<KRPPKRP>("KRPPKRP"); add<ScalingFunction<KRPPKRP> >("KRPPKRP");
add_sf<KRPPKRP>("KRPPKRP"); add<ScalingFunction<KRPPKRP> >("KRPPKRP");
} }
EndgameFunctions::~EndgameFunctions() { EndgameFunctions::~EndgameFunctions() {
@ -350,8 +349,8 @@ EndgameFunctions::~EndgameFunctions() {
for (std::map<Key, EF*>::iterator it = EEFmap.begin(); it != EEFmap.end(); ++it) for (std::map<Key, EF*>::iterator it = EEFmap.begin(); it != EEFmap.end(); ++it)
delete (*it).second; delete (*it).second;
for (std::map<Key, ScalingInfo>::iterator it = ESFmap.begin(); it != ESFmap.end(); ++it) for (std::map<Key, SF*>::iterator it = ESFmap.begin(); it != ESFmap.end(); ++it)
delete (*it).second.fun; delete (*it).second;
} }
Key EndgameFunctions::buildKey(const string& keyCode) { Key EndgameFunctions::buildKey(const string& keyCode) {
@ -382,35 +381,18 @@ const string EndgameFunctions::swapColors(const string& keyCode) {
return keyCode.substr(idx) + keyCode.substr(0, idx); return keyCode.substr(idx) + keyCode.substr(0, idx);
} }
template<EndgameType et> template<class T>
void EndgameFunctions::add_ef(const string& keyCode) { void EndgameFunctions::add(const string& keyCode) {
EEFmap.insert(std::pair<Key, EF*>(buildKey(keyCode), new EvaluationFunction<et>(WHITE))); typedef typename T::Base F;
EEFmap.insert(std::pair<Key, EF*>(buildKey(swapColors(keyCode)), new EvaluationFunction<et>(BLACK)));
map<F>().insert(std::pair<Key, F*>(buildKey(keyCode), new T(WHITE)));
map<F>().insert(std::pair<Key, F*>(buildKey(swapColors(keyCode)), new T(BLACK)));
} }
template<EndgameType et> template<class T>
void EndgameFunctions::add_sf(const string& keyCode) { T* EndgameFunctions::get(Key key) const {
ScalingInfo s1 = {WHITE, new ScalingFunction<et>(WHITE)}; std::map<Key, T*>::const_iterator it(map<T>().find(key));
ScalingInfo s2 = {BLACK, new ScalingFunction<et>(BLACK)}; return (it != map<T>().end() ? it->second : NULL);
ESFmap.insert(std::pair<Key, ScalingInfo>(buildKey(keyCode), s1));
ESFmap.insert(std::pair<Key, ScalingInfo>(buildKey(swapColors(keyCode)), s2));
}
EndgameEvaluationFunctionBase* EndgameFunctions::getEEF(Key key) const {
std::map<Key, EF*>::const_iterator it(EEFmap.find(key));
return (it != EEFmap.end() ? it->second : NULL);
}
EndgameScalingFunctionBase* EndgameFunctions::getESF(Key key, Color* c) const {
std::map<Key, ScalingInfo>::const_iterator it(ESFmap.find(key));
if (it == ESFmap.end())
return NULL;
*c = it->second.col;
return it->second.fun;
} }