思路
1.布置雷; 首先我们应该让电脑随机布置好雷 2.玩家进行扫雷。我们将要面对的问题
1.用什么来区分雷与非雷;
- 使用某些特殊字符还是数字呢?
- 若用字符表示,后面又怎么对雷来进行计数呢?
- 若用数字0和1,那么在计数时也会产生1、2、3等数即会产生歧义
2.创建什么数组,字符型?整型?
3.在边界检查时,会出现非法的数组越界情况,怎么解决?
(读者若有其他思考,可在评论区写出你的看法)
效果图
菜单栏
游戏中
成功递归一步实现对空白区域的展开
test.c
#include"game.h"
void menu()
{
printf("※※※※※※※※※※※※※※※※\n");
printf("※※※※※ menu ※※※※※\n");
printf("※※※※※※※※※※※※※※※※\n");
printf("※※※※※ 1.paly ※※※※※\n");
printf("※※※※※ 0.exit ※※※※※\n");
printf("※※※※※※※※※※※※※※※※\n");
}
void game()
{
//创建扫雷盘对应的数组
char mine[ROWS][COLS];//存放布置的雷的信息
char show[ROWS][COLS];//排查出的雷的信息
InitSweep(mine, ROWS, COLS,'0');
InitSweep(show, ROWS, COLS,'*');
//打印扫雷页面
//PrintSweep(mine, ROW, COL);
PrintSweep(show, ROW, COL);
//布置雷
SetMine(mine, ROW, COL,MID_COUNT);
//PrintSweep(mine, ROW, COL);
//排查雷
FineMine(mine, show, ROW, COL);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game(); //扫雷游戏的实现
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
if(input)
system("cls");
} while (input);
return 0;
}
game.c
#include"game.h"
void InitSweep(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0,j=0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
void PrintSweep(char board[ROWS][COLS], int row, int col)
{
int i = 0, j = 0;
printf(" ");
for (i = 1; i <= col; i++)
{
printf(" %d", i);
}
printf("\n");
printf(" ┅┅ ┅┅ ┅┅ ┅┅ ┅┅ ┅┅ ┅┅ ┅┅ ┅┅\n");
for (i = 1; i <= row; i++)
{
printf("%d", i);
printf("┇");
for (j = 1; j <= col; j++)
{
printf(" %c", board[i][j]);
printf("┇");
}
printf("\n ");
for (j = 1; j <= col; j++)
{
printf(" ┅┅");
}
printf("\n");
}
}
void SetMine(char mine[ROWS][COLS], int row, int col, int count)
{
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
//统计mine数组中x,y坐标周围有几个雷
int GetMineCount(char mine[ROWS][COLS],int x,int y)
{
int i = 0, j = 0, k = 0;
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
k += mine[i][j]-'0';
}
}
return k;
}
int SearchMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int cont)
{
static int a[ROWS][COLS] = { 0 };
a[x][y] = 1;
int i, j;
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
if (i >= 1 && i <= ROW && j >= 1 && j <= COL)
{
int count = GetMineCount(mine, i, j);
if (count == 0 && a[i][j] == 0)
{
cont++;
cont=SearchMine(mine, show, i, j, cont);
show[i][j] = '0';
}
else
{
/*a[i][j] = 1;*/
show[i][j] = count + '0';
cont++;
}
}
}
}
return cont;
}
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int flag = 1;
int cot = 0;
while (1)
{
printf("请输入要排查的坐标:>");
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
getchar();getchar();
//1.坐标合法性
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
flag = 0;
printf("很遗憾,你踩雷了!\n");
PrintSweep(mine, row, col);
break;
}
else
{
//2.该坐标是不是雷?不是雷,统计周围雷的个数
int count = GetMineCount(mine,x,y);
if (count == 0)
{
cot++;
cot=SearchMine(mine, show, x, y, cot);
show[x][y] = '0';
}
else
{
show[x][y] = count + '0';//存放的是字符
cot++;
}
PrintSweep(show, row, col);
if (cot == row * col - MID_COUNT)
break;
}
}
else
{
printf("坐标非法,请重新输入!\n");
}
}
if (flag)
{
printf("恭喜你,扫雷成功!\n");
}
}
game.h
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define MID_COUNT 15
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//初始化页面
void InitSweep(char board[ROWS][COLS], int rows, int cols,char set);
//打印棋盘
void PrintSweep(char board[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col, int count);
//排雷
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
总结
笔者想要实现对空白地的展开没有完全实现,只能够最多展开周围8个,在此留坑,也希望读者大佬们指点一下。(后来改了下,应该可以了,但又发现了一些问题,正在努力修改…)