扫雷 java版本


import java.util.*;
public class Game {

    private static int[][] originalMap;//原始地图,记录地雷坐标
    private static int[][] scanMap;//扫描地图,扫描用于记录格子对应的周围地雷数量
    private static int height = 10;//地图高度
    private static int width = 10;//地图宽度
    private static int mine = 10;//地雷数量

    private final static String myFormat = "%3s";

    public static void main(String[] args) throws Exception {
        Scanner scanner = null;
        System.out.println("请输入地图的宽度和高度和地雷数量,示例:  10,10,7");
        try {
            scanner = new Scanner(System.in);
            String inputString = scanner.nextLine();
            String[] split = inputString.split(",");
            try {
                width = Integer.parseInt(split[0]);
                height = Integer.parseInt(split[1]);
                mine = Integer.parseInt(split[2]);
            } catch (Exception e) {
                System.out.println("地图输入异常,使用默认格式 15,15,45");
                width = 15;
                height = 15;
                mine = 45;
            }
            init();//初始化地图大小并且埋入地雷
            while (true) {
                System.out.println("请输入当前排查地雷坐标 x,y 示例: 2,2");
                AbstractMap.SimpleEntry<Integer, Integer> coordinate = inputCoordinate(scanner);
                exec(coordinate);//排雷
                System.out.println("当前地图: ");
                show();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (scanner != null)
                scanner.close();
        }


    }

    private static AbstractMap.SimpleEntry<Integer, Integer> inputCoordinate(Scanner scanner) {
        String inputString = scanner.nextLine();
        String[] split = inputString.split(",");
        if (split.length != 2) {
            System.out.println("输入坐标格式错误,请重新输入 示例:  3,5");
            return inputCoordinate(scanner);
        }
        AbstractMap.SimpleEntry<Integer, Integer> coordinate = new HashMap.SimpleEntry<>(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
        if (!isSurpass(coordinate)) {
            System.out.println("输入的坐标操过界限,请重新输入");
            return inputCoordinate(scanner);
        } else {
            return coordinate;
        }
    }

    private static void show() {
        //显示探索地图

        for (int i = height - 1; i >= 0; i--) {
            System.out.printf(myFormat, i);
            System.out.printf(myFormat, "|");
            for (int j = 0; j < width; j++) {
                String tmp;
                if (scanMap[j][i] == -1) {
                    tmp = "?";
                } else if (scanMap[j][i] == 0) {
                    tmp = "0";
                } else {
                    tmp = String.valueOf(scanMap[j][i]);
                }

                System.out.printf(myFormat, tmp);
            }
            System.out.println();
        }
        System.out.printf(myFormat, "y");
        System.out.printf(myFormat, "/");
        for (int j = 0; j < width; j++) {
            System.out.printf(myFormat, "-");
        }
        System.out.println();

        System.out.printf(myFormat, " ");
        System.out.printf(myFormat, "x");
        for (int j = 0; j < width; j++) {
            System.out.printf(myFormat, j);
        }
        System.out.println();
    }


    /**
     * 初始化地图大小并且埋入地雷
     *
     * @throws Exception 地雷过多
     */
    private static void init() throws Exception {
        if (mine > (height * width * 0.4)) {
            throw new Exception("地雷数量太多,当前地图太拥挤,请增加地图大小或者降低地图中的地雷数量");
        }
        originalMap = new int[width][height];//初始化地图大小
        scanMap = new int[width][height];
        //初始化地图与扫描图
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                originalMap[i][j] = 0;//初始化地图的一个点 记录当前格子是否有地雷
                scanMap[i][j] = -1;//初始化扫描图的一个点 数字表示周围一圈的地雷数量,-1表示当前格子没有探索过
            }
        }
        for (int i = 0; i < mine; i++) {//放地雷到地图中
            setMine();//放地雷
        }
    }


    /**
     * 往地图中随机埋入单个地雷
     * 如果埋入地雷的位置已经有地雷了 重新找位置埋入地雷
     */
    private static void setMine() {
        //随机得到埋雷的坐标
        double heightRandom = Math.random();//获取0~1之间的小数
        double widthRandom = Math.random();//获取0~1之间的小数
        long heightRound = Math.round((height - 1) * heightRandom);
        long widthRound = Math.round((width - 1) * widthRandom);
        int heightRoundInt = (int) heightRound;//横坐标
        int widthRoundInt = (int) widthRound;//纵坐标
        if (originalMap[heightRoundInt][widthRoundInt] == 0) {//找地方埋雷
            //如果没有地雷,直接埋入
            originalMap[heightRoundInt][widthRoundInt] = 1;
        } else {
            //如果有地雷,重新再埋入一次
            setMine();//当前位置已经有地雷,重新找地方埋雷
        }
    }

    private static void exec(AbstractMap.SimpleEntry<Integer, Integer> coordinate) throws Exception {
        if (scanMap[coordinate.getKey()][coordinate.getValue()] != -1) {//只能探索未探索的格子
            return;
        }

        if (originalMap[coordinate.getKey()][coordinate.getValue()] == 1) {
            throw new Exception("踩到地雷");
        } else {//当前格子没有地雷,自动向四周探索一圈
            //获取周围一圈未被探索的坐标,并且在地图中的坐标
            List<AbstractMap.SimpleEntry<Integer, Integer>> coordinateArray = getCoordinateArray(coordinate);//
            //判断雷数量
            int aroundMineSum = 0;//周围雷数量
            for (AbstractMap.SimpleEntry<Integer, Integer> tuple2 : coordinateArray) {
                if (originalMap[tuple2.getKey()][tuple2.getValue()] == 1) aroundMineSum++;
            }
            //记录当前探索的格子标记地雷数量
            scanMap[coordinate.getKey()][coordinate.getValue()] = aroundMineSum;
            if (aroundMineSum != 0) return; //如果周围有雷跳过 否则扩大一圈
            for (AbstractMap.SimpleEntry<Integer, Integer> tuple2 : coordinateArray) {
                exec(tuple2);
            }
        }
    }

    /**
     * 当前坐标是否在越内
     *
     * @param coordinate 当前坐标点
     * @return 是否越界
     */
    public static boolean isSurpass(AbstractMap.SimpleEntry<Integer, Integer> coordinate) {
        return coordinate.getKey() >= 0 && coordinate.getKey() < width && coordinate.getValue() >= 0 && coordinate.getValue() < height;
    }

    /**
     * 当前坐标是否未探索
     *
     * @param coordinate 当前坐标点
     * @return 是否探索
     */
    public static boolean isExplore(AbstractMap.SimpleEntry<Integer, Integer> coordinate) {
        return scanMap[coordinate.getKey()][coordinate.getValue()] == -1;
    }


    private static List<AbstractMap.SimpleEntry<Integer, Integer>> getCoordinateArray(AbstractMap.SimpleEntry<Integer, Integer> coordinate) {
        int x = coordinate.getKey();
        int y = coordinate.getValue();
        //获取周围一圈的坐标

        AbstractMap.SimpleEntry<Integer, Integer> LeftUpper = new HashMap.SimpleEntry<>(coordinate.getKey() - 1, coordinate.getValue() + 1);
        AbstractMap.SimpleEntry<Integer, Integer> inUpper = new HashMap.SimpleEntry<>(coordinate.getKey(), coordinate.getValue() + 1);
        AbstractMap.SimpleEntry<Integer, Integer> rightUpper = new HashMap.SimpleEntry<>(coordinate.getKey() + 1, coordinate.getValue() + 1);


        AbstractMap.SimpleEntry<Integer, Integer> LeftIn = new HashMap.SimpleEntry<>(coordinate.getKey() - 1, coordinate.getValue());
        AbstractMap.SimpleEntry<Integer, Integer> rightIn = new HashMap.SimpleEntry<>(coordinate.getKey() + 1, coordinate.getValue());

        AbstractMap.SimpleEntry<Integer, Integer> LeftLower = new HashMap.SimpleEntry<>(coordinate.getKey() - 1, coordinate.getValue() - 1);
        AbstractMap.SimpleEntry<Integer, Integer> inLower = new HashMap.SimpleEntry<>(coordinate.getKey(), coordinate.getValue() - 1);
        AbstractMap.SimpleEntry<Integer, Integer> rightLower = new HashMap.SimpleEntry<>(coordinate.getKey() + 1, coordinate.getValue() - 1);
        List<AbstractMap.SimpleEntry<Integer, Integer>> coordinateArray = new ArrayList<>();
        if (isSurpass(LeftUpper) && isExplore(LeftUpper)) {
            coordinateArray.add(LeftUpper);
        }
        if (isSurpass(inUpper) && isExplore(inUpper)) {
            coordinateArray.add(inUpper);
        }
        if (isSurpass(rightUpper) && isExplore(rightUpper)) {
            coordinateArray.add(rightUpper);
        }
        if (isSurpass(LeftIn) && isExplore(LeftIn)) {
            coordinateArray.add(LeftIn);
        }
        if (isSurpass(rightIn) && isExplore(rightIn)) {
            coordinateArray.add(rightIn);
        }
        if (isSurpass(LeftLower) && isExplore(LeftLower)) {
            coordinateArray.add(LeftLower);
        }
        if (isSurpass(inLower) && isExplore(inLower)) {
            coordinateArray.add(inLower);
        }
        if (isSurpass(rightLower) && isExplore(rightLower)) {
            coordinateArray.add(rightLower);
        }
        return coordinateArray;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小钻风巡山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值