- const int pieceCount[2][8] = {
- { pos.piece_count(WHITE, BISHOP) > 1, pos.piece_count(WHITE, PAWN), pos.piece_count(WHITE, KNIGHT),
- pos.piece_count(WHITE, BISHOP) , pos.piece_count(WHITE, ROOK), pos.piece_count(WHITE, QUEEN) },
- { pos.piece_count(BLACK, BISHOP) > 1, pos.piece_count(BLACK, PAWN), pos.piece_count(BLACK, KNIGHT),
- pos.piece_count(BLACK, BISHOP) , pos.piece_count(BLACK, ROOK), pos.piece_count(BLACK, QUEEN) } };
-
- mi->value = (int16_t)(imbalance<WHITE>(pieceCount) - imbalance<BLACK>(pieceCount)) / 16;
- return mi;
-}
-
-
-/// MaterialInfoTable::imbalance() calculates imbalance comparing piece count of each
-/// piece type for both colors.
-
-template<Color Us>
-int MaterialInfoTable::imbalance(const int pieceCount[][8]) {
-
- const Color Them = (Us == WHITE ? BLACK : WHITE);
-
- int pt1, pt2, pc, vv;
- int value = 0;
-
- // Redundancy of major pieces, formula based on Kaufman's paper
- // "The Evaluation of Material Imbalances in Chess"
- if (pieceCount[Us][ROOK] > 0)
- value -= RedundantRookPenalty * (pieceCount[Us][ROOK] - 1)
- + RedundantQueenPenalty * pieceCount[Us][QUEEN];
-
- // Second-degree polynomial material imbalance by Tord Romstad
- for (pt1 = PIECE_TYPE_NONE; pt1 <= QUEEN; pt1++)
- {
- pc = pieceCount[Us][pt1];
- if (!pc)
- continue;
-
- vv = LinearCoefficients[pt1];
-
- for (pt2 = PIECE_TYPE_NONE; pt2 <= pt1; pt2++)
- vv += QuadraticCoefficientsSameColor[pt1][pt2] * pieceCount[Us][pt2]
- + QuadraticCoefficientsOppositeColor[pt1][pt2] * pieceCount[Them][pt2];
-
- value += pc * vv;
- }
- return value;
-}
-
-
-/// MaterialInfoTable::game_phase() calculates the phase given the current
-/// position. Because the phase is strictly a function of the material, it
-/// is stored in MaterialInfo.
-
-Phase MaterialInfoTable::game_phase(const Position& pos) {
-
- Value npm = pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK);
-
- if (npm >= MidgameLimit)
- return PHASE_MIDGAME;
-
- if (npm <= EndgameLimit)
- return PHASE_ENDGAME;
-
- return Phase(((npm - EndgameLimit) * 128) / (MidgameLimit - EndgameLimit));
-}
-
-
-/// EndgameFunctions member definitions
-
-EndgameFunctions::EndgameFunctions() {
-
- add<EvaluationFunction<KNNK> >("KNNK");
- 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");
-}
-
-EndgameFunctions::~EndgameFunctions() {
-
- for (EFMap::const_iterator it = maps.first.begin(); it != maps.first.end(); ++it)
- delete it->second;
-
- for (SFMap::const_iterator it = maps.second.begin(); it != maps.second.end(); ++it)
- delete it->second;
-}
-
-Key EndgameFunctions::buildKey(const string& keyCode) {
-
- assert(keyCode.length() > 0 && keyCode.length() < 8);
- assert(keyCode[0] == 'K');
-
- string fen;
- bool upcase = false;
-
- // Build up a fen string 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;
-
- fen += char(upcase ? toupper(keyCode[i]) : tolower(keyCode[i]));
- }
- fen += char(8 - keyCode.length() + '0');
- fen += "/8/8/8/8/8/8/8 w - -";
- return Position(fen, false, 0).get_material_key();