From 039badfda8fa05bc466612bce996837c7d69f22b Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Thu, 12 Feb 2009 13:20:22 +0100 Subject: [PATCH] Use templates for end game evaluation functions Huge simplification and no speed cost penalty. Signed-off-by: Marco Costalba --- src/endgame.cpp | 88 ++++++++++++------------------------- src/endgame.h | 114 +++++++++++------------------------------------- 2 files changed, 54 insertions(+), 148 deletions(-) diff --git a/src/endgame.cpp b/src/endgame.cpp index 9fafb042..f01f75a0 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -35,39 +35,18 @@ /// 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); +EvaluationFunction EvaluateKmmKm(WHITE); + +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 /// Scaling functions @@ -185,17 +164,6 @@ 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); } @@ -215,8 +183,8 @@ KPKPScalingFunction::KPKPScalingFunction(Color c) : ScalingFunction(c) {} /// 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 +209,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 +238,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 +286,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 +343,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 +359,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 +383,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 +402,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 +428,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); } diff --git a/src/endgame.h b/src/endgame.h index f2990e74..21e8ab6d 100644 --- a/src/endgame.h +++ b/src/endgame.h @@ -34,86 +34,41 @@ //// Types //// -/// Abstract base class for all special endgame evaluation functions: +/// Abstract base class for all special endgame evaluation functions class EndgameEvaluationFunction { public: EndgameEvaluationFunction(Color c); virtual ~EndgameEvaluationFunction() { } - virtual Value apply(const Position &pos) =0; + virtual Value apply(const Position &pos) = 0; protected: Color strongerSide, weakerSide; }; -/// Subclasses for various concrete endgames: - -// Generic "mate lone king" eval: -class KXKEvaluationFunction : public EndgameEvaluationFunction { -public: - KXKEvaluationFunction(Color c); - Value apply(const Position &pos); -}; - -// KBN vs K: -class KBNKEvaluationFunction : public EndgameEvaluationFunction { -public: - KBNKEvaluationFunction(Color c); - Value apply(const Position &pos); -}; - -// KP vs K: -class KPKEvaluationFunction : public EndgameEvaluationFunction { -public: - KPKEvaluationFunction(Color c); - Value apply(const Position &pos); -}; - -// KR vs KP: -class KRKPEvaluationFunction : public EndgameEvaluationFunction { -public: - KRKPEvaluationFunction(Color c); - Value apply(const Position &pos); -}; - -// KR vs KB: -class KRKBEvaluationFunction : public EndgameEvaluationFunction { -public: - KRKBEvaluationFunction(Color c); - Value apply(const Position &pos); -}; +/// Template subclass for various concrete endgames -// KR vs KN: -class KRKNEvaluationFunction : public EndgameEvaluationFunction { -public: - KRKNEvaluationFunction(Color c); - Value apply(const Position &pos); -}; - -// KQ vs KR: -class KQKREvaluationFunction : public EndgameEvaluationFunction { -public: - KQKREvaluationFunction(Color c); - Value apply(const Position &pos); +enum EndgameType { + KXK, // Generic "mate lone king" eval + KBNK, // KBN vs K + KPK, // KP vs K + KRKP, // KR vs KP + KRKB, // KR vs KB + KRKN, // KR vs KN + KQKR, // KQ vs KR + KBBKN, // KBB vs KN + KmmKm // K and two minors vs K and one or two minors }; -// KBB vs KN: -class KBBKNEvaluationFunction : public EndgameEvaluationFunction { +template +class EvaluationFunction : public EndgameEvaluationFunction { public: - KBBKNEvaluationFunction(Color C); - Value apply(const Position &pos); + explicit EvaluationFunction(Color c): EndgameEvaluationFunction(c) {} + Value apply(const Position& pos); }; -// K and two minors vs K and one or two minors: -class KmmKmEvaluationFunction : public EndgameEvaluationFunction { -public: - KmmKmEvaluationFunction(Color c); - Value apply(const Position &pos); -}; - - /// Abstract base class for all evaluation scaling functions: class ScalingFunction { @@ -198,32 +153,15 @@ public: //// Constants and variables //// -// Generic "mate lone king" eval: -extern KXKEvaluationFunction EvaluateKXK, EvaluateKKX; - -// KBN vs K: -extern KBNKEvaluationFunction EvaluateKBNK, EvaluateKKBN; - -// KP vs K: -extern KPKEvaluationFunction EvaluateKPK, EvaluateKKP; - -// KR vs KP: -extern KRKPEvaluationFunction EvaluateKRKP, EvaluateKPKR; - -// KR vs KB: -extern KRKBEvaluationFunction EvaluateKRKB, EvaluateKBKR; - -// KR vs KN: -extern KRKNEvaluationFunction EvaluateKRKN, EvaluateKNKR; - -// KQ vs KR: -extern KQKREvaluationFunction EvaluateKQKR, EvaluateKRKQ; - -// KBB vs KN: -extern KBBKNEvaluationFunction EvaluateKBBKN, EvaluateKNKBB; - -// K and two minors vs K and one or two minors: -extern KmmKmEvaluationFunction EvaluateKmmKm; +extern EvaluationFunction EvaluateKXK, EvaluateKKX; // Generic "mate lone king" eval +extern EvaluationFunction EvaluateKBNK, EvaluateKKBN; // KBN vs K +extern EvaluationFunction EvaluateKPK, EvaluateKKP; // KP vs K +extern EvaluationFunction EvaluateKRKP, EvaluateKPKR; // KR vs KP +extern EvaluationFunction EvaluateKRKB, EvaluateKBKR; // KR vs KB +extern EvaluationFunction EvaluateKRKN, EvaluateKNKR; // KR vs KN +extern EvaluationFunction EvaluateKQKR, EvaluateKRKQ; // KQ vs KR +extern EvaluationFunction EvaluateKBBKN, EvaluateKNKBB; // KBB vs KN +extern EvaluationFunction EvaluateKmmKm; // K and two minors vs K and one or two minors: // KBP vs K: extern KBPKScalingFunction ScaleKBPK, ScaleKKBP; -- 2.39.2