- const int LinearCoefficients[6] = { 1709, -137, -1185, -166, 141, 59 };
-
- const int QuadraticCoefficientsSameColor[][6] = {
- { 0, 0, 0, 0, 0, 0 }, { 33, -6, 0, 0, 0, 0 }, { 29, 269, -12, 0, 0, 0 },
- { 0, 19, -4, 0, 0, 0 }, { -35, -10, 40, 95, 50, 0 }, { 52, 23, 78, 144, -11, -33 } };
-
- const int QuadraticCoefficientsOppositeColor[][6] = {
- { 0, 0, 0, 0, 0, 0 }, { -5, 0, 0, 0, 0, 0 }, { -33, 23, 0, 0, 0, 0 },
- { 17, 25, -3, 0, 0, 0 }, { 10, -2, -19, -67, 0, 0 }, { 69, 64, -41, 116, 137, 0 } };
-
- // Unmapped endgame evaluation and scaling functions, these
- // are accessed direcly and not through the function maps.
- EvaluationFunction<KmmKm> EvaluateKmmKm(WHITE);
- EvaluationFunction<KXK> EvaluateKXK(WHITE), EvaluateKKX(BLACK);
- ScalingFunction<KBPK> ScaleKBPK(WHITE), ScaleKKBP(BLACK);
- ScalingFunction<KQKRP> ScaleKQKRP(WHITE), ScaleKRPKQ(BLACK);
- ScalingFunction<KPsK> ScaleKPsK(WHITE), ScaleKKPs(BLACK);
- ScalingFunction<KPKP> ScaleKPKPw(WHITE), ScaleKPKPb(BLACK);
+
+ const int LinearCoefficients[6] = { 1617, -162, -1172, -190, 105, 26 };
+
+ const int QuadraticCoefficientsSameColor[][8] = {
+ { 7, 7, 7, 7, 7, 7 }, { 39, 2, 7, 7, 7, 7 }, { 35, 271, -4, 7, 7, 7 },
+ { 7, 25, 4, 7, 7, 7 }, { -27, -2, 46, 100, 56, 7 }, { 58, 29, 83, 148, -3, -25 } };
+
+ const int QuadraticCoefficientsOppositeColor[][8] = {
+ { 41, 41, 41, 41, 41, 41 }, { 37, 41, 41, 41, 41, 41 }, { 10, 62, 41, 41, 41, 41 },
+ { 57, 64, 39, 41, 41, 41 }, { 50, 40, 23, -22, 41, 41 }, { 106, 101, 3, 151, 171, 41 } };
+
+ typedef EndgameEvaluationFunctionBase EF;
+ typedef EndgameScalingFunctionBase SF;
+ typedef map<Key, EF*> EFMap;
+ typedef map<Key, SF*> SFMap;
+
+ // Endgame evaluation and scaling functions accessed direcly and not through
+ // the function maps because correspond to more then one material hash key.
+ EvaluationFunction<KmmKm> EvaluateKmmKm[] = { EvaluationFunction<KmmKm>(WHITE), EvaluationFunction<KmmKm>(BLACK) };
+ EvaluationFunction<KXK> EvaluateKXK[] = { EvaluationFunction<KXK>(WHITE), EvaluationFunction<KXK>(BLACK) };
+ ScalingFunction<KBPsK> ScaleKBPsK[] = { ScalingFunction<KBPsK>(WHITE), ScalingFunction<KBPsK>(BLACK) };
+ ScalingFunction<KQKRPs> ScaleKQKRPs[] = { ScalingFunction<KQKRPs>(WHITE), ScalingFunction<KQKRPs>(BLACK) };
+ ScalingFunction<KPsK> ScaleKPsK[] = { ScalingFunction<KPsK>(WHITE), ScalingFunction<KPsK>(BLACK) };
+ ScalingFunction<KPKP> ScaleKPKP[] = { ScalingFunction<KPKP>(WHITE), ScalingFunction<KPKP>(BLACK) };
+
+ // Helper templates used to detect a given material distribution
+ template<Color Us> bool is_KXK(const Position& pos) {
+ const Color Them = (Us == WHITE ? BLACK : WHITE);
+ return pos.non_pawn_material(Them) == VALUE_ZERO
+ && pos.piece_count(Them, PAWN) == 0
+ && pos.non_pawn_material(Us) >= RookValueMidgame;
+ }
+
+ template<Color Us> bool is_KBPsK(const Position& pos) {
+ return pos.non_pawn_material(Us) == BishopValueMidgame
+ && pos.piece_count(Us, BISHOP) == 1
+ && pos.piece_count(Us, PAWN) >= 1;
+ }
+
+ template<Color Us> bool is_KQKRPs(const Position& pos) {
+ const Color Them = (Us == WHITE ? BLACK : WHITE);
+ return pos.piece_count(Us, PAWN) == 0
+ && pos.non_pawn_material(Us) == QueenValueMidgame
+ && pos.piece_count(Us, QUEEN) == 1
+ && pos.piece_count(Them, ROOK) == 1
+ && pos.piece_count(Them, PAWN) >= 1;
+ }