这一章我们将要实现标记和展开一片区域的功能。
游戏途中我们如果推测出某个方格是雷,就可以对其进行标记。
首先我还是要在game.h头文件中定义一个标记函数
game.h
//标记雷
int Mark_Mine(char mine[ROWS][COLS], char showp[ROWS][COLS], int x, int y, int win);
game.c
int Mark_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int win)
{
int i, j;
while (1)
{
printf("请输入你要标记的坐标:\n");
scanf("%d %d", &i, &j);
if (i > 0 && i <= row && j > 0 && j <= col)
{
if (show[i][j] == '*')//判断该区域是否排查过
{
show[i][j] = '!';//对你认为是雷的区域标记为‘!’
Display(show, ROW, COL);
if (mine[i][j] == '1')//如果该区域确实是雷那么win(雷数)就--
win--;
return win;
}
else
printf("坐标已排查,请重新输入:\n");
}
else
printf("坐标错误\n");
}
}
最后在主函数判断win=0游戏通过
在我们翻开一个格子的时候,如果周围有雷,我们需要显示雷的个数,如果没有,将该位置标记为空白,然后对周围的方格进行递归判定,直到找到周围有雷的方格为止。
game.h
//递归展开
void expand_blank(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
game.c
void expand_blank(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
{
int i = 0, j = 0;
int count = CountMine(mine, x, y);
if (count)//周围区域如果有雷就显示雷的数量
{
show[x][y] = count+'0';
}
else if (show[x][y] == '*')
{
show[x][y] = ' ';//如果周围没有雷就将该方格标记为空白
for (i = x - 1; i <= x + 1; i++)
for (j = y - 1; j <= y + 1; j++)
expand_blank(mine,show, i, j);//如此一直对周边区域进行排查直到找到周围区 域有雷的方格为止
}
}
}
如果运用了展开一片区域的功能,就不一定知道一次性排查了几个方格,所以就不能用基础版扫雷中的(win=row*col-EASY_count)来判断游戏是否结束,所以要对排雷函数进行一定修改。
game.h
//排雷
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
game.c
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0, y = 0;
while (1)
{
printf("请输入要排查的坐标:");
scanf("%d %d", &x, &y);
if (x > 0 && x <= row && y > 0 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾你被炸死了\n");
Display(mine, ROW, COL);
return 1;
}
else
{
expand_blank(mine, show, x,y);//如果排查方格不是雷就调用expan_blank函数对 周围进行排查
Display(show, ROW, COL);
return 0;//返回1或0来判断排查区域是否为雷
}
}
else
{
printf("输入非法坐标,请重新输入");
}
}
}
完整代码展示
game.h
#pragma?? ?once
#include
#include
#include#define EASY_count 10
#define ROW 9
#define COL 9#define ROWS ROW+2
#define COLS COL+2//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);//打印棋盘
void Display(char arr[ROWS][COLS], int row, int col);//布置雷
void SetMine(char arr[ROWS][COLS], int row, int col);//递归展开
void expand_blank(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
//排雷
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//标记雷
int Mark_Mine(char mine[ROWS][COLS], char showp[ROWS][COLS], int x, int y, int win);
game.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"int CountMine(char mine[ROWS][COLS], int x, int y)
{
int sum = 0;
int i = 0, j = 0;
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
sum += mine[i][j] - '0';
}
return sum;
}void InitBoard(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 Display(char arr[ROWS][COLS], int row, int col)
{
int i = 0, j = 0;
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
putchar('\n');
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
printf("%c ", arr[i][j]);
printf("\n");
}
printf("-------------------\n");
}void SetMine(char arr[ROWS][COLS], int row, int col)
{
int count = EASY_count;while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}}
void expand_blank(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
{
int i = 0, j = 0;
int count = CountMine(mine, x, y);
if (count)
{
show[x][y] = count+'0';
}
else if (show[x][y] == '*')
{
show[x][y] = ' ';
for (i = x - 1; i <= x + 1; i++)
for (j = y - 1; j <= y + 1; j++)
expand_blank(mine,show, i, j);
}
}
}int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0, y = 0;
while (1)
{
printf("请输入要排查的坐标:");
scanf("%d %d", &x, &y);
if (x > 0 && x <= row && y > 0 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾你被炸死了\n");
Display(mine, ROW, COL);
return 1;
}
else
{
expand_blank(mine, show, x,y);
Display(show, ROW, COL);
return 0;
}
}
else
{
printf("输入非法坐标,请重新输入");
}
}
}int Mark_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int win)
{
int i, j;
while (1)
{
printf("请输入你要标记的坐标:\n");
scanf("%d %d", &i, &j);
if (i > 0 && i <= row && j > 0 && j <= col)
{
if (show[i][j] == '*')
{
show[i][j] = '!';
Display(show, ROW, COL);
if (mine[i][j] == '1')
win--;
return win;
}
else
printf("坐标已排查,请重新输入:\n");
}
else
printf("坐标错误\n");
}
}
test.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
printf("**************************\n");
printf("******* 1.play ********\n");
printf("******* 0.exit ********\n");
printf("**************************\n");
}void game()
{
int win = EASY_count;
char mine[ROWS][COLS];
char show[ROWS][COLS];InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');//Display(mine, ROW, COL);
//Display(show, ROW, COL);SetMine(mine, ROW, COL);
//Display(mine, ROW, COL);//FindMine(mine, show, ROW, COL);
while (win)
{
printf("输入1排雷,输入2标记");
int m = 0;
scanf("%d", &m);
if (m == 1)
{
if (FindMine(mine, show, ROW, COL))
{
break;
}
}
else if (!(Mark_Mine(mine, show, ROW, COL,win)))
{
printf("恭喜你赢了!!\n");
break;
}
}
}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("退出游戏");
break;
default:
printf("选择错误,请重新选择");
break;
}
} while (input);return 0;
}
详细二者间的不同,可以与上一章的代码进行比较
实现某个功能就创建一个函数的思想,但创建新函数的途中可能会对原来某些函数产生影响,所以需要一一排查,避免发生错误。切记耐心是写好代码的条件之一!!!