mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-21 01:27:16 +08:00
Use templates for end game evaluation functions
Huge simplification and no speed cost penalty. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
@@ -35,39 +35,18 @@
|
|||||||
/// Evaluation functions
|
/// Evaluation functions
|
||||||
|
|
||||||
// Generic "mate lone king" eval
|
// Generic "mate lone king" eval
|
||||||
KXKEvaluationFunction EvaluateKXK = KXKEvaluationFunction(WHITE);
|
EvaluationFunction<KXK> EvaluateKXK(WHITE), EvaluateKKX(BLACK);
|
||||||
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);
|
|
||||||
|
|
||||||
// K and two minors vs K and one or two minors
|
// K and two minors vs K and one or two minors
|
||||||
KmmKmEvaluationFunction EvaluateKmmKm = KmmKmEvaluationFunction(WHITE);
|
EvaluationFunction<KmmKm> EvaluateKmmKm(WHITE);
|
||||||
|
|
||||||
|
EvaluationFunction<KBNK> EvaluateKBNK(WHITE), EvaluateKKBN(BLACK); // KBN vs K
|
||||||
|
EvaluationFunction<KPK> EvaluateKPK(WHITE), EvaluateKKP(BLACK); // KP vs K
|
||||||
|
EvaluationFunction<KRKP> EvaluateKRKP(WHITE), EvaluateKPKR(BLACK); // KR vs KP
|
||||||
|
EvaluationFunction<KRKB> EvaluateKRKB(WHITE), EvaluateKBKR(BLACK); // KR vs KB
|
||||||
|
EvaluationFunction<KRKN> EvaluateKRKN(WHITE), EvaluateKNKR(BLACK); // KR vs KN
|
||||||
|
EvaluationFunction<KQKR> EvaluateKQKR(WHITE), EvaluateKRKQ(BLACK); // KQ vs KR
|
||||||
|
EvaluationFunction<KBBKN> EvaluateKBBKN(WHITE), EvaluateKNKBB(BLACK); // KBB vs KN
|
||||||
|
|
||||||
|
|
||||||
/// Scaling functions
|
/// Scaling functions
|
||||||
@@ -185,17 +164,6 @@ EndgameEvaluationFunction::EndgameEvaluationFunction(Color c) : strongerSide(c)
|
|||||||
weakerSide = opposite_color(strongerSide);
|
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) {
|
ScalingFunction::ScalingFunction(Color c) : strongerSide(c) {
|
||||||
weakerSide = opposite_color(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
|
/// 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
|
/// 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.
|
/// of the board, and for keeping the distance between the two kings small.
|
||||||
|
template<>
|
||||||
Value KXKEvaluationFunction::apply(const Position& pos) {
|
Value EvaluationFunction<KXK>::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(weakerSide) == Value(0));
|
assert(pos.non_pawn_material(weakerSide) == Value(0));
|
||||||
assert(pos.piece_count(weakerSide, PAWN) == 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
|
/// 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.
|
/// defending king towards a corner square of the right color.
|
||||||
|
template<>
|
||||||
Value KBNKEvaluationFunction::apply(const Position& pos) {
|
Value EvaluationFunction<KBNK>::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(weakerSide) == Value(0));
|
assert(pos.non_pawn_material(weakerSide) == Value(0));
|
||||||
assert(pos.piece_count(weakerSide, PAWN) == 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.
|
/// KP vs K. This endgame is evaluated with the help of a bitbase.
|
||||||
|
template<>
|
||||||
Value KPKEvaluationFunction::apply(const Position& pos) {
|
Value EvaluationFunction<KPK>::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(strongerSide) == Value(0));
|
assert(pos.non_pawn_material(strongerSide) == Value(0));
|
||||||
assert(pos.non_pawn_material(weakerSide) == 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
|
/// 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
|
/// far advanced with support of the king, while the attacking king is far
|
||||||
/// away.
|
/// away.
|
||||||
|
template<>
|
||||||
Value KRKPEvaluationFunction::apply(const Position& pos) {
|
Value EvaluationFunction<KRKP>::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
|
assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
|
||||||
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
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
|
/// 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.
|
/// score is slightly bigger when the defending king is close to the edge.
|
||||||
|
template<>
|
||||||
Value KRKBEvaluationFunction::apply(const Position& pos) {
|
Value EvaluationFunction<KRKB>::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
|
assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
|
||||||
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
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
|
/// 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.
|
/// in KR vs KB, particularly if the king and the knight are far apart.
|
||||||
|
template<>
|
||||||
Value KRKNEvaluationFunction::apply(const Position& pos) {
|
Value EvaluationFunction<KRKN>::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
|
assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
|
||||||
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
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
|
/// 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
|
/// for the defending side in the search, this is usually sufficient to be
|
||||||
/// able to win KQ vs KR.
|
/// able to win KQ vs KR.
|
||||||
|
template<>
|
||||||
Value KQKREvaluationFunction::apply(const Position& pos) {
|
Value EvaluationFunction<KQKR>::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
|
assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
|
||||||
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
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;
|
return (strongerSide == pos.side_to_move())? result : -result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
Value KBBKNEvaluationFunction::apply(const Position& pos) {
|
Value EvaluationFunction<KBBKN>::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.piece_count(strongerSide, BISHOP) == 2);
|
assert(pos.piece_count(strongerSide, BISHOP) == 2);
|
||||||
assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame);
|
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);
|
return (strongerSide == pos.side_to_move() ? result : -result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
Value KmmKmEvaluationFunction::apply(const Position &pos) {
|
Value EvaluationFunction<KmmKm>::apply(const Position &pos) {
|
||||||
return Value(0);
|
return Value(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
114
src/endgame.h
114
src/endgame.h
@@ -34,86 +34,41 @@
|
|||||||
//// Types
|
//// Types
|
||||||
////
|
////
|
||||||
|
|
||||||
/// Abstract base class for all special endgame evaluation functions:
|
/// Abstract base class for all special endgame evaluation functions
|
||||||
|
|
||||||
class EndgameEvaluationFunction {
|
class EndgameEvaluationFunction {
|
||||||
public:
|
public:
|
||||||
EndgameEvaluationFunction(Color c);
|
EndgameEvaluationFunction(Color c);
|
||||||
virtual ~EndgameEvaluationFunction() { }
|
virtual ~EndgameEvaluationFunction() { }
|
||||||
|
|
||||||
virtual Value apply(const Position &pos) =0;
|
virtual Value apply(const Position &pos) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Color strongerSide, weakerSide;
|
Color strongerSide, weakerSide;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Subclasses for various concrete endgames:
|
/// Template subclass for various concrete endgames
|
||||||
|
|
||||||
// Generic "mate lone king" eval:
|
enum EndgameType {
|
||||||
class KXKEvaluationFunction : public EndgameEvaluationFunction {
|
KXK, // Generic "mate lone king" eval
|
||||||
public:
|
KBNK, // KBN vs K
|
||||||
KXKEvaluationFunction(Color c);
|
KPK, // KP vs K
|
||||||
Value apply(const Position &pos);
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
// KBN vs K:
|
template<EndgameType>
|
||||||
class KBNKEvaluationFunction : public EndgameEvaluationFunction {
|
class EvaluationFunction : public EndgameEvaluationFunction {
|
||||||
public:
|
public:
|
||||||
KBNKEvaluationFunction(Color c);
|
explicit EvaluationFunction(Color c): EndgameEvaluationFunction(c) {}
|
||||||
Value apply(const Position &pos);
|
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// KBB vs KN:
|
|
||||||
class KBBKNEvaluationFunction : public EndgameEvaluationFunction {
|
|
||||||
public:
|
|
||||||
KBBKNEvaluationFunction(Color 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:
|
/// Abstract base class for all evaluation scaling functions:
|
||||||
|
|
||||||
class ScalingFunction {
|
class ScalingFunction {
|
||||||
@@ -198,32 +153,15 @@ public:
|
|||||||
//// Constants and variables
|
//// Constants and variables
|
||||||
////
|
////
|
||||||
|
|
||||||
// Generic "mate lone king" eval:
|
extern EvaluationFunction<KXK> EvaluateKXK, EvaluateKKX; // Generic "mate lone king" eval
|
||||||
extern KXKEvaluationFunction EvaluateKXK, EvaluateKKX;
|
extern EvaluationFunction<KBNK> EvaluateKBNK, EvaluateKKBN; // KBN vs K
|
||||||
|
extern EvaluationFunction<KPK> EvaluateKPK, EvaluateKKP; // KP vs K
|
||||||
// KBN vs K:
|
extern EvaluationFunction<KRKP> EvaluateKRKP, EvaluateKPKR; // KR vs KP
|
||||||
extern KBNKEvaluationFunction EvaluateKBNK, EvaluateKKBN;
|
extern EvaluationFunction<KRKB> EvaluateKRKB, EvaluateKBKR; // KR vs KB
|
||||||
|
extern EvaluationFunction<KRKN> EvaluateKRKN, EvaluateKNKR; // KR vs KN
|
||||||
// KP vs K:
|
extern EvaluationFunction<KQKR> EvaluateKQKR, EvaluateKRKQ; // KQ vs KR
|
||||||
extern KPKEvaluationFunction EvaluateKPK, EvaluateKKP;
|
extern EvaluationFunction<KBBKN> EvaluateKBBKN, EvaluateKNKBB; // KBB vs KN
|
||||||
|
extern EvaluationFunction<KmmKm> EvaluateKmmKm; // K and two minors vs K and one or two minors:
|
||||||
// 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;
|
|
||||||
|
|
||||||
// KBP vs K:
|
// KBP vs K:
|
||||||
extern KBPKScalingFunction ScaleKBPK, ScaleKKBP;
|
extern KBPKScalingFunction ScaleKBPK, ScaleKKBP;
|
||||||
|
|||||||
Reference in New Issue
Block a user