// 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);
        }