实现扫雷游戏的过程可以分为以下几个步骤:
-
创建游戏界面:使用二维数组表示游戏的格子,并初始化为未翻开状态。使用字符来表示未翻开的格子、地雷和数字。
-
随机布置地雷:使用随机数生成器在二维数组中随机选择位置,将地雷布置在其中。
-
计算周围地雷数量:遍历二维数组中的每个格子,对于每个非地雷的格子,统计周围8个格子中地雷的数量,并将该数字保存在该格子中。
-
主循环:进入游戏的主循环,每次循环需要进行以下操作:
- 显示游戏界面。
- 接收玩家的输入,包括翻开格子、标记地雷等。
- 根据玩家的输入更新游戏状态。
- 判断游戏是否结束,如果结束则显示游戏结果并退出循环。
-
根据玩家的输入更新游戏状态:根据玩家翻开的格子或标记的地雷,更新游戏界面的状态。如果翻开的格子是地雷,则游戏输掉;否则根据翻开的格子周围地雷数量进行递归地翻开周围的格子。
-
判断游戏是否结束:检查游戏界面中未翻开格子的数量,如果只剩下地雷格子,则游戏胜利;否则游戏继续。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
// 定义棋盘大小
#define ROWS 10
#define COLS 10
// 定义雷区标记
#define MINE -1
#define HIDDEN -2
// 初始化棋盘
void init_board(int board[][COLS], int rows, int cols, int mine_count) {
// 清空棋盘
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
board[i][j] = 0;
}
}
// 随机布雷
srand(time(NULL));
for(int k = 0; k < mine_count; k++) {
int row = rand() % rows;
int col = rand() % cols;
if(board[row][col] == MINE) {
k--;
continue;
}
board[row][col] = MINE;
}
}
// 显示棋盘
void display_board(int board[][COLS], int rows, int cols) {
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
if(board[i][j] == HIDDEN) {
printf("■ ");
} else if(board[i][j] == MINE) {
printf("* ");
} else {
printf("%d ", board[i][j]);
}
}
printf("\n");
}
}
// 计算某个位置周围雷的数量
int count_mines(int board[][COLS], int row, int col) {
int count = 0;
// 上方
if(row - 1 >= 0 && board[row - 1][col] == MINE) {
count++;
}
// 下方
if(row + 1 < ROWS && board[row + 1][col] == MINE) {
count++;
}
// 左方
if(col - 1 >= 0 && board[row][col - 1] == MINE) {
count++;
}
// 右方
if(col + 1 < COLS && board[row][col + 1] == MINE) {
count++;
}
// 左上方
if(row - 1 >= 0 && col - 1 >= 0 && board[row - 1][col - 1] == MINE) {
count++;
}
// 右上方
if(row - 1 >= 0 && col + 1 < COLS && board[row - 1][col + 1] == MINE) {
count++;
}
// 左下方
if(row + 1 < ROWS && col - 1 >= 0 && board[row + 1][col - 1] == MINE) {
count++;
}
// 右下方
if(row + 1 < ROWS && col + 1 < COLS && board[row + 1][col + 1] == MINE) {
count++;
}
return count;
}
// 点击某个位置
void click(int board[][COLS], int row, int col) {
// 检查边界
if(row < 0 || row >= ROWS || col < 0 || col >= COLS) {
return;
}
// 已经点击过或标记为雷的位置不处理
if(board[row][col] != HIDDEN) {
return;
}
// 判断该位置周围雷的数量
int count = count_mines(board, row, col);
if(count == 0) {
board[row][col] = 0;
// 递归点击周围的位置
click(board, row - 1, col);
click(board, row + 1, col);
click(board, row, col - 1);
click(board, row, col + 1);
click(board, row - 1, col - 1);
click(board, row - 1, col + 1);
click(board, row + 1, col - 1);
click(board, row + 1, col + 1);
} else {
board[row][col] = count;
}
}
int main() {
int board[ROWS][COLS];
int mine_count;
printf("请输入雷的数量:");
scanf("%d", &mine_count);
init_board(board, ROWS, COLS, mine_count);
display_board(board, ROWS, COLS);
int row, col;
while(1) {
printf("请输入要点击的位置(行 列):");
scanf("%d %d", &row, &col);
// 检查边界
if(row < 0 || row >= ROWS || col < 0 || col >= COLS) {
printf("输入位置不合法,请重新输入\n");
continue;
}
// 点击位置
click(board, row, col);
// 判断游戏是否结束
int is_gameover = 0;
for(int i = 0; i < ROWS; i++) {
for(int j = 0; j < COLS; j++) {
if(board[i][j] == MINE) {
is_gameover = 1;
break;
}
}
if(is_gameover) {
break;
}
}
// 显示棋盘
display_board(board, ROWS, COLS);
// 判断游戏是否结束
if(is_gameover) {
printf("游戏结束,你踩到雷了!\n");
break;
}
}
return 0;
}