mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 08:43:09 +00:00
Use flip_sq idea in endgame.cpp
The normalising transformation is computed all at once by the helper function get_flip_sq and then applied immediately to the relevant squares as soon as they are loaded from the position class. bench: 8350690
This commit is contained in:
parent
72f7282ad4
commit
3674f18b97
1 changed files with 47 additions and 80 deletions
127
src/endgame.cpp
127
src/endgame.cpp
|
@ -174,11 +174,11 @@ Value Endgame<KBNK>::operator()(const Position& pos) const {
|
||||||
|
|
||||||
// kbnk_mate_table() tries to drive toward corners A1 or H8,
|
// kbnk_mate_table() tries to drive toward corners A1 or H8,
|
||||||
// if we have a bishop that cannot reach the above squares we
|
// if we have a bishop that cannot reach the above squares we
|
||||||
// mirror the kings so to drive enemy toward corners A8 or H1.
|
// flip the kings so to drive enemy toward corners A8 or H1.
|
||||||
if (opposite_colors(bishopSq, SQ_A1))
|
if (opposite_colors(bishopSq, SQ_A1))
|
||||||
{
|
{
|
||||||
winnerKSq = mirror(winnerKSq);
|
winnerKSq = ~winnerKSq;
|
||||||
loserKSq = mirror(loserKSq);
|
loserKSq = ~loserKSq;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value result = VALUE_KNOWN_WIN
|
Value result = VALUE_KNOWN_WIN
|
||||||
|
@ -188,6 +188,22 @@ Value Endgame<KBNK>::operator()(const Position& pos) const {
|
||||||
return strongSide == pos.side_to_move() ? result : -result;
|
return strongSide == pos.side_to_move() ? result : -result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a square that will allow us to orient the board so that
|
||||||
|
// strongSide is white and strongSide's only pawn is on the left
|
||||||
|
// half of the board
|
||||||
|
Square get_flip_sq(const Position& pos, Color strongSide) {
|
||||||
|
|
||||||
|
assert(pos.count<PAWN>(strongSide) == 1);
|
||||||
|
|
||||||
|
Square psq = pos.list<PAWN>(strongSide)[0];
|
||||||
|
|
||||||
|
return (FILE_H * (file_of(psq) >= FILE_E)) | (RANK_8 * int(strongSide));
|
||||||
|
}
|
||||||
|
|
||||||
|
Square operator^(Square s, Square flip_sq) {
|
||||||
|
assert(flip_sq == SQ_A1 || flip_sq == SQ_H1 || flip_sq == SQ_A8 || flip_sq == SQ_H8);
|
||||||
|
return Square(int(s) ^ int(flip_sq));
|
||||||
|
}
|
||||||
|
|
||||||
/// 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<>
|
template<>
|
||||||
|
@ -196,25 +212,14 @@ Value Endgame<KPK>::operator()(const Position& pos) const {
|
||||||
assert(verify_material(pos, strongSide, VALUE_ZERO, 1));
|
assert(verify_material(pos, strongSide, VALUE_ZERO, 1));
|
||||||
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
||||||
|
|
||||||
Square wksq = pos.king_square(strongSide);
|
// Assume strongSide is white and the pawn is on files A-D
|
||||||
Square bksq = pos.king_square(weakSide);
|
Square flip_sq = get_flip_sq(pos, strongSide);
|
||||||
Square psq = pos.list<PAWN>(strongSide)[0];
|
|
||||||
Color us = pos.side_to_move();
|
|
||||||
|
|
||||||
if (strongSide == BLACK)
|
Square wksq = pos.king_square(strongSide) ^ flip_sq;
|
||||||
{
|
Square bksq = pos.king_square(weakSide) ^ flip_sq;
|
||||||
wksq = ~wksq;
|
Square psq = pos.list<PAWN>(strongSide)[0] ^ flip_sq;
|
||||||
bksq = ~bksq;
|
|
||||||
psq = ~psq;
|
|
||||||
us = ~us;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_of(psq) >= FILE_E)
|
Color us = strongSide == pos.side_to_move() ? WHITE : BLACK;
|
||||||
{
|
|
||||||
wksq = mirror(wksq);
|
|
||||||
bksq = mirror(bksq);
|
|
||||||
psq = mirror(psq);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Bitbases::probe_kpk(wksq, psq, bksq, us))
|
if (!Bitbases::probe_kpk(wksq, psq, bksq, us))
|
||||||
return VALUE_DRAW;
|
return VALUE_DRAW;
|
||||||
|
@ -235,18 +240,10 @@ Value Endgame<KRKP>::operator()(const Position& pos) const {
|
||||||
assert(verify_material(pos, strongSide, RookValueMg, 0));
|
assert(verify_material(pos, strongSide, RookValueMg, 0));
|
||||||
assert(verify_material(pos, weakSide, VALUE_ZERO, 1));
|
assert(verify_material(pos, weakSide, VALUE_ZERO, 1));
|
||||||
|
|
||||||
Square wksq = pos.king_square(strongSide);
|
Square wksq = relative_square(strongSide, pos.king_square(strongSide));
|
||||||
Square bksq = pos.king_square(weakSide);
|
Square bksq = relative_square(strongSide, pos.king_square(weakSide));
|
||||||
Square rsq = pos.list<ROOK>(strongSide)[0];
|
Square rsq = relative_square(strongSide, pos.list<ROOK>(strongSide)[0]);
|
||||||
Square psq = pos.list<PAWN>(weakSide)[0];
|
Square psq = relative_square(strongSide, pos.list<PAWN>(weakSide)[0]);
|
||||||
|
|
||||||
if (strongSide == BLACK)
|
|
||||||
{
|
|
||||||
wksq = ~wksq;
|
|
||||||
bksq = ~bksq;
|
|
||||||
rsq = ~rsq;
|
|
||||||
psq = ~psq;
|
|
||||||
}
|
|
||||||
|
|
||||||
Square queeningSq = file_of(psq) | RANK_1;
|
Square queeningSq = file_of(psq) | RANK_1;
|
||||||
Value result;
|
Value result;
|
||||||
|
@ -486,31 +483,14 @@ ScaleFactor Endgame<KRPKR>::operator()(const Position& pos) const {
|
||||||
assert(verify_material(pos, strongSide, RookValueMg, 1));
|
assert(verify_material(pos, strongSide, RookValueMg, 1));
|
||||||
assert(verify_material(pos, weakSide, RookValueMg, 0));
|
assert(verify_material(pos, weakSide, RookValueMg, 0));
|
||||||
|
|
||||||
Square wksq = pos.king_square(strongSide);
|
// Assume strongSide is white and the pawn is on files A-D
|
||||||
Square bksq = pos.king_square(weakSide);
|
Square flip_sq = get_flip_sq(pos, strongSide);
|
||||||
Square wrsq = pos.list<ROOK>(strongSide)[0];
|
|
||||||
Square wpsq = pos.list<PAWN>(strongSide)[0];
|
|
||||||
Square brsq = pos.list<ROOK>(weakSide)[0];
|
|
||||||
|
|
||||||
// Orient the board in such a way that the stronger side is white, and the
|
Square wksq = pos.king_square(strongSide) ^ flip_sq;
|
||||||
// pawn is on the left half of the board.
|
Square bksq = pos.king_square(weakSide) ^ flip_sq;
|
||||||
if (strongSide == BLACK)
|
Square wrsq = pos.list<ROOK>(strongSide)[0] ^ flip_sq;
|
||||||
{
|
Square wpsq = pos.list<PAWN>(strongSide)[0] ^ flip_sq;
|
||||||
wksq = ~wksq;
|
Square brsq = pos.list<ROOK>(weakSide)[0] ^ flip_sq;
|
||||||
wrsq = ~wrsq;
|
|
||||||
wpsq = ~wpsq;
|
|
||||||
bksq = ~bksq;
|
|
||||||
brsq = ~brsq;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_of(wpsq) > FILE_D)
|
|
||||||
{
|
|
||||||
wksq = mirror(wksq);
|
|
||||||
wrsq = mirror(wrsq);
|
|
||||||
wpsq = mirror(wpsq);
|
|
||||||
bksq = mirror(bksq);
|
|
||||||
brsq = mirror(brsq);
|
|
||||||
}
|
|
||||||
|
|
||||||
File f = file_of(wpsq);
|
File f = file_of(wpsq);
|
||||||
Rank r = rank_of(wpsq);
|
Rank r = rank_of(wpsq);
|
||||||
|
@ -852,15 +832,13 @@ ScaleFactor Endgame<KNPK>::operator()(const Position& pos) const {
|
||||||
assert(verify_material(pos, strongSide, KnightValueMg, 1));
|
assert(verify_material(pos, strongSide, KnightValueMg, 1));
|
||||||
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
||||||
|
|
||||||
Square pawnSq = pos.list<PAWN>(strongSide)[0];
|
// Assume strongSide is white and the pawn is on files A-D
|
||||||
Square weakKingSq = pos.king_square(weakSide);
|
Square flip_sq = get_flip_sq(pos, strongSide);
|
||||||
|
|
||||||
if ( pawnSq == relative_square(strongSide, SQ_A7)
|
Square pawnSq = pos.list<PAWN>(strongSide)[0] ^ flip_sq;
|
||||||
&& square_distance(weakKingSq, relative_square(strongSide, SQ_A8)) <= 1)
|
Square weakKingSq = pos.king_square(weakSide) ^ flip_sq;
|
||||||
return SCALE_FACTOR_DRAW;
|
|
||||||
|
|
||||||
if ( pawnSq == relative_square(strongSide, SQ_H7)
|
if (pawnSq == SQ_A7 && square_distance(SQ_A8, weakKingSq) <= 1)
|
||||||
&& square_distance(weakKingSq, relative_square(strongSide, SQ_H8)) <= 1)
|
|
||||||
return SCALE_FACTOR_DRAW;
|
return SCALE_FACTOR_DRAW;
|
||||||
|
|
||||||
return SCALE_FACTOR_NONE;
|
return SCALE_FACTOR_NONE;
|
||||||
|
@ -896,25 +874,14 @@ ScaleFactor Endgame<KPKP>::operator()(const Position& pos) const {
|
||||||
assert(verify_material(pos, strongSide, VALUE_ZERO, 1));
|
assert(verify_material(pos, strongSide, VALUE_ZERO, 1));
|
||||||
assert(verify_material(pos, weakSide, VALUE_ZERO, 1));
|
assert(verify_material(pos, weakSide, VALUE_ZERO, 1));
|
||||||
|
|
||||||
Square wksq = pos.king_square(strongSide);
|
// Assume strongSide is white and the pawn is on files A-D
|
||||||
Square bksq = pos.king_square(weakSide);
|
Square flip_sq = get_flip_sq(pos, strongSide);
|
||||||
Square psq = pos.list<PAWN>(strongSide)[0];
|
|
||||||
Color us = pos.side_to_move();
|
|
||||||
|
|
||||||
if (strongSide == BLACK)
|
Square wksq = pos.king_square(strongSide) ^ flip_sq;
|
||||||
{
|
Square bksq = pos.king_square(weakSide) ^ flip_sq;
|
||||||
wksq = ~wksq;
|
Square psq = pos.list<PAWN>(strongSide)[0] ^ flip_sq;
|
||||||
bksq = ~bksq;
|
|
||||||
psq = ~psq;
|
|
||||||
us = ~us;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_of(psq) >= FILE_E)
|
Color us = strongSide == pos.side_to_move() ? WHITE : BLACK;
|
||||||
{
|
|
||||||
wksq = mirror(wksq);
|
|
||||||
bksq = mirror(bksq);
|
|
||||||
psq = mirror(psq);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the pawn has advanced to the fifth rank or further, and is not a
|
// If the pawn has advanced to the fifth rank or further, and is not a
|
||||||
// rook pawn, it's too dangerous to assume that it's at least a draw.
|
// rook pawn, it's too dangerous to assume that it's at least a draw.
|
||||||
|
|
Loading…
Add table
Reference in a new issue