需求
初始化:
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周围的九宫递归调用