-
-/// 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 needed
-/// because std::map is not guaranteed to be thread-safe even if accessed
-/// only for a lookup.
-
-EndgameFunctions::EndgameFunctions() {
-
- KNNKMaterialKey = buildKey("KNNK");
- KKNNMaterialKey = buildKey("KKNN");
-
- add<EvaluationFunction<KPK> >("KPK");
- add<EvaluationFunction<KBNK> >("KBNK");
- add<EvaluationFunction<KRKP> >("KRKP");
- add<EvaluationFunction<KRKB> >("KRKB");
- add<EvaluationFunction<KRKN> >("KRKN");
- add<EvaluationFunction<KQKR> >("KQKR");
- add<EvaluationFunction<KBBKN> >("KBBKN");
-
- add<ScalingFunction<KNPK> >("KNPK");
- add<ScalingFunction<KRPKR> >("KRPKR");
- add<ScalingFunction<KBPKB> >("KBPKB");
- add<ScalingFunction<KBPPKB> >("KBPPKB");
- add<ScalingFunction<KBPKN> >("KBPKN");
- add<ScalingFunction<KRPPKRP> >("KRPPKRP");
- add<ScalingFunction<KRPPKRP> >("KRPPKRP");
-}
-
-EndgameFunctions::~EndgameFunctions() {
-
- for (std::map<Key, EF*>::iterator it = EEFmap.begin(); it != EEFmap.end(); ++it)
- delete (*it).second;
-
- for (std::map<Key, SF*>::iterator it = ESFmap.begin(); it != ESFmap.end(); ++it)
- delete (*it).second;
-}
-
-Key EndgameFunctions::buildKey(const string& keyCode) {
-
- assert(keyCode.length() > 0 && keyCode[0] == 'K');
- assert(keyCode.length() < 8);
-
- std::stringstream s;
- bool upcase = false;
-
- // Build up a fen substring 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;
-
- s << char(upcase? toupper(keyCode[i]) : tolower(keyCode[i]));
- }
- s << 8 - keyCode.length() << "/8/8/8/8/8/8/8 w -";
- return Position(s.str()).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<class T>
-void EndgameFunctions::add(const string& keyCode) {
-
- typedef typename T::Base F;
-
- 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<class T>
-T* EndgameFunctions::get(Key key) const {
-
- std::map<Key, T*>::const_iterator it(map<T>().find(key));
- return (it != map<T>().end() ? it->second : NULL);
-}