实现扫雷游戏:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 10 // 游戏区域大小
#define MINES 10 // 雷的数量
int isMine(int board[SIZE][SIZE], int row, int col) {
// 检查一个方格是否是雷
if (board[row][col] == -1) {
return 1;
} else {
return 0;
}
}
int countMines(int board[SIZE][SIZE], int row, int col) {
// 计算某个方格周围的雷的数量
int i, j;
int count = 0;
for (i = row - 1; i <= row + 1; i++) {
for (j = col - 1; j <= col + 1; j++) {
// 忽略超出边界的方格
if (i < 0 || i >= SIZE || j < 0 || j >= SIZE) {
continue;
}
if (isMine(board, i, j)) {
count++;
}
}
}
return count;
}
void printBoard(int board[SIZE][SIZE], int showMines) {
// 打印游戏板
int row, col;
printf(" ");
for (col = 0; col < SIZE; col++) {
printf("%2d ", col);
}
printf("\n");
for (row = 0; row < SIZE; row++) {
printf("%2d ", row);
for (col = 0; col < SIZE; col++) {
if (board[row][col] == -1 && showMines) {
printf("* "); // 显示雷
} else if (board[row][col] == -1) {
printf(". "); // 隐藏雷
} else {
printf("%d ", board[row][col]);
}
}
printf("\n");
}
}
int main() {
int board[SIZE][SIZE]; // 游戏板
int revealed[SIZE][SIZE] = {0}; // 记录被揭开的方格
int row, col, remaining;
// 初始化游戏板
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++) {
board[row][col] = 0; // 先将每个方格设置为0
}
}
// 随机放置雷
srand(time(0));
for (int i = 0; i < MINES; i++) {
int randRow = rand() % SIZE;
int randCol = rand() % SIZE;
board[randRow][randCol] = -1; // -1 表示雷
}
remaining = SIZE * SIZE - MINES; // 剩余未揭开的方格数量
printf("欢迎来到扫雷游戏!\n");
printf("输入坐标(行 列)来揭开一个方格。\n");
printf("例如,输入 \"3 4\" 来揭开第 3 行第 4 列的方格。\n");
// 游戏主循环
while (remaining > 0) {
printBoard(revealed, 0); // 打印游戏板(隐藏雷的情况)
printf("剩余方格数量:%d\n", remaining);
printf("请揭开一个方格:");
scanf("%d %d", &row, &col);
// 检查坐标是否合法
if (row < 0 || row >= SIZE || col < 0 || col >= SIZE) {
printf("无效的方格,请重新输入。\n");
continue;
}
// 如果已经揭开了该方格,则忽略
if (revealed[row][col]) {
printf("该方格已经揭开,请选择其他方格。\n");
continue;
}
// 如果揭开的是雷,游戏结束
if (isMine(board, row, col)) {
printBoard(board, 1); // 打印游戏板(显示雷的情况)
printf("很遗憾,你揭开了一个雷,游戏结束!\n");
break;
} else {
// 计算揭开方格周围的雷的数量
int numMines = countMines(board, row, col);
board[row][col] = numMines;
revealed[row][col] = 1;
remaining--;
// 如果揭开的方格周围没有雷,自动揭开周围的方格
if (numMines == 0) {
for (int i = row - 1; i <= row + 1; i++) {
for (int j = col - 1; j <= col + 1; j++) {
// 忽略超出边界的方格
if (i < 0 || i >= SIZE || j < 0 || j >= SIZE) {
continue;
}
// 如果方格未被揭开,则递归揭开
if (!revealed[i][j]) {
revealed[i][j] = 1;
remaining--;
// 如果揭开的方格周围没有雷,继续自动揭开周围的方格
if (countMines(board, i, j) == 0) {
// 使用递归来揭开周围的方格
// 这里可能导致栈溢出,可以使用循环实现相同的效果
// 例如,使用一个栈结构来保存待揭开的方格坐标
// while (stack.isNotEmpty()) {
// int r = stack.pop();
// int c = stack.pop();
// ...
// }
// 这里为了简化代码,使用了递归
main();
}
}
}
}
}
}
}
// 游戏结束,打印最终游戏板
if (remaining == 0) {
printf("恭喜你,你成功揭开了所有方格!\n");
}
printf("游戏结束!再玩一次吗?(Y/N):");
char choice;
scanf(" %c", &choice);
// 如果玩家选择继续玩,则重新开始游戏
if (choice == 'y' || choice == 'Y') {
main();
}
return 0;
}