C语言实现扫雷,代码+思路
Github链接:
https://github.com/SWQXDBA/Sweep-mines
下图非代码实现效果,仅原理展示
游戏规则不加赘述
game.h中写函数声明,宏定义与库
棋盘大小宏定义
#define H 7
#define L 7
#include
#include
#include
void play();
void printBoard(char Board[H][L], int h, int l);
void setMines(char Board[H][L], int h, int l,int count);
int getCount(char Board[H][L], int x, int y);
void clearBoard(char Board[H][L], char ch,int h,int l);
void searchBoard(char Board[H][L], char showsBoard[H][L], char ch, int x, int y, int *win);
main函数:
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
int main()
{
while (1)
{
int option;
printf("1 开始 2 退出\n");
option = getchar();
switch (option)
{
case '1':play(); break;
case '2':return 0; break;
case '3':printf("请输入正确的操作!\n"); break;
}
}
return 0;
}
之后是函数的具体实现
play()函数进行整个游戏流程,以及胜负判断等
注意,此处win变量用于统计已经排查的地块数量,当所有的地块都排查后,判断玩家获胜。
此处创建两个Board棋盘,一个用于存储地雷地块数据,一个用于玩家和显示。
void play()
{
flag:;
int minecount = 0;
printf("请输入埋雷的数量>>");
scanf("%d",&minecount);
if (minecount > (H - 2)*(L - 2)-1)
{
printf("雷太多了!!!\n");
goto flag;
}
char Board[H][L];
char ShowsBoard[H][L];
clearBoard(Board,'0',H,L);
clearBoard(ShowsBoard, ' ', H , L );
setMines(Board, H - 2, L - 2, minecount);
int win = 0;
while (1)
{
int x, y;
printBoard(ShowsBoard, H - 2, L - 2);
puts("\n");
//printBoard(Board, H - 2, L - 2);
printf("请输入坐标\n");
scanf("%d%d",&x,&y);
if (x<1 || x>H - 2 || y < 1 || y > L - 2)
{
printf("坐标非法!\n");
continue;
}
if (ShowsBoard[x][y] != ' ')
{
printf("这个点看过了,请换一个点!\n");
continue;
}
if (Board[x][y] == '1')
{
printf("踩到雷了\n");
for (int i = 1; i <= H-2; i++)
for (int j = 1; j <= L - 2; j++)
{
if (Board[i][j] == '1')
ShowsBoard[i][j] = '*';
}
ShowsBoard[x][y]='!';
printBoard(ShowsBoard, H - 2, L - 2);
break;
}
else
{
ShowsBoard[x][y] = getCount(Board,x,y) + '0';
if (getCount(Board, x, y) == 0)
{
searchBoard(Board,ShowsBoard,'1',x,y,&win);
}
win++;
}
if (win == (H - 2)*(L - 2)-minecount)
{
printf("恭喜获胜!\n");
for (int i = 1; i <= H - 2; i++)
for (int j = 1; j <= L - 2; j++)
{
if (Board[i][j] == '1')
ShowsBoard[i][j] = '*';
}
break;
}
printf("wins is%d\n", win);
}
}
打印函数:
void printBoard(char Board[H][L], int h, int l)
{
for (int i = 1; i <= h; i++)
{
printf(" “);
for (int j = 1; j <= l; j++)
{
printf(” -%d-",j);
}
puts("");
printf("%d|",i);
for (int j = 1; j <= l; j++)
{
printf(" %c |", Board[i][j]);
}
puts("");
printf(" “);
for (int j = 1; j <= l; j++)
{
printf(” —");
}
puts("");
}
}
打印效果:因为通过输入坐标进行操作,给出横纵坐标方便进行游戏。
布置地雷:
void setMines(char Board[H][L], int h, int l, int count)
{
srand((unsigned int)time(NULL));
int counts = 0;
while (counts < count)
{
int x = 1+rand() % h;
int y = 1+rand() % l;
if (Board[x][y] == '0')
{
Board[x][y] = '1';
counts++;
}
}
}
getCount函数,用于获取某个坐标周围的地雷数量
int getCount(char Board[H][L], int x, int y)
{
int countis = 0;
for (int i = x - 1; i <= x + 1; i++)
for (int j = y - 1; j <= y + 1; j++)
{
if (Board[i][j] == '1')
countis++;
}
return countis;
}
初始化地图:
void clearBoard(char Board[H][L], char ch, int h, int l)
{
for (int i = 0; i < h; i++)
for (int j = 0; j < l; j++)
Board[i][j] = ch;
}
searchboard函数,用于实现自动点,类似
如果点到周围地雷为0的地块,会自动搜索周围的8格子,直到触碰到“边界”
void searchBoard(char Board[H][L], char showsBoard[H][L], char ch, int x, int y, int *win)
{
for (int i = x - 1; i <= x + 1; i++)
for (int j = y - 1; j <= y + 1; j++)
{
if (showsBoard[i][j] == ' '&&(i>=1&&j>=1&&i<=H-2&&j<=L-2))
{
showsBoard[i][j] = getCount(Board, i, j) + '0';
(*win)++;
if (showsBoard[i][j] == '0')
{
searchBoard(Board, showsBoard, ch, i, j, win);
}
}
}
}