Skip to content

Commit 848fae6

Browse files
authored
Fix antichess K vs N endgame evaluation (#909)
1 parent 4aef2ca commit 848fae6

1 file changed

Lines changed: 20 additions & 10 deletions

File tree

src/endgame.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,24 +1033,34 @@ Value Endgame<RK, EG_EVAL_ANTI>::operator()(const Position& pos) const {
10331033
}
10341034

10351035

1036-
/// K vs N. The king usally wins, but there are a few exceptions.
1036+
/// K vs N. The king usually wins, but there are a few exceptions.
10371037
template<>
10381038
Value Endgame<KN, EG_EVAL_ANTI>::operator()(const Position& pos) const {
10391039

10401040
assert(pos.endgame_eval() == EG_EVAL_ANTI);
10411041

10421042
Square KSq = pos.square<COMMONER>(strongSide);
10431043
Square NSq = pos.square<KNIGHT>(weakSide);
1044+
Bitboard kingAttacks = attacks_bb<KING>(KSq) & pos.board_bb();
1045+
Bitboard knightAttacks = attacks_bb<KNIGHT>(NSq) & pos.board_bb();
1046+
bool strongSideToMove = pos.side_to_move() == strongSide;
1047+
1048+
// Loss in 1 play
1049+
if (strongSideToMove ? kingAttacks & NSq : knightAttacks & KSq)
1050+
return VALUE_TB_LOSS_IN_MAX_PLY + 1;
1051+
// Win in 2 ply
1052+
if (kingAttacks & knightAttacks)
1053+
return VALUE_TB_WIN_IN_MAX_PLY - 2;
1054+
// Loss in 3 ply
1055+
if (strongSideToMove ? knightAttacks & KSq : kingAttacks & NSq)
1056+
return VALUE_TB_LOSS_IN_MAX_PLY + 3;
1057+
1058+
Value result = Value(push_to_edge(NSq, pos)) - push_to_edge(KSq, pos);
1059+
// The king usually wins, but scenarios with king on the edge are more complicated
1060+
if (!(KSq & (FileABB | FileHBB | Rank1BB | Rank8BB)))
1061+
result += VALUE_KNOWN_WIN;
10441062

1045-
// wins for knight
1046-
if (pos.side_to_move() == strongSide && (attacks_bb<KNIGHT>(NSq) & KSq))
1047-
return -VALUE_KNOWN_WIN;
1048-
if (pos.side_to_move() == weakSide && (attacks_bb<KNIGHT>(NSq) & attacks_bb<KING>(KSq)))
1049-
return VALUE_KNOWN_WIN;
1050-
1051-
Value result = VALUE_KNOWN_WIN + push_to_edge(NSq, pos) - push_to_edge(KSq, pos);
1052-
1053-
return strongSide == pos.side_to_move() ? result : -result;
1063+
return strongSideToMove ? result : -result;
10541064
}
10551065

10561066
/// N vs N. The side to move always wins/loses if the knights are on

0 commit comments

Comments
 (0)