mirror of
https://github.com/sockspls/badfish
synced 2025-07-12 03:59:15 +00:00
Some more cleanup in endgame.cpp
No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
6608a16a6a
commit
fe8f5b3497
2 changed files with 35 additions and 48 deletions
|
@ -31,7 +31,7 @@ namespace {
|
||||||
|
|
||||||
// Table used to drive the defending king towards the edge of the board
|
// Table used to drive the defending king towards the edge of the board
|
||||||
// in KX vs K and KQ vs KR endgames.
|
// in KX vs K and KQ vs KR endgames.
|
||||||
const uint8_t MateTable[64] = {
|
const int MateTable[64] = {
|
||||||
100, 90, 80, 70, 70, 80, 90, 100,
|
100, 90, 80, 70, 70, 80, 90, 100,
|
||||||
90, 70, 60, 50, 50, 60, 70, 90,
|
90, 70, 60, 50, 50, 60, 70, 90,
|
||||||
80, 60, 40, 30, 30, 40, 60, 80,
|
80, 60, 40, 30, 30, 40, 60, 80,
|
||||||
|
@ -44,7 +44,7 @@ namespace {
|
||||||
|
|
||||||
// Table used to drive the defending king towards a corner square of the
|
// Table used to drive the defending king towards a corner square of the
|
||||||
// right color in KBN vs K endgames.
|
// right color in KBN vs K endgames.
|
||||||
const uint8_t KBNKMateTable[64] = {
|
const int KBNKMateTable[64] = {
|
||||||
200, 190, 180, 170, 160, 150, 140, 130,
|
200, 190, 180, 170, 160, 150, 140, 130,
|
||||||
190, 180, 170, 160, 150, 140, 130, 140,
|
190, 180, 170, 160, 150, 140, 130, 140,
|
||||||
180, 170, 155, 140, 140, 125, 140, 150,
|
180, 170, 155, 140, 140, 125, 140, 150,
|
||||||
|
@ -63,49 +63,33 @@ namespace {
|
||||||
// and knight in KR vs KN endgames.
|
// and knight in KR vs KN endgames.
|
||||||
const int KRKNKingKnightDistancePenalty[8] = { 0, 0, 4, 10, 20, 32, 48, 70 };
|
const int KRKNKingKnightDistancePenalty[8] = { 0, 0, 4, 10, 20, 32, 48, 70 };
|
||||||
|
|
||||||
// Various inline functions for accessing the above arrays
|
// Build corresponding key code for the opposite color: "KBPKN" -> "KNKBP"
|
||||||
inline Value mate_table(Square s) {
|
const string swap_colors(const string& keyCode) {
|
||||||
return Value(MateTable[s]);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Value kbnk_mate_table(Square s) {
|
|
||||||
return Value(KBNKMateTable[s]);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Value distance_bonus(int d) {
|
|
||||||
return Value(DistanceBonus[d]);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Value krkn_king_knight_distance_penalty(int d) {
|
|
||||||
return Value(KRKNKingKnightDistancePenalty[d]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build corresponding key for the opposite color: "KBPKN" -> "KNKBP"
|
|
||||||
const string swapColors(const string& keyCode) {
|
|
||||||
|
|
||||||
size_t idx = keyCode.find('K', 1);
|
size_t idx = keyCode.find('K', 1);
|
||||||
return keyCode.substr(idx) + keyCode.substr(0, idx);
|
return keyCode.substr(idx) + keyCode.substr(0, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build up a fen string with the given pieces, note that the fen string
|
// Get the material key of a position out of the given endgame key code
|
||||||
// could be of an illegal position.
|
// like "KBPKN". The trick here is to first build up a FEN string and then
|
||||||
Key buildKey(const string& keyCode) {
|
// let a Position object to do the work for us. Note that the FEN string
|
||||||
|
// could correspond to an illegal position.
|
||||||
|
Key mat_key(const string& keyCode) {
|
||||||
|
|
||||||
assert(keyCode.length() > 0 && keyCode.length() < 8);
|
assert(keyCode.length() > 0 && keyCode.length() < 8);
|
||||||
assert(keyCode[0] == 'K');
|
assert(keyCode[0] == 'K');
|
||||||
|
|
||||||
string fen;
|
string fen;
|
||||||
bool upcase = false;
|
size_t i = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < keyCode.length(); i++)
|
// First add white and then black pieces
|
||||||
{
|
do fen += keyCode[i]; while (keyCode[++i] != 'K');
|
||||||
if (keyCode[i] == 'K')
|
do fen += char(tolower(keyCode[i])); while (++i < keyCode.length());
|
||||||
upcase = !upcase;
|
|
||||||
|
|
||||||
fen += char(upcase ? toupper(keyCode[i]) : tolower(keyCode[i]));
|
// Add file padding and remaining empty ranks
|
||||||
}
|
fen += string(1, '0' + int(8 - keyCode.length())) + "/8/8/8/8/8/8/8 w - -";
|
||||||
fen += char(8 - keyCode.length() + '0');
|
|
||||||
fen += "/8/8/8/8/8/8/8 w - -";
|
// Build a Position out of the fen string and get its material key
|
||||||
return Position(fen, false, 0).get_material_key();
|
return Position(fen, false, 0).get_material_key();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,8 +138,8 @@ void Endgames::add(const string& keyCode) {
|
||||||
typedef typename T::Base F;
|
typedef typename T::Base F;
|
||||||
typedef std::map<Key, F*> M;
|
typedef std::map<Key, F*> M;
|
||||||
|
|
||||||
const_cast<M&>(get<F>()).insert(std::pair<Key, F*>(buildKey(keyCode), new T(WHITE)));
|
const_cast<M&>(get<F>()).insert(std::pair<Key, F*>(mat_key(keyCode), new T(WHITE)));
|
||||||
const_cast<M&>(get<F>()).insert(std::pair<Key, F*>(buildKey(swapColors(keyCode)), new T(BLACK)));
|
const_cast<M&>(get<F>()).insert(std::pair<Key, F*>(mat_key(swap_colors(keyCode)), new T(BLACK)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -185,8 +169,8 @@ Value Endgame<Value, KXK>::apply(const Position& pos) const {
|
||||||
|
|
||||||
Value result = pos.non_pawn_material(strongerSide)
|
Value result = pos.non_pawn_material(strongerSide)
|
||||||
+ pos.piece_count(strongerSide, PAWN) * PawnValueEndgame
|
+ pos.piece_count(strongerSide, PAWN) * PawnValueEndgame
|
||||||
+ mate_table(loserKSq)
|
+ MateTable[loserKSq]
|
||||||
+ distance_bonus(square_distance(winnerKSq, loserKSq));
|
+ DistanceBonus[square_distance(winnerKSq, loserKSq)];
|
||||||
|
|
||||||
if ( pos.piece_count(strongerSide, QUEEN)
|
if ( pos.piece_count(strongerSide, QUEEN)
|
||||||
|| pos.piece_count(strongerSide, ROOK)
|
|| pos.piece_count(strongerSide, ROOK)
|
||||||
|
@ -224,8 +208,8 @@ Value Endgame<Value, KBNK>::apply(const Position& pos) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Value result = VALUE_KNOWN_WIN
|
Value result = VALUE_KNOWN_WIN
|
||||||
+ distance_bonus(square_distance(winnerKSq, loserKSq))
|
+ DistanceBonus[square_distance(winnerKSq, loserKSq)]
|
||||||
+ kbnk_mate_table(loserKSq);
|
+ KBNKMateTable[loserKSq];
|
||||||
|
|
||||||
return strongerSide == pos.side_to_move() ? result : -result;
|
return strongerSide == pos.side_to_move() ? result : -result;
|
||||||
}
|
}
|
||||||
|
@ -346,7 +330,7 @@ Value Endgame<Value, KRKB>::apply(const Position& pos) const {
|
||||||
assert(pos.piece_count(weakerSide, PAWN) == 0);
|
assert(pos.piece_count(weakerSide, PAWN) == 0);
|
||||||
assert(pos.piece_count(weakerSide, BISHOP) == 1);
|
assert(pos.piece_count(weakerSide, BISHOP) == 1);
|
||||||
|
|
||||||
Value result = mate_table(pos.king_square(weakerSide));
|
Value result = Value(MateTable[pos.king_square(weakerSide)]);
|
||||||
return strongerSide == pos.side_to_move() ? result : -result;
|
return strongerSide == pos.side_to_move() ? result : -result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,8 +351,8 @@ Value Endgame<Value, KRKN>::apply(const Position& pos) const {
|
||||||
|
|
||||||
int d = square_distance(defendingKSq, nSq);
|
int d = square_distance(defendingKSq, nSq);
|
||||||
Value result = Value(10)
|
Value result = Value(10)
|
||||||
+ mate_table(defendingKSq)
|
+ MateTable[defendingKSq]
|
||||||
+ krkn_king_knight_distance_penalty(d);
|
+ KRKNKingKnightDistancePenalty[d];
|
||||||
|
|
||||||
return strongerSide == pos.side_to_move() ? result : -result;
|
return strongerSide == pos.side_to_move() ? result : -result;
|
||||||
}
|
}
|
||||||
|
@ -392,8 +376,8 @@ Value Endgame<Value, KQKR>::apply(const Position& pos) const {
|
||||||
|
|
||||||
Value result = QueenValueEndgame
|
Value result = QueenValueEndgame
|
||||||
- RookValueEndgame
|
- RookValueEndgame
|
||||||
+ mate_table(loserKSq)
|
+ MateTable[loserKSq]
|
||||||
+ distance_bonus(square_distance(winnerKSq, loserKSq));
|
+ DistanceBonus[square_distance(winnerKSq, loserKSq)];
|
||||||
|
|
||||||
return strongerSide == pos.side_to_move() ? result : -result;
|
return strongerSide == pos.side_to_move() ? result : -result;
|
||||||
}
|
}
|
||||||
|
@ -413,7 +397,7 @@ Value Endgame<Value, KBBKN>::apply(const Position& pos) const {
|
||||||
Square nsq = pos.piece_list(weakerSide, KNIGHT, 0);
|
Square nsq = pos.piece_list(weakerSide, KNIGHT, 0);
|
||||||
|
|
||||||
// Bonus for attacking king close to defending king
|
// Bonus for attacking king close to defending king
|
||||||
result += distance_bonus(square_distance(wksq, bksq));
|
result += Value(DistanceBonus[square_distance(wksq, bksq)]);
|
||||||
|
|
||||||
// Bonus for driving the defending king and knight apart
|
// Bonus for driving the defending king and knight apart
|
||||||
result += Value(square_distance(bksq, nsq) * 32);
|
result += Value(square_distance(bksq, nsq) * 32);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
enum EndgameType {
|
enum EndgameType {
|
||||||
|
|
||||||
// Evaluation functions
|
// Evaluation functions
|
||||||
|
|
||||||
KXK, // Generic "mate lone king" eval
|
KXK, // Generic "mate lone king" eval
|
||||||
KBNK, // KBN vs K
|
KBNK, // KBN vs K
|
||||||
KPK, // KP vs K
|
KPK, // KP vs K
|
||||||
|
@ -43,7 +44,9 @@ enum EndgameType {
|
||||||
KNNK, // KNN vs K
|
KNNK, // KNN vs K
|
||||||
KmmKm, // K and two minors vs K and one or two minors
|
KmmKm, // K and two minors vs K and one or two minors
|
||||||
|
|
||||||
|
|
||||||
// Scaling functions
|
// Scaling functions
|
||||||
|
|
||||||
KBPsK, // KB+pawns vs K
|
KBPsK, // KB+pawns vs K
|
||||||
KQKRPs, // KQ vs KR+pawns
|
KQKRPs, // KQ vs KR+pawns
|
||||||
KRPKR, // KRP vs KR
|
KRPKR, // KRP vs KR
|
||||||
|
@ -57,7 +60,7 @@ enum EndgameType {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Base and derived template class for endgame evaluation and scaling functions
|
/// Base and derived templates for endgame evaluation and scaling functions
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct EndgameBase {
|
struct EndgameBase {
|
||||||
|
@ -88,8 +91,8 @@ private:
|
||||||
|
|
||||||
class Endgames {
|
class Endgames {
|
||||||
|
|
||||||
typedef std::map<Key, EndgameBase<Value>*> EFMap;
|
typedef std::map<Key, EndgameBase<Value>* > EFMap;
|
||||||
typedef std::map<Key, EndgameBase<ScaleFactor>*> SFMap;
|
typedef std::map<Key, EndgameBase<ScaleFactor>* > SFMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Endgames();
|
Endgames();
|
||||||
|
|
Loading…
Add table
Reference in a new issue