嗨,又是我,前几天写了个三子棋后,意犹未尽,于是乎,今天又写了一个扫雷小游戏。下面就是我写的扫雷代码了。
在写之前,同样是先将思路捋一遍。
按照网页上的扫雷游戏,进入画面后,首先打印一份菜单,以供玩家选择是否开始游戏,以及选择难度。(不过今天为了试验代码,便将难度默认为简单难度,在99的棋盘里布置10个雷。)选择完难度后,进入游戏,能看到一个99棋盘,等待玩家选择坐标。输入坐标后判断是否踩雷,以及附近有几颗雷。并将雷的数量打印在棋盘中。直至盘内无雷,宣布胜利。
捋完游戏基本逻辑,那便开始写吧。
首先当然是主函数,
打印完菜单后,便等待玩家输入是否开始游戏
#define ROW 9
#define COW 9
#define COWS COW+2
#define ROWS ROW+2
#define EASY 10
void Initboard(char board[ROWS][COWS], int row, int cow, char a);
void Print(char board[ROWS][COWS], int row, int cow);
void setboard(char board[ROWS][COWS], int row, int cow, int n);
void Find(char board1[ROWS][COWS], char board2[ROWS][COWS], int row, int cow);
int main()
{
int a = 0;
srand((unsigned int)time(NULL));//时间戳,创建随机数
do
{
menu();//打印菜单
printf("请选择是否开始游戏:>");
scanf("%d", &a);
switch (a)
{
case 1:
game();//游戏实现函数
break;
case 0:
printf("退出游戏");
break;
default:
printf("输入错误");
}
}
while (a);
return 0;
}
将菜单打印出来
void menu()
{
system("cls");
printf("\n********************************");
printf("\n***********1.开始游戏***********");
printf("\n***********0.退出游戏***********");
printf("\n********************************\n");
}
进入游戏后,按照扫雷逻辑,首先打印棋盘,再在棋盘内布置雷。 再由玩家输入坐标,判断,打印棋盘,输入坐标,判断,打印,一直循环
void game()
{
char board1[ROWS][COWS] = { 0 };
char board2[ROWS][COWS] = { 0 };
Initboard(board1, ROWS, COWS, '*');//初始化棋盘,棋盘初始化内容由函数给出
Initboard(board2, ROWS, COWS, '0');//初始化棋盘
Print(board1, ROW, COW);//打印棋盘
setboard(board2, ROW, COW, EASY);//布置雷
Find(board1, board2, ROW, COW);//下坐标及判断是否踩雷或者游戏胜利
}
棋盘设置为两个,一个内置,一个打印出使玩家观察,内置棋盘内布置雷,判断,再由另一个打印出来附近雷的数量。
以上就是游戏的主体过程,只要再将函数补充便可。
并且,游戏的棋盘大小为9* 9,但我们设计的棋盘是11* 11,这也是有原因的,如果棋盘只有9* 9,那在之后判断坐标为棋盘边缘一圈时,就需要加一个判断条件以免越界访问,设计为11* 11则不需要,初始化11* 11的棋盘后,只要将中间9* 9的棋盘打印出来,之后的判断时所有格子都能遍历。
先是将棋盘初始化化
void Initboard(char board[ROWS][COWS], int row, int cow, char a)//初始化棋盘
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < cow; j++)
{
board[i][j] = a;
}
}
}
这步很简单,只有一个初始化的内容是由函数给出,方便两个棋盘分别初始化为不同的值。
void Print(char board[ROWS][COWS], int row, int cow)//打印棋盘
{
printf("\n");
int i, j;
for (j = 0; j <= row; j++)
{
printf("%d ", j);
}printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= cow; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("————————————————\n");
}
我们的棋盘大小是11 * 11,打印只需打印9 * 9,所以循环的下标从1开始,到9结束。
void setboard(char board[ROWS][COWS], int row, int cow,int n)//布置雷
{
int a = n;
while (a)
{
int x = rand() % row + 1;
int y = rand() % cow + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
a--;
}
}
}
雷的位置是随机,所以需要创建横纵坐标两个随机数。雷的数量也需要传参。
int Getmine(char board2[ROWS][COWS], int x, int y)//判断坐标附近有几个雷
{
return
board2[x - 1][y - 1] +
board2[x - 1][y] +
board2[x - 1][y + 1] +
board2[x][y - 1] +
board2[x][y + 1] +
board2[x + 1][y] +
board2[x + 1][y + 1] - 7 * '0';
}
void Find(char board1[ROWS][COWS], char board2[ROWS][COWS], int row, int cow)
{
int x = 0;
int y = 0;
int n = ROW * COW - EASY;
while (n)
{
printf("请输入一个坐标:>\n");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row || y >= 1 && y <= cow)
{
if (board2[x][y] == '1')
{
printf("\n很遗憾,踩到雷了:>\n");
Print(board2, ROW, COW);
break;
}
else
{
int count = Getmine(board2, x, y);
board1[x][y] = count + '0';
Print(board1, ROW, COW);
n--;
}
}
else
{
printf("输入非法,重新输入:>\n");
}
}
if (n == 0)
{
printf("恭喜你,排雷成功\n");
}
printf("按任意键继续");
getch();
}
到了排雷的过程,创建一个计数器,计数棋盘内非雷的个数。再由玩家输入坐标后,要判断坐标是否合法,在确定坐标合法后,判断坐标位置是否踩雷,如果没有踩雷,那就将坐标附近雷的数量赋值在展示用棋盘上,并打印出来,在进行输入坐标。每走一步,计数器减少1,直至棋盘内非雷个数为0;
在break出循环后,因为还有一种踩雷的结果会跳出循环,所以,在函数末尾,还需要加一个判断计数器是否为0,只有为0,才会出现胜利。
今天的扫雷比较粗糙,很多功能都没有,如判断坐标附近0个雷时,坐标应该展开等等,之后还会补进。
感谢观看到这里,有不足之处,希望大佬指出。