需求

初始化:
1、Scanner输入
2、随机生成器
3、行列数,地雷数(可输入生成)
4、存放地雷的二维数组
5、游戏界面数组
6、游戏获胜or失败条件

步骤:
1、随机生成地雷位置
2、填充游戏界面

3、输入要点击的位置(行列号)

4、点到的是地雷,设置flag,游戏结束
4.1、点到不是地雷,显示周围地雷数量
如果是0,则扫码周围未点且不是雷的方块
获取它周围地雷数并标注,若还是0,递归翻开

5、全部翻开,则结束游戏

import java.util.*;
public class Main {
    static int remainCount;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Random random = new Random();

        int rows = 5; // 行数
        int cols = 5; // 列数
        int mineCount = 4; // 地雷数量
        remainCount = rows*cols - mineCount; // 可点的方块数量

        boolean isGameOver = false;

        int[][] mines = new int[rows][cols]; // 存放地雷位置信息的数组,0表示该位置无地雷,1表示该位置有地雷
        char[][] board = new char[rows][cols]; // 存放游戏界面信息的数组,'-'表示未翻开的方块,'*'表示有地雷的方块,数字表示该方块周围地雷数量

        Arrays.stream(board).forEach(row -> Arrays.fill(row, '-')); // 初始化每个位置为'-'

        // 随机生成地雷位置
        for (int i = 0; i < mineCount; i++) {
            int row, col;
            do {
                row = random.nextInt(rows);
                col = random.nextInt(cols);

            } while (mines[row][col] == 1); // 如果当前位置已经有地雷,则重新生成

            mines[row][col] = 1;
        }

        while (!isGameOver) {
            System.out.println("剩余空的数量:"+ remainCount);
            displayBoard(board, mines, isGameOver);

            System.out.print("请输入要翻开的行号和列号(用空格隔开):");
            int row = scanner.nextInt();
            int col = scanner.nextInt();

            if (row >= rows || row < 0 || col >= cols || col < 0) {
                System.out.println("别皮,请输入行列0~"+ (rows-1) +"的数!");
                continue;
            }

            if (mines[row][col] == 1) { // 点到地雷,游戏结束
                System.out.println("很遗憾,你点到了地雷!");
                isGameOver = true;
            } else { // 没有点到地雷
                int count = getMineCount(mines, row, col);
                board[row][col] = (char) (count + '0'); // 将周围地雷数量转换成字符并显示在界面上
                remainCount--; 
                
                if (count == 0) { // 如果周围没有地雷,则翻开周围的方块
                    openSurrounding(board, mines, row, col);
                }

                if (checkWin()) { // 如果所有非地雷方块都已经被翻开,则游戏胜利
                    System.out.println("恭喜你获得了胜利!");
                    isGameOver = true;
                }
            }
        }

        displayBoard(board, mines, isGameOver);

        scanner.close();
    }

    /**
     * 在控制台上显示当前游戏界面
     */
    public static void displayBoard(char[][] board, int[][]mines, boolean isGameOver) {
        // 若游戏结束,则显示所有的雷
        if (isGameOver) {
            for (int i = 0; i < board.length; i++) {
                for (int j = 0; j < board[0].length; j++) {
                    if (mines[i][j] == 1) {
                        board[i][j] = '*';
                    }
                }
            }
        }

        System.out.print("   ");
        for (int i = 0; i < board[0].length; i++) {
            System.out.print(i + " ");
        }
        System.out.println();

        for (int i = 0; i < board.length; i++) {
            System.out.print(i + " |");
            for (int j = 0; j < board[0].length; j++) {
                System.out.print(board[i][j] + "|");
            }
            System.out.println();
        }
    }

    /**
     * 获取某个方块周围地雷的数量
     */
    public static int getMineCount(int[][] mines, int row, int col) {
        int count = 0;
        for (int i = Math.max(row - 1, 0); i <= Math.min(row + 1, mines.length - 1); i++) {
            for (int j = Math.max(col - 1, 0); j <= Math.min(col + 1, mines[0].length - 1); j++) {
                if (mines[i][j] == 1) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 翻开周围的方块(如果周围没有地雷)
     */
    public static void openSurrounding(char[][] board, int[][] mines, int row, int col) {
        for (int i = Math.max(row - 1, 0); i <= Math.min(row + 1, board.length - 1); i++) {
            for (int j = Math.max(col - 1, 0); j <= Math.min(col + 1, board[0].length - 1); j++) {
                if (board[i][j] == '-' && mines[i][j] == 0) { // 如果当前方块未翻开且周围没有地雷,则将其翻开
                    int count = getMineCount(mines, i, j);
                    board[i][j] = (char) (count + '0');
                    remainCount--;

                    if (count == 0) { // 如果翻开的方块周围没有地雷,则递归翻开周围的方块
                        openSurrounding(board, mines, i, j);
                    }
                }
            }
        }
    }

    /**
     * 检查是否所有非地雷方块都已经被翻开
     */
    public static boolean checkWin() {
        return remainCount == 0;
    }
}

后期优化

  • 行列数自动设置,雷数量自动生成
  • 优化点开0周围的九宫递归调用