用C写一个功能完备的扫雷游戏
时间: 2023-06-14 13:02:29 浏览: 37
以下是一个简单的扫雷游戏的C代码,实现了基本的功能:
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 10
#define COL 10
#define N 10
int mine[ROW][COL] = {0}; //雷区
int map[ROW][COL] = {0}; //地图
int cnt = 0; //已经扫开的格子数
void init_mine() //初始化雷区
{
int i, j, k;
srand((unsigned)time(NULL));
for (k = 0; k < N; k++) {
i = rand() % ROW;
j = rand() % COL;
if (mine[i][j] == -1) {
k--;
continue;
}
mine[i][j] = -1;
}
return;
}
void show_map() //打印地图
{
int i, j;
printf(" ");
for (i = 0; i < COL; i++) {
printf("%d ", i);
}
printf("\n");
for (i = 0; i < ROW; i++) {
printf("%d ", i);
for (j = 0; j < COL; j++) {
if (map[i][j] == -1) printf("* ");
else if (map[i][j] == 0) printf("- ");
else printf("%d ", map[i][j]);
}
printf("\n");
}
printf("\n");
return;
}
int count_mine(int i, int j) //计算周围地雷数量
{
int cnt = 0;
if (i > 0 && j > 0 && mine[i-1][j-1] == -1) cnt++;
if (i > 0 && mine[i-1][j] == -1) cnt++;
if (i > 0 && j < COL-1 && mine[i-1][j+1] == -1) cnt++;
if (j > 0 && mine[i][j-1] == -1) cnt++;
if (j < COL-1 && mine[i][j+1] == -1) cnt++;
if (i < ROW-1 && j > 0 && mine[i+1][j-1] == -1) cnt++;
if (i < ROW-1 && mine[i+1][j] == -1) cnt++;
if (i < ROW-1 && j < COL-1 && mine[i+1][j+1] == -1) cnt++;
return cnt;
}
void open_tile(int i, int j) //打开格子
{
if (map[i][j] != 0) return;
if (mine[i][j] == -1) {
map[i][j] = -1;
return;
}
int cnt = count_mine(i, j);
map[i][j] = cnt;
if (cnt > 0) return;
if (i > 0 && j > 0) open_tile(i-1, j-1);
if (i > 0) open_tile(i-1, j);
if (i > 0 && j < COL-1) open_tile(i-1, j+1);
if (j > 0) open_tile(i, j-1);
if (j < COL-1) open_tile(i, j+1);
if (i < ROW-1 && j > 0) open_tile(i+1, j-1);
if (i < ROW-1) open_tile(i+1, j);
if (i < ROW-1 && j < COL-1) open_tile(i+1, j+1);
return;
}
int main()
{
int i, j;
init_mine();
show_map();
while (cnt < ROW*COL-N) {
printf("Enter the row and column of the tile you want to open: ");
scanf("%d%d", &i, &j);
if (i < 0 || i >= ROW || j < 0 || j >= COL) {
printf("Invalid input!\n");
continue;
}
if (map[i][j] != 0) {
printf("This tile has been opened!\n");
continue;
}
open_tile(i, j);
show_map();
cnt++;
}
printf("Congratulations! You win!\n");
return 0;
}
```
在这个代码中,我们使用两个数组 `mine` 和 `map` 分别表示雷区和地图。在雷区中,我们将地雷标记为 `-1`,其它格子的值为 `0`。在游戏开始时,我们使用 `init_mine()` 函数随机分布地雷。在打印地图时,我们根据 `map` 数组的值打印不同的字符。如果 `map` 中某个格子的值为 `-1`,表示这个格子是地雷;如果为 `0`,表示这个格子还没有打开;如果为其它正整数,表示这个格子周围有多少个地雷。
打开格子的操作是递归实现的。在 `open_tile()` 函数中,首先判断这个格子是否已经被打开,并且是否是地雷。如果是地雷,将 `map` 中对应的格子标记为 `-1`,否则计算它周围地雷的数量,并将这个数量存储在 `map` 中对应的格子中。如果这个数量大于 `0`,表示周围有地雷,不需要继续打开周围的格子。否则,递归调用 `open_tile()` 函数打开周围的格子。
在主函数中,我们使用循环不断读入玩家要打开的格子坐标,并调用 `open_tile()` 函数打开格子。当已经打开的格子数等于总格子数减去地雷数时,表示玩家已经把所有非地雷格子都打开了,游戏结束。