mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 16:53:09 +00:00
Rewrite KBBKN endgame
This was thought to be a draw but the bishops generally win. However, it takes up to 66 moves. The position in the diagram was thought to be a draw for over one hundred years, but tablebases show that White wins in 45 moves. All of the long wins go through this type of semi-fortress position. It takes several moves to force Black out of the temporary fortress in the corner; then precise play with the bishops prevents Black from forming the temporary fortress in another corner (Nunn 1995:265ff). Before computer analysis, Speelman listed this position as unresolved, but "probably a draw" (Speelman 1981:109). bench: 3453945
This commit is contained in:
parent
849b089a63
commit
9ff594c3a9
1 changed files with 13 additions and 8 deletions
|
@ -57,7 +57,7 @@ namespace {
|
||||||
|
|
||||||
// Tables used to drive a piece towards or away from another piece
|
// Tables used to drive a piece towards or away from another piece
|
||||||
const int PushClose[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
|
const int PushClose[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
|
||||||
const int PushAway [8] = { 0, 10, 14, 20, 30, 42, 58, 80 };
|
const int PushAway [8] = { 0, 5, 20, 40, 60, 80, 90, 100 };
|
||||||
|
|
||||||
// Get the material key of a Position out of the given endgame key code
|
// Get the material key of a Position out of the given endgame key code
|
||||||
// like "KBPKN". The trick here is to first forge an ad-hoc fen string
|
// like "KBPKN". The trick here is to first forge an ad-hoc fen string
|
||||||
|
@ -365,6 +365,11 @@ Value Endgame<KQKR>::operator()(const Position& pos) const {
|
||||||
return strongerSide == pos.side_to_move() ? result : -result;
|
return strongerSide == pos.side_to_move() ? result : -result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// KBB vs KN. This is almost always a win. We try to push enemy king to a corner
|
||||||
|
/// and away from his knight. For a reference of this difficult endgame see:
|
||||||
|
/// en.wikipedia.org/wiki/Chess_endgame#Effect_of_tablebases_on_endgame_theory
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
Value Endgame<KBBKN>::operator()(const Position& pos) const {
|
Value Endgame<KBBKN>::operator()(const Position& pos) const {
|
||||||
|
|
||||||
|
@ -374,14 +379,14 @@ Value Endgame<KBBKN>::operator()(const Position& pos) const {
|
||||||
assert(pos.count<KNIGHT>(weakerSide ) == 1);
|
assert(pos.count<KNIGHT>(weakerSide ) == 1);
|
||||||
assert(!pos.pieces(PAWN));
|
assert(!pos.pieces(PAWN));
|
||||||
|
|
||||||
Square wksq = pos.king_square(strongerSide);
|
Square winnerKSq = pos.king_square(strongerSide);
|
||||||
Square bksq = pos.king_square(weakerSide);
|
Square loserKSq = pos.king_square(weakerSide);
|
||||||
Square nsq = pos.list<KNIGHT>(weakerSide)[0];
|
Square knightSq = pos.list<KNIGHT>(weakerSide)[0];
|
||||||
|
|
||||||
Value result = BishopValueEg
|
Value result = VALUE_KNOWN_WIN
|
||||||
+ PushClose[square_distance(wksq, bksq)]
|
+ PushToCorners[loserKSq]
|
||||||
+ square_distance(bksq, nsq) * 32
|
+ PushClose[square_distance(winnerKSq, loserKSq)]
|
||||||
+ (8 - popcount<Max15>(pos.attacks_from<KNIGHT>(nsq))) * 8;
|
+ PushAway[square_distance(loserKSq, knightSq)];
|
||||||
|
|
||||||
return strongerSide == pos.side_to_move() ? result : -result;
|
return strongerSide == pos.side_to_move() ? result : -result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue