- 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][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);
+ KNNKMaterialKey = buildKey("KNNK");
+ KKNNMaterialKey = buildKey("KKNN");
+
+ add_ef<KPK>("KPK");
+ add_ef<KBNK>("KBNK");
+ add_ef<KRKP>("KRKP");
+ add_ef<KRKB>("KRKB");
+ add_ef<KRKN>("KRKN");
+ add_ef<KQKR>("KQKR");
+ add_ef<KBBKN>("KBBKN");
+
+ add_sf<KNPK>("KNPK");
+ add_sf<KRPKR>("KRPKR");
+ add_sf<KBPKB>("KBPKB");
+ add_sf<KBPPKB>("KBPPKB");
+ add_sf<KBPKN>("KBPKN");
+ add_sf<KRPPKRP>("KRPPKRP");
+ add_sf<KRPPKRP>("KRPPKRP");
+}
+
+EndgameFunctions::~EndgameFunctions() {
+
+ for (std::map<Key, EF*>::iterator it = EEFmap.begin(); it != EEFmap.end(); ++it)
+ delete (*it).second;
+
+ for (std::map<Key, ScalingInfo>::iterator it = ESFmap.begin(); it != ESFmap.end(); ++it)
+ delete (*it).second.fun;
+}
+
+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();