X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fendgame.cpp;h=01f4101ed8866ce63748d72cd8da177b78a229e1;hb=fcecc5212e42794cba218fc1ffd39cd9da818655;hp=9fafb042d86452f56006f23732f64c7b51bd436f;hpb=82bf08e4f20509b1e8e284833cd508dea7e3c145;p=stockfish diff --git a/src/endgame.cpp b/src/endgame.cpp index 9fafb042..01f4101e 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -35,78 +35,31 @@ /// Evaluation functions // Generic "mate lone king" eval -KXKEvaluationFunction EvaluateKXK = KXKEvaluationFunction(WHITE); -KXKEvaluationFunction EvaluateKKX = KXKEvaluationFunction(BLACK); - -// KBN vs K -KBNKEvaluationFunction EvaluateKBNK = KBNKEvaluationFunction(WHITE); -KBNKEvaluationFunction EvaluateKKBN = KBNKEvaluationFunction(BLACK); - -// KP vs K -KPKEvaluationFunction EvaluateKPK = KPKEvaluationFunction(WHITE); -KPKEvaluationFunction EvaluateKKP = KPKEvaluationFunction(BLACK); - -// KR vs KP -KRKPEvaluationFunction EvaluateKRKP = KRKPEvaluationFunction(WHITE); -KRKPEvaluationFunction EvaluateKPKR = KRKPEvaluationFunction(BLACK); - -// KR vs KB -KRKBEvaluationFunction EvaluateKRKB = KRKBEvaluationFunction(WHITE); -KRKBEvaluationFunction EvaluateKBKR = KRKBEvaluationFunction(BLACK); - -// KR vs KN -KRKNEvaluationFunction EvaluateKRKN = KRKNEvaluationFunction(WHITE); -KRKNEvaluationFunction EvaluateKNKR = KRKNEvaluationFunction(BLACK); - -// KQ vs KR -KQKREvaluationFunction EvaluateKQKR = KQKREvaluationFunction(WHITE); -KQKREvaluationFunction EvaluateKRKQ = KQKREvaluationFunction(BLACK); - -// KBB vs KN -KBBKNEvaluationFunction EvaluateKBBKN = KBBKNEvaluationFunction(WHITE); -KBBKNEvaluationFunction EvaluateKNKBB = KBBKNEvaluationFunction(BLACK); +EvaluationFunction EvaluateKXK(WHITE), EvaluateKKX(BLACK); // K and two minors vs K and one or two minors -KmmKmEvaluationFunction EvaluateKmmKm = KmmKmEvaluationFunction(WHITE); - - -/// Scaling functions - -// KBP vs K -KBPKScalingFunction ScaleKBPK = KBPKScalingFunction(WHITE); -KBPKScalingFunction ScaleKKBP = KBPKScalingFunction(BLACK); +EvaluationFunction EvaluateKmmKm(WHITE); -// KQ vs KRP -KQKRPScalingFunction ScaleKQKRP = KQKRPScalingFunction(WHITE); -KQKRPScalingFunction ScaleKRPKQ = KQKRPScalingFunction(BLACK); +EvaluationFunction EvaluateKBNK(WHITE), EvaluateKKBN(BLACK); // KBN vs K +EvaluationFunction EvaluateKPK(WHITE), EvaluateKKP(BLACK); // KP vs K +EvaluationFunction EvaluateKRKP(WHITE), EvaluateKPKR(BLACK); // KR vs KP +EvaluationFunction EvaluateKRKB(WHITE), EvaluateKBKR(BLACK); // KR vs KB +EvaluationFunction EvaluateKRKN(WHITE), EvaluateKNKR(BLACK); // KR vs KN +EvaluationFunction EvaluateKQKR(WHITE), EvaluateKRKQ(BLACK); // KQ vs KR +EvaluationFunction EvaluateKBBKN(WHITE), EvaluateKNKBB(BLACK); // KBB vs KN -// KRP vs KR -KRPKRScalingFunction ScaleKRPKR = KRPKRScalingFunction(WHITE); -KRPKRScalingFunction ScaleKRKRP = KRPKRScalingFunction(BLACK); -// KRPP vs KRP -KRPPKRPScalingFunction ScaleKRPPKRP = KRPPKRPScalingFunction(WHITE); -KRPPKRPScalingFunction ScaleKRPKRPP = KRPPKRPScalingFunction(BLACK); - -// King and pawns vs king -KPsKScalingFunction ScaleKPsK = KPsKScalingFunction(WHITE); -KPsKScalingFunction ScaleKKPs = KPsKScalingFunction(BLACK); - -// KBP vs KB -KBPKBScalingFunction ScaleKBPKB = KBPKBScalingFunction(WHITE); -KBPKBScalingFunction ScaleKBKBP = KBPKBScalingFunction(BLACK); - -// KBP vs KN -KBPKNScalingFunction ScaleKBPKN = KBPKNScalingFunction(WHITE); -KBPKNScalingFunction ScaleKNKBP = KBPKNScalingFunction(BLACK); - -// KNP vs K -KNPKScalingFunction ScaleKNPK = KNPKScalingFunction(WHITE); -KNPKScalingFunction ScaleKKNP = KNPKScalingFunction(BLACK); +/// Scaling functions -// KPKP -KPKPScalingFunction ScaleKPKPw = KPKPScalingFunction(WHITE); -KPKPScalingFunction ScaleKPKPb = KPKPScalingFunction(BLACK); +ScalingFunction ScaleKBPK(WHITE), ScaleKKBP(BLACK); // KBP vs K +ScalingFunction ScaleKQKRP(WHITE), ScaleKRPKQ(BLACK); // KQ vs KRP +ScalingFunction ScaleKRPKR(WHITE), ScaleKRKRP(BLACK); // KRP vs KR +ScalingFunction ScaleKRPPKRP(WHITE), ScaleKRPKRPP(BLACK); // KRPP vs KRP +ScalingFunction ScaleKPsK(WHITE), ScaleKKPs(BLACK); // King and pawns vs king +ScalingFunction ScaleKBPKB(WHITE), ScaleKBKBP(BLACK); // KBP vs KB +ScalingFunction ScaleKBPKN(WHITE), ScaleKNKBP(BLACK); // KBP vs KN +ScalingFunction ScaleKNPK(WHITE), ScaleKKNP(BLACK); // KNP vs K +ScalingFunction ScaleKPKPw(WHITE), ScaleKPKPb(BLACK); // KPKP //// @@ -179,44 +132,12 @@ namespace { //// Functions //// -/// Constructors - -EndgameEvaluationFunction::EndgameEvaluationFunction(Color c) : strongerSide(c) { - weakerSide = opposite_color(strongerSide); -} - -KXKEvaluationFunction::KXKEvaluationFunction(Color c) : EndgameEvaluationFunction(c) {} -KBNKEvaluationFunction::KBNKEvaluationFunction(Color c) : EndgameEvaluationFunction(c) {} -KPKEvaluationFunction::KPKEvaluationFunction(Color c) : EndgameEvaluationFunction(c) {} -KRKPEvaluationFunction::KRKPEvaluationFunction(Color c) : EndgameEvaluationFunction(c) {} -KRKBEvaluationFunction::KRKBEvaluationFunction(Color c) : EndgameEvaluationFunction(c) {} -KRKNEvaluationFunction::KRKNEvaluationFunction(Color c) : EndgameEvaluationFunction(c) {} -KQKREvaluationFunction::KQKREvaluationFunction(Color c) : EndgameEvaluationFunction(c) {} -KBBKNEvaluationFunction::KBBKNEvaluationFunction(Color c) : EndgameEvaluationFunction(c) {} -KmmKmEvaluationFunction::KmmKmEvaluationFunction(Color c) : EndgameEvaluationFunction(c) {} - - -ScalingFunction::ScalingFunction(Color c) : strongerSide(c) { - weakerSide = opposite_color(c); -} - -KBPKScalingFunction::KBPKScalingFunction(Color c) : ScalingFunction(c) {} -KQKRPScalingFunction::KQKRPScalingFunction(Color c) : ScalingFunction(c) {} -KRPKRScalingFunction::KRPKRScalingFunction(Color c) : ScalingFunction(c) {} -KRPPKRPScalingFunction::KRPPKRPScalingFunction(Color c) : ScalingFunction(c) {} -KPsKScalingFunction::KPsKScalingFunction(Color c) : ScalingFunction(c) {} -KBPKBScalingFunction::KBPKBScalingFunction(Color c) : ScalingFunction(c) {} -KBPKNScalingFunction::KBPKNScalingFunction(Color c) : ScalingFunction(c) {} -KNPKScalingFunction::KNPKScalingFunction(Color c) : ScalingFunction(c) {} -KPKPScalingFunction::KPKPScalingFunction(Color c) : ScalingFunction(c) {} - - /// Mate with KX vs K. This function is used to evaluate positions with /// King and plenty of material vs a lone king. It simply gives the /// attacking side a bonus for driving the defending king towards the edge /// of the board, and for keeping the distance between the two kings small. - -Value KXKEvaluationFunction::apply(const Position& pos) { +template<> +Value EvaluationFunction::apply(const Position& pos) { assert(pos.non_pawn_material(weakerSide) == Value(0)); assert(pos.piece_count(weakerSide, PAWN) == Value(0)); @@ -241,8 +162,8 @@ Value KXKEvaluationFunction::apply(const Position& pos) { /// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the /// defending king towards a corner square of the right color. - -Value KBNKEvaluationFunction::apply(const Position& pos) { +template<> +Value EvaluationFunction::apply(const Position& pos) { assert(pos.non_pawn_material(weakerSide) == Value(0)); assert(pos.piece_count(weakerSide, PAWN) == Value(0)); @@ -270,8 +191,8 @@ Value KBNKEvaluationFunction::apply(const Position& pos) { /// KP vs K. This endgame is evaluated with the help of a bitbase. - -Value KPKEvaluationFunction::apply(const Position& pos) { +template<> +Value EvaluationFunction::apply(const Position& pos) { assert(pos.non_pawn_material(strongerSide) == Value(0)); assert(pos.non_pawn_material(weakerSide) == Value(0)); @@ -318,8 +239,8 @@ Value KPKEvaluationFunction::apply(const Position& pos) { /// a bitbase. The function below returns drawish scores when the pawn is /// far advanced with support of the king, while the attacking king is far /// away. - -Value KRKPEvaluationFunction::apply(const Position& pos) { +template<> +Value EvaluationFunction::apply(const Position& pos) { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 0); @@ -375,8 +296,8 @@ Value KRKPEvaluationFunction::apply(const Position& pos) { /// KR vs KB. This is very simple, and always returns drawish scores. The /// score is slightly bigger when the defending king is close to the edge. - -Value KRKBEvaluationFunction::apply(const Position& pos) { +template<> +Value EvaluationFunction::apply(const Position& pos) { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 0); @@ -391,8 +312,8 @@ Value KRKBEvaluationFunction::apply(const Position& pos) { /// KR vs KN. The attacking side has slightly better winning chances than /// in KR vs KB, particularly if the king and the knight are far apart. - -Value KRKNEvaluationFunction::apply(const Position& pos) { +template<> +Value EvaluationFunction::apply(const Position& pos) { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 0); @@ -415,8 +336,8 @@ Value KRKNEvaluationFunction::apply(const Position& pos) { /// defending king towards the edge. If we also take care to avoid null move /// for the defending side in the search, this is usually sufficient to be /// able to win KQ vs KR. - -Value KQKREvaluationFunction::apply(const Position& pos) { +template<> +Value EvaluationFunction::apply(const Position& pos) { assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 0); @@ -434,8 +355,8 @@ Value KQKREvaluationFunction::apply(const Position& pos) { return (strongerSide == pos.side_to_move())? result : -result; } - -Value KBBKNEvaluationFunction::apply(const Position& pos) { +template<> +Value EvaluationFunction::apply(const Position& pos) { assert(pos.piece_count(strongerSide, BISHOP) == 2); assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame); @@ -460,8 +381,8 @@ Value KBBKNEvaluationFunction::apply(const Position& pos) { return (strongerSide == pos.side_to_move() ? result : -result); } - -Value KmmKmEvaluationFunction::apply(const Position &pos) { +template<> +Value EvaluationFunction::apply(const Position &pos) { return Value(0); } @@ -471,8 +392,8 @@ Value KmmKmEvaluationFunction::apply(const Position &pos) { /// bishop of the wrong color. If such a draw is detected, ScaleFactor(0) is /// returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling /// will be used. - -ScaleFactor KBPKScalingFunction::apply(const Position& pos) { +template<> +ScaleFactor ScalingFunction::apply(const Position& pos) { assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame); assert(pos.piece_count(strongerSide, BISHOP) == 1); @@ -526,8 +447,8 @@ ScaleFactor KBPKScalingFunction::apply(const Position& pos) { /// king and queen, while the weaker side has at least a rook and a pawn. /// It tests for fortress draws with a rook on the third rank defended by /// a pawn. - -ScaleFactor KQKRPScalingFunction::apply(const Position& pos) { +template<> +ScaleFactor ScalingFunction::apply(const Position& pos) { assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame); assert(pos.piece_count(strongerSide, QUEEN) == 1); @@ -557,8 +478,8 @@ ScaleFactor KQKRPScalingFunction::apply(const Position& pos) { /// /// It would also be nice to rewrite the actual code for this function, /// which is mostly copied from Glaurung 1.x, and not very pretty. - -ScaleFactor KRPKRScalingFunction::apply(const Position &pos) { +template<> +ScaleFactor ScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 1); @@ -675,8 +596,8 @@ ScaleFactor KRPKRScalingFunction::apply(const Position &pos) { /// KRPPKRPScalingFunction scales KRPP vs KRP endgames. There is only a /// single pattern: If the stronger side has no pawns and the defending king /// is actively placed, the position is drawish. - -ScaleFactor KRPPKRPScalingFunction::apply(const Position &pos) { +template<> +ScaleFactor ScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); assert(pos.piece_count(strongerSide, PAWN) == 2); @@ -714,8 +635,8 @@ ScaleFactor KRPPKRPScalingFunction::apply(const Position &pos) { /// KPsKScalingFunction scales endgames with king and two or more pawns /// against king. There is just a single rule here: If all pawns are on /// the same rook file and are blocked by the defending king, it's a draw. - -ScaleFactor KPsKScalingFunction::apply(const Position &pos) { +template<> +ScaleFactor ScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == Value(0)); assert(pos.piece_count(strongerSide, PAWN) >= 2); @@ -760,8 +681,8 @@ ScaleFactor KPsKScalingFunction::apply(const Position &pos) { /// square of the king is not of the same color as the stronger side's bishop, /// it's a draw. If the two bishops have opposite color, it's almost always /// a draw. - -ScaleFactor KBPKBScalingFunction::apply(const Position &pos) { +template<> +ScaleFactor ScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame); assert(pos.piece_count(strongerSide, BISHOP) == 1); @@ -815,8 +736,8 @@ ScaleFactor KBPKBScalingFunction::apply(const Position &pos) { /// If the defending king is somewhere along the path of the pawn, and the /// square of the king is not of the same color as the stronger side's bishop, /// it's a draw. - -ScaleFactor KBPKNScalingFunction::apply(const Position &pos) { +template<> +ScaleFactor ScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame); assert(pos.piece_count(strongerSide, BISHOP) == 1); @@ -842,8 +763,8 @@ ScaleFactor KBPKNScalingFunction::apply(const Position &pos) { /// KNPKScalingFunction scales KNP vs K endgames. There is a single rule: /// If the pawn is a rook pawn on the 7th rank and the defending king prevents /// the pawn from advancing, the position is drawn. - -ScaleFactor KNPKScalingFunction::apply(const Position &pos) { +template<> +ScaleFactor ScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame); assert(pos.piece_count(strongerSide, KNIGHT) == 1); @@ -872,8 +793,8 @@ ScaleFactor KNPKScalingFunction::apply(const Position &pos) { /// the pawn as well. The exception is when the stronger side's pawn is far /// advanced and not on a rook file; in this case it is often possible to win /// (e.g. 8/4k3/3p4/3P4/6K1/8/8/8 w - - 0 1). - -ScaleFactor KPKPScalingFunction::apply(const Position &pos) { +template<> +ScaleFactor ScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == Value(0)); assert(pos.non_pawn_material(weakerSide) == Value(0));