前言
扫雷想必大家都玩过,尝试写一下
一、大概思路
暂时采用9x9的区域进行游戏,因为要统计每个格子周围八个格子的雷数,所以创建两个11x11的二维数组,数组Presets用来存储安全格子(置为字符‘0’)和埋雷格子(置为字符‘1’)的信息,数组Show用来展示给玩家。比较复杂一点的是周围无雷的格子可以展开,需要用递归实现。
二、具体实现
1.初始化
先定义标识符常量
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
Presets全置为’0‘,Show全置为’*‘
void Init(char Presets[ROWS][COLS], char Show[ROWS][COLS], int rows, int cols)
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
Presets[i][j] = '0';
Show[i][j] = '*';
}
}
}
2.展示排雷区
可以提示一下坐标数
void Display(char Show[ROWS][COLS], int row, int col)
{
system("cls");
int i,j;
for (i = 0; i <= row; i++)
{
printf("%d ", i);//列坐标提示
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);//行坐标提示
for (j = 1; j <= col; j++)
{
printf("%c ", Show[i][j]);
}
printf("\n");
}
}
3.随机埋雷
Presets数组的9*9区域内随机将’0‘置为’1‘
void Setting(char Presets[ROWS][COLS], int row, int col,int num)
{
for (int i = 0; i < num; i++)
{
while(1)
{
int x = rand() % 9 + 1;
int y = rand() % 9 + 1;
if (Presets[x][y] == '0')
{
Presets[x][y] = '1';
break;
}
}
}
}
4.玩家排雷
计算某格子周围的雷的数量
static int SurNum(char Presets[ROWS][COLS], int x, int y)//计算周围的雷数
{
return Presets[x - 1][y - 1] + Presets[x - 1][y] + Presets[x - 1][y + 1]
+ Presets[x][y - 1] + Presets[x][y + 1]
+ Presets[x + 1][y - 1] + Presets[x + 1][y] + Presets[x + 1][y + 1]
- '0' * 8;
}
如果周围没有雷则可以展开
static void space(char Presets[ROWS][COLS], char Show[ROWS][COLS], int x, int y)
{
int i;
int j;
if (SurNum(Presets, x, y) == 0)
{
Show[x][y] = ' ';
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
if (i > 0 && i <= ROW && j > 0 && j <= COL && Presets[i][j] != '1' && Show[i][j] == '*')
{//若不是'*'则说明已经调用过space
space(Presets, Show, i, j);
}
}
}
}
else
Show[x][y] = '0' + SurNum(Presets, x, y);
}
全部排完则返回1,游戏继续返回0,遇到雷则返回-1游戏结束
int Exclude(char Presets[ROWS][COLS], char Show[ROWS][COLS], int row, int col,int num)
{
printf("请输入坐标(中间用空格):");
while (1)
{
int x, y;
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col && Show[x][y] == '*')
{
if (Presets[x][y] == '1')
{
return -1;
}
else
{
int i, j;
int count = 0;
int surNum = SurNum(Presets, x, y);//周围雷的个数
if (surNum == 0)
{
space(Presets, Show, x, y);//周围无雷时,展开
}
else
{
Show[x][y] = surNum + '0';
}
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
if (Show[i][j] == '*')//是否只剩雷
{
count++;
}
}
}
if (count == num)
{
return 1;//游戏胜利
}
else
{
return 0;//游戏继续
}
}
}
else
{
printf("输入错误,重新输入:");
}
}
}
用死循环+break控制排雷(写在main函数所在文件)
while (1)//排雷
{
int ret = Exclude(Presets, Show, ROW, COL,num);
if (ret == -1)
{
printf("直接爆炸!\n");
break;
}
else
{
Display(Show, ROW, COL);
if (ret == 1)
{
printf("游戏结束,排雷成功!\n");
break;
}
else
{
printf("游戏继续\n");
}
}
}
总结
扫雷游戏是对分支循环结构的综合应用,尝试一下大有裨益,共勉。