// Map the square as if strongSide is white and strongSide's only pawn // is on the left half of the board. public Square normalize(Position pos, Color strongSide, Square sq) { Debug.Assert(pos.count(strongSide, PieceTypeS.PAWN) == 1); if (Types.file_of(pos.list(strongSide, PieceTypeS.PAWN)[0]) >= FileS.FILE_E) { sq = (Square)(sq ^ 7); // Mirror SQ_H1 -> SQ_A1 } if (strongSide == ColorS.BLACK) { sq = Types.notSquare(sq); } return(sq); }
/// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the /// defending king towards a corner square of the right color. public Value KBNK(Position pos) { Debug.Assert(verify_material(pos, strongSide, ValueS.KnightValueMg + ValueS.BishopValueMg, 0)); Debug.Assert(verify_material(pos, weakSide, ValueS.VALUE_ZERO, 0)); Square winnerKSq = pos.king_square(strongSide); Square loserKSq = pos.king_square(weakSide); Square bishopSq = pos.list(strongSide, PieceTypeS.BISHOP)[0]; // kbnk_mate_table() tries to drive toward corners A1 or H8. If we have a // bishop that cannot reach the above squares, we flip the kings in order // to drive the enemy toward corners A8 or H1. if (Types.opposite_colors(bishopSq, SquareS.SQ_A1)) { winnerKSq = Types.notSquare(winnerKSq); loserKSq = Types.notSquare(loserKSq); } Value result = ValueS.VALUE_KNOWN_WIN + PushClose[BitBoard.square_distance(winnerKSq, loserKSq)] + PushToCorners[loserKSq]; return(strongSide == pos.side_to_move() ? result : -result); }