+
+
+/// 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.
+
+EndgameFunctions::EndgameFunctions() {
+
+ typedef Key ZM[2][8][16];
+ const ZM& z = Position::zobMaterial;
+
+ static const Color W = WHITE;
+ static const Color B = BLACK;
+
+ KNNKMaterialKey = z[W][KNIGHT][1] ^ z[W][KNIGHT][2];
+ KKNNMaterialKey = z[B][KNIGHT][1] ^ z[B][KNIGHT][2];
+
+ add(z[W][PAWN][1], &EvaluateKPK);
+ add(z[B][PAWN][1], &EvaluateKKP);
+
+ add(z[W][BISHOP][1] ^ z[W][KNIGHT][1], &EvaluateKBNK);
+ add(z[B][BISHOP][1] ^ z[B][KNIGHT][1], &EvaluateKKBN);
+ add(z[W][ROOK][1] ^ z[B][PAWN][1], &EvaluateKRKP);
+ add(z[W][PAWN][1] ^ z[B][ROOK][1], &EvaluateKPKR);
+ add(z[W][ROOK][1] ^ z[B][BISHOP][1], &EvaluateKRKB);
+ add(z[W][BISHOP][1] ^ z[B][ROOK][1], &EvaluateKBKR);
+ add(z[W][ROOK][1] ^ z[B][KNIGHT][1], &EvaluateKRKN);
+ add(z[W][KNIGHT][1] ^ z[B][ROOK][1], &EvaluateKNKR);
+ add(z[W][QUEEN][1] ^ z[B][ROOK][1], &EvaluateKQKR);
+ add(z[W][ROOK][1] ^ z[B][QUEEN][1], &EvaluateKRKQ);
+ add(z[W][BISHOP][2] ^ z[B][KNIGHT][1], &EvaluateKBBKN);
+ add(z[W][KNIGHT][1] ^ z[B][BISHOP][2], &EvaluateKNKBB);
+
+ add(z[W][KNIGHT][1] ^ z[W][PAWN][1], W, &ScaleKNPK);
+ add(z[B][KNIGHT][1] ^ z[B][PAWN][1], B, &ScaleKKNP);
+
+ add(z[W][ROOK][1] ^ z[W][PAWN][1] ^ z[B][ROOK][1] , W, &ScaleKRPKR);
+ add(z[W][ROOK][1] ^ z[B][ROOK][1] ^ z[B][PAWN][1] , B, &ScaleKRKRP);
+ add(z[W][BISHOP][1] ^ z[W][PAWN][1] ^ z[B][BISHOP][1], W, &ScaleKBPKB);
+ add(z[W][BISHOP][1] ^ z[B][BISHOP][1] ^ z[B][PAWN][1] , B, &ScaleKBKBP);
+ add(z[W][BISHOP][1] ^ z[W][PAWN][1] ^ z[B][KNIGHT][1], W, &ScaleKBPKN);
+ add(z[W][KNIGHT][1] ^ z[B][BISHOP][1] ^ z[B][PAWN][1] , B, &ScaleKNKBP);
+
+ add(z[W][ROOK][1] ^ z[W][PAWN][1] ^ z[W][PAWN][2] ^ z[B][ROOK][1] ^ z[B][PAWN][1], W, &ScaleKRPPKRP);
+ add(z[W][ROOK][1] ^ z[W][PAWN][1] ^ z[B][ROOK][1] ^ z[B][PAWN][1] ^ z[B][PAWN][2], B, &ScaleKRPKRPP);
+}
+
+void EndgameFunctions::add(Key k, EndgameEvaluationFunction* f) {
+
+ EEFmap.insert(std::pair<Key, EndgameEvaluationFunction*>(k, f));
+}
+
+void EndgameFunctions::add(Key k, Color c, ScalingFunction* f) {
+
+ ScalingInfo s = {c, f};
+ ESFmap.insert(std::pair<Key, ScalingInfo>(k, s));
+}
+
+EndgameEvaluationFunction* EndgameFunctions::getEEF(Key key) const {
+
+ std::map<Key, EndgameEvaluationFunction*>::const_iterator it(EEFmap.find(key));
+ return (it != EEFmap.end() ? it->second : NULL);
+}
+
+ScalingFunction* 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;
+}