/// KP vs K. This endgame is evaluated with the help of a bitbase. public Value KPK(Position pos) { Debug.Assert(verify_material(pos, strongSide, ValueS.VALUE_ZERO, 1)); Debug.Assert(verify_material(pos, weakSide, ValueS.VALUE_ZERO, 0)); // Assume strongSide is white and the pawn is on files A-D Square wksq = normalize(pos, strongSide, pos.king_square(strongSide)); Square bksq = normalize(pos, strongSide, pos.king_square(weakSide)); Square psq = normalize(pos, strongSide, pos.list(strongSide, PieceTypeS.PAWN)[0]); Color us = strongSide == pos.side_to_move() ? ColorS.WHITE : ColorS.BLACK; if (!Bitbases.probe_kpk(wksq, psq, bksq, us)) { return(ValueS.VALUE_DRAW); } Value result = ValueS.VALUE_KNOWN_WIN + ValueS.PawnValueEg + Types.rank_of(psq); return(strongSide == pos.side_to_move() ? result : -result); }
/// KP vs KP. This is done by removing the weakest side's pawn and probing the /// KP vs K bitbase: If the weakest side has a draw without the pawn, it probably /// has at least a draw with the pawn as well. The exception is when the stronger /// side's pawn is far advanced and not on a rook file; in this case it is often /// possible to win (e.g. 8/4k3/3p4/3P4/6K1/8/8/8 w - - 0 1). public ScaleFactor KPKP(Position pos) { Debug.Assert(verify_material(pos, strongSide, ValueS.VALUE_ZERO, 1)); Debug.Assert(verify_material(pos, weakSide, ValueS.VALUE_ZERO, 1)); // Assume strongSide is white and the pawn is on files A-D Square wksq = normalize(pos, strongSide, pos.king_square(strongSide)); Square bksq = normalize(pos, strongSide, pos.king_square(weakSide)); Square psq = normalize(pos, strongSide, pos.list(strongSide, PieceTypeS.PAWN)[0]); Color us = strongSide == pos.side_to_move() ? ColorS.WHITE : ColorS.BLACK; // 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. if (Types.rank_of(psq) >= RankS.RANK_5 && Types.file_of(psq) != FileS.FILE_A) { return(ScaleFactorS.SCALE_FACTOR_NONE); } // Probe the KPK bitbase with the weakest side's pawn removed. If it's a draw, // it's probably at least a draw even with the pawn. return(Bitbases.probe_kpk(wksq, psq, bksq, us) ? ScaleFactorS.SCALE_FACTOR_NONE : ScaleFactorS.SCALE_FACTOR_DRAW); }