enum EndgameType {
// Evaluation functions
+
KXK, // Generic "mate lone king" eval
KBNK, // KBN vs K
KPK, // KP vs K
KNNK, // KNN vs K
KmmKm, // K and two minors vs K and one or two minors
+
// Scaling functions
+ SCALE_FUNS,
+
KBPsK, // KB+pawns vs K
KQKRPs, // KQ vs KR+pawns
KRPKR, // KRP vs KR
};
-/// Base and derived template class for endgame evaluation and scaling functions
+/// Some magic to detect family type of endgame from its enum value
+
+template<bool> struct bool_to_type { typedef Value type; };
+template<> struct bool_to_type<true> { typedef ScaleFactor type; };
+template<EndgameType E> struct eg_family : public bool_to_type<(E > SCALE_FUNS)> {};
+
+
+/// Base and derived templates for endgame evaluation and scaling functions
template<typename T>
struct EndgameBase {
- typedef EndgameBase<T> Base;
-
virtual ~EndgameBase() {}
virtual Color color() const = 0;
- virtual T apply(const Position&) const = 0;
+ virtual T operator()(const Position&) const = 0;
};
-template<typename T, EndgameType>
+template<EndgameType E, typename T = typename eg_family<E>::type>
struct Endgame : public EndgameBase<T> {
- explicit Endgame(Color c) : strongerSide(c), weakerSide(opposite_color(c)) {}
+ explicit Endgame(Color c) : strongerSide(c), weakerSide(flip(c)) {}
Color color() const { return strongerSide; }
- T apply(const Position&) const;
+ T operator()(const Position&) const;
private:
Color strongerSide, weakerSide;
/// and scaling base objects. Then we use polymorphism to invoke the actual
/// endgame function calling its apply() method that is virtual.
-class Endgames {
+struct Endgames {
+
+ template<typename T>
+ struct Map { typedef std::map<Key, EndgameBase<T>*> type; };
- typedef std::map<Key, EndgameBase<Value>*> EFMap;
- typedef std::map<Key, EndgameBase<ScaleFactor>*> SFMap;
+ typedef Map<Value>::type M1;
+ typedef Map<ScaleFactor>::type M2;
-public:
Endgames();
~Endgames();
- template<class T> T* get(Key key) const;
-private:
- template<class T> void add(const std::string& keyCode);
+ template<typename T>
+ EndgameBase<T>* get(Key key) const {
- // Here we store two maps, for evaluate and scaling functions...
- std::pair<EFMap, SFMap> maps;
+ typedef typename Map<T>::type M;
+ typename M::const_iterator it = map<M>().find(key);
+ return it != map<M>().end() ? it->second : NULL;
+ }
+
+private:
+ template<EndgameType E> void add(const std::string& keyCode);
+ template<typename M> const M& map() const;
- // ...and here is the accessing template function
- template<typename T> const std::map<Key, T*>& get() const;
+ M1 m1;
+ M2 m2;
};
#endif // !defined(ENDGAME_H_INCLUDED)