X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fmaterial.cpp;h=c9dcaba1d42c8441a02bb03638ac80b75d3c3520;hp=845519bc41648cedd2a7933564d4307b5ceafffa;hb=297c12e595ebc33e11be73ee4b188326418acb4f;hpb=5c20f59788c30cdfc5b1d16dae125ab394c5145c diff --git a/src/material.cpp b/src/material.cpp index 845519bc..c9dcaba1 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -42,8 +42,17 @@ namespace { Key KNNKMaterialKey, KKNNMaterialKey; + // Unmapped endgame evaluation and scaling functions, these + // are accessed direcly and not through the function maps. + EvaluationFunction EvaluateKmmKm(WHITE); + EvaluationFunction EvaluateKXK(WHITE), EvaluateKKX(BLACK); + ScalingFunction ScaleKBPK(WHITE), ScaleKKBP(BLACK); + ScalingFunction ScaleKQKRP(WHITE), ScaleKRPKQ(BLACK); + ScalingFunction ScaleKPsK(WHITE), ScaleKKPs(BLACK); + ScalingFunction ScaleKPKPw(WHITE), ScaleKPKPb(BLACK); } + //// //// Classes //// @@ -54,23 +63,28 @@ namespace { class EndgameFunctions { + typedef EndgameEvaluationFunctionBase EF; + typedef EndgameScalingFunctionBase SF; + public: EndgameFunctions(); - EndgameEvaluationFunctionBase* getEEF(Key key) const; - EndgameScalingFunctionBase* getESF(Key key, Color* c) const; + ~EndgameFunctions(); + EF* getEEF(Key key) const; + SF* getESF(Key key, Color* c) const; private: - void add(const string& keyCode, EndgameEvaluationFunctionBase* f); - void add(const string& keyCode, Color c, EndgameScalingFunctionBase* f); Key buildKey(const string& keyCode); + const string swapColors(const string& keyCode); + template void add_ef(const string& keyCode); + template void add_sf(const string& keyCode); struct ScalingInfo { Color col; - EndgameScalingFunctionBase* fun; + SF* fun; }; - std::map EEFmap; + std::map EEFmap; std::map ESFmap; }; @@ -176,7 +190,7 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) { // material configuration. Is there a suitable scaling function? // // The code below is rather messy, and it could easily get worse later, - // 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 // decide which one to use. Color c; @@ -305,42 +319,39 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) { /// 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. +/// 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("KPK", &EvaluateKPK); - add("KKP", &EvaluateKKP); - add("KBNK", &EvaluateKBNK); - add("KKBN", &EvaluateKKBN); - add("KRKP", &EvaluateKRKP); - add("KPKR", &EvaluateKPKR); - add("KRKB", &EvaluateKRKB); - add("KBKR", &EvaluateKBKR); - add("KRKN", &EvaluateKRKN); - add("KNKR", &EvaluateKNKR); - add("KQKR", &EvaluateKQKR); - add("KRKQ", &EvaluateKRKQ); - add("KBBKN", &EvaluateKBBKN); - add("KNKBB", &EvaluateKNKBB); - - add("KNPK", WHITE, &ScaleKNPK); - add("KKNP", BLACK, &ScaleKKNP); - add("KRPKR", WHITE, &ScaleKRPKR); - add("KRKRP", BLACK, &ScaleKRKRP); - add("KBPKB", WHITE, &ScaleKBPKB); - add("KBKBP", BLACK, &ScaleKBKBP); - add("KBPPKB", WHITE, &ScaleKBPPKB); - add("KBKBPP", BLACK, &ScaleKBKBPP); - add("KBPKN", WHITE, &ScaleKBPKN); - add("KNKBP", BLACK, &ScaleKNKBP); - add("KRPPKRP", WHITE, &ScaleKRPPKRP); - add("KRPKRPP", BLACK, &ScaleKRPKRPP); - add("KRPPKRP", WHITE, &ScaleKRPPKRP); - add("KRPKRPP", BLACK, &ScaleKRPKRPP); + add_ef("KPK"); + add_ef("KBNK"); + add_ef("KRKP"); + add_ef("KRKB"); + add_ef("KRKN"); + add_ef("KQKR"); + add_ef("KBBKN"); + + add_sf("KNPK"); + add_sf("KRPKR"); + add_sf("KBPKB"); + add_sf("KBPPKB"); + add_sf("KBPKN"); + add_sf("KRPPKRP"); + add_sf("KRPPKRP"); +} + +EndgameFunctions::~EndgameFunctions() { + + for (std::map::iterator it = EEFmap.begin(); it != EEFmap.end(); ++it) + delete (*it).second; + + for (std::map::iterator it = ESFmap.begin(); it != ESFmap.end(); ++it) + delete (*it).second.fun; } Key EndgameFunctions::buildKey(const string& keyCode) { @@ -364,20 +375,33 @@ Key EndgameFunctions::buildKey(const string& keyCode) { return Position(s.str()).get_material_key(); } -void EndgameFunctions::add(const string& keyCode, EndgameEvaluationFunctionBase* f) { +const string EndgameFunctions::swapColors(const string& keyCode) { - EEFmap.insert(std::pair(buildKey(keyCode), f)); + // Build corresponding key for the opposite color: "KBPKN" -> "KNKBP" + size_t idx = keyCode.find("K", 1); + return keyCode.substr(idx) + keyCode.substr(0, idx); } -void EndgameFunctions::add(const string& keyCode, Color c, EndgameScalingFunctionBase* f) { +template +void EndgameFunctions::add_ef(const string& keyCode) { + + EEFmap.insert(std::pair(buildKey(keyCode), new EvaluationFunction(WHITE))); + EEFmap.insert(std::pair(buildKey(swapColors(keyCode)), new EvaluationFunction(BLACK))); +} + +template +void EndgameFunctions::add_sf(const string& keyCode) { + + ScalingInfo s1 = {WHITE, new ScalingFunction(WHITE)}; + ScalingInfo s2 = {BLACK, new ScalingFunction(BLACK)}; - ScalingInfo s = {c, f}; - ESFmap.insert(std::pair(buildKey(keyCode), s)); + ESFmap.insert(std::pair(buildKey(keyCode), s1)); + ESFmap.insert(std::pair(buildKey(swapColors(keyCode)), s2)); } EndgameEvaluationFunctionBase* EndgameFunctions::getEEF(Key key) const { - std::map::const_iterator it(EEFmap.find(key)); + std::map::const_iterator it(EEFmap.find(key)); return (it != EEFmap.end() ? it->second : NULL); }