前言
说实话如果不是因为作业我真的不喜欢写博客,靠自己努力做好就行来着,让我分享经验基本感觉很糟
一、基本思路
和之前三子棋一样扫雷也是一个棋盘类型输入坐标操作所以就可以用程序员的最佳按键ctrl+cv将之前的打印棋盘部分复制(虽然也有改动),随机放雷也是同理
众所周知扫雷有两个棋盘:一个是给玩家呈现的外衣要一层层剥开(好像有点涩(*/ω\*))另一层就是底部埋雷的模样了,操作模式也只是三子棋思路的延伸(操作外层棋盘,用内层棋盘来反馈数字)
二、实践
首先当然是熟悉的星号菜单
int menu()
{
int p = 0;
printf("***************************************\n");
printf("**************扫雷游戏*****************\n");
printf("***************************************\n");
printf("****************1.start****************\n");
printf("****************2. exit****************\n");
printf("***************************************\n");
scanf("%d",&p);
return p;
}
(说实话是有点单调)
老规矩用Switch语句进入退出游戏
srand((unsigned int)time(NULL));
int i=0;
while (1) {i = menu();
switch (i)
{
case 1:game(); break;
case 2:goto G;
default:
break;
}
}
G:
return 0;
别人都喜欢用do while 我一直是while+goto(这样会不会不太好)
扫雷需要对周围八个位置的情况为了防止溢出扫到不存在的位置所以需要两对长宽
#define ROW 10
#define COL 10
#define ROWS ROW+2
#define COLS COL+2
刷新雷区棋盘就需要全部放好
void init(char b[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
b[i][j] = '0';
}
}
}
但打印时仍需额外处理一下
void print(char b[ROW][COL], int row, int col)
{
int i = 0;
for (int j = 0; j < col; j++)
{
if (i == 0)
{
printf(" %2d", j+1);
if (j == col - 1)
{
printf("\n");
}
}
}
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (j == 0)
{
printf("%2d",i+1);
}
printf(" %c ", b[i+1][j+1]);
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
if (i < row - 1)//分割线
{
printf(" ");
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
printf("----------------------------------------------------------------------\n");
}
在打印之前将坐标数固定为两位数将会更容易对齐吧(应该不会有人喜欢玩几百行几百列的扫雷吧?)
打印时横纵坐标全部加1就可以给数组留下个边角不去打印了
接下来就是紧张刺激的放雷环节了同样为了方便调整难度使用#define定义
#define count 9
放雷方式依然是用时间戳产生的随机数来处理
void set(char b[ROW][COL], int row, int col)
{
int boom = count;
while (boom)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (b[x][y] == '0')
{
b[x][y] = '1';
boom--;
}
}
}
雷区已经准备好,接下来请玩家入场(坏笑)
和三子棋不同这个需要操作两个数组,一个给看另一个给用
所以内容就比较繁杂
同样也需要一个判断周围地雷数的函数
int scan(char b[ROW][COL], int x, int y)
{
return(b[x - 1][y - 1] + b[x - 1][y]
+ b[x - 1][y + 1] + b[x][y - 1]
+ b[x][y + 1] + b[x + 1][y + 1]
+ b[x + 1][y] + b[x + 1][y -1]-8*'0');
}
万事俱备可以请玩家上路了(雾)
void find(char b[ROW][COL], char a[ROW][COL], int row, int col)
{
int x = 0, y = 0;
int w = 0;
while (w < (row * col - count))
{
printf("请输入要排查的坐标:>");
scanf("%d %d", &x, &y);
if (x <= row && y <= col && x >= 1 && y >= 1)
{
if (b[x][y] != '*')
{
printf("重复扫描\n");
continue;
}
if (a[x][y] == '1')
{
printf("GAME OVER\n");
print(a, row, col);
break;
}
if (b[x][y] == '*')
if (a[x][y] == '0')
{
int z = scan(a, x, y);
b[x][y] = z+ '0';
print(b, row, col);
w++;
}
}
else { printf("坐标非法请重新输入"); }
}
if (w == (row * col - count)) {
printf("恭喜你扫出所有雷!\n");
print(a, row, col);
}
}
只要将所有没雷的地方走一遍就用了是不是很简单呢
偌大的扫雷就这么简简单单清清爽爽拿下了
如果想采取标记可以采用个Switch函数来分操作类型
总结,思路不难只是很麻烦。