前言
为了提高代码的可读性,跟三子棋一样写该扫雷分了三个部分,test.c(表达自己的步骤),game.h(实现游戏代码块之前对函数的声明)game.c(游戏代码块的实现),在.c文件中对函数的实现需引用.h文件中的函数声明,例如使用库函数printf需使用头文件#include <stdio.h>,在.c 文件中总要使用到一些库函数,因此可将对应的头文件放于game.h头文件中,在.c文件使用时引用#include "game.h"即可。最终我们需要的是这么一个扫雷模板并在上面进行扫雷,接下来进行分析
test.c
游戏菜单
void menu()
{
printf("*********************************\n");
printf("*****输入1开始游戏 0退出游戏*****\n");
printf("*********************************\n");
}
选择是否开始游戏
输入数字1开始游戏,0则退出游戏,输入错误则重新输入,玩家判断是否想玩游戏或者继续游戏,因此这里用到一个do…while循环语句来控制是否继续进行游戏
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();//游戏菜单
printf("请输入一个数:>");
scanf("%d", &input);
switch (input)//选择是否开始游戏
{
case 0:
printf("退出游戏\n");
break;
case 1:
printf("开始游戏\n");
game();//进入游戏
break;;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
进入游戏
这里需要两个扫雷盘,这里建立两个数组,玩过扫雷的应该都知道,选定一个不是雷的时候出现数字,会表明以该格子为中心周围的8个格子有几个雷,但在扫雷盘边缘时,访问周围8个格子会出现越界,而用户看到的是99的扫雷盘,因此需要将在给用户看到的扫雷盘的基础上将其扩大成1111的形式
void game()
{
char board[ROWS][COLS];//布置雷的操作数组
char board1[ROWS][COLS];//给用户扫雷的操作数组
//初始化扫雷盘
//用0,*区分两个扫雷盘,0是将要布置雷的扫雷盘,*代表用户要排查雷的盘
Initboard(board, ROWS, COLS,'0');
Initboard(board1, ROWS, COLS,'*');
//打印扫雷盘
DisPlayboard(board, ROW, COL);
DisPlayboard(board1, ROW, COL);//给用户玩时,最终可以将这一行和上面两行给注释掉
//布置雷
Setboard(board, ROW, COL);
//DisPlayboard(board, ROW, COL);
DisPlayboard(board1, ROW, COL);
//排查雷
Searchboard(board,board1,ROW, COL);
}
test.c完整代码
#include "game.h"
void menu()
{
printf("*********************************\n");
printf("*****输入1开始游戏 0退出游戏*****\n");
printf("*********************************\n");
}
void game()
{
char board[ROWS][COLS];//布置雷的操作数组
char board1[ROWS][COLS];//给用户扫雷的操作数组
//初始化扫雷盘
//用0,*区分两个扫雷盘,0是将要布置雷的扫雷盘,*代表用户要排查雷的盘
Initboard(board, ROWS, COLS,'0');
Initboard(board1, ROWS, COLS,'*');
//打印扫雷盘
DisPlayboard(board, ROW, COL);
DisPlayboard(board1, ROW, COL);//给用户玩时,最终可以将这一行和上面两行给注释掉
//布置雷
Setboard(board, ROW, COL);
//DisPlayboard(board, ROW, COL);
DisPlayboard(board1, ROW, COL);
//排查雷
Searchboard(board,board1,ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();//游戏菜单
printf("请输入一个数:>");
scanf("%d", &input);
switch (input)//选择是否开始游戏
{
case 0:
printf("退出游戏\n");
break;
case 1:
printf("开始游戏\n");
game();//进入游戏
break;;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
game.h
这里包含头文件,一些定义,对要使用到的库函数进行声明,对要实现游戏的函数进行声明
#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9//用户实际操作扫雷盘行的大小
#define COL 9//用户实际操作扫雷盘列的大小
#define ROWS ROW+2//布置扫雷盘行的大小
#define COLS COL+2//布置扫雷盘列的大小
#define COUNT 10;//定义雷的个数
//初始化扫雷盘
void Initboard(char board[ROWS][COLS],int row, int col,char set);
//打印扫雷盘
void DisPlayboard(char board[ROWS][COLS], int row, int col);
//布置雷
void Setboard(char board[ROWS][COLS], int row, int col);
//排查雷
void Searchboard(char board[ROWS][COLS],char board1[ROWS][COLS], int row, int col);
game.c
这里进行游戏的具体实现也就是每个函数的具体实现
初始化扫雷盘
用char set 来接收要初始化的值,直接用set来代替要初始化的值,这就不会导致初始化时到底选择0还是*,直接用一个函数又可以实现初始化值,这是初始化的优点所在
//初始化扫雷盘
void Initboard(char board[ROWS][COLS], int row, int col,char set)
{
int i = 0;
for (i = 0; i < row; i++)//控制行
{
int j = 0;
for (j = 0; j < col; j++)//控制列,一行输入几个列
{
board[i][j] = set;//将刚刚传过来的字符进行初始化
}
}
}
打印扫雷盘
这里除了打印扫雷盘之外,还打印了行列的标号
//打印扫雷盘
void DisPlayboard(char board[ROWS][COLS], int row, int col)
{
printf("----------扫雷游戏-----------\n");
int i = 0;
for (i = 0; i <= row; i++)
{
printf("%2d ", i);//控制列的标号
}
printf("\n");//打印完列之后进行换行
for (i = 1; i <=row; i++)
{
printf("%2d ", i);//控制行的标号
int j = 0;
for (j = 1; j <=col; j++)
{
printf("%2c ", board[i][j]);//将初始化的内容打印出来
}
printf("\n");
}
}
布置雷
这里使用了rand函数来产生随机数,但srand产生的随机数是固定的,这里了在使用此函数之前需先进行设置随机值起点,即需用到srand((unsigned int)time(NULL))语句来设置随机值起点,里头还有一个time函数产生时间差来产生一个随机值起点,后被rand接收来产生不同的随机数。使用这些函数之前需要包含头文件,#include <stdlib.h>,#include <time.h>即可
//布置雷
void Setboard(char board[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = COUNT;//布置雷的个数,这里布置10个雷
while (count)
{
x = rand() % row + 1;
y = rand() % col + 1;//产生1到9的随机数
if (board[x][y] == '0')
{
board[x][y] = '1';//1代表雷,随机布置十个雷
count--;
}
}
}
排查雷
此部分也是最难的一部分,体现在如何判断周围有几颗雷和如何结束游戏,这里又通过了一个函数来返回周围有几颗雷,通过设立一个起始排雷的一个标志,排了多少次来判断是否结束游戏
//排查雷
int CountBoard(char board[ROWS][COLS],int x, int y)
{
return board[x][y] + board[x][y - 1] + board[x][y + 1] +
board[x - 1][y] + board[x - 1][y - 1] + board[x - 1][y + 1] +
board[x + 1][y] + board[x + 1][y - 1] + board[x + 1][y + 1]-8*'0';
//返回周围8个格子有几个雷
}
void Searchboard(char board[ROWS][COLS], char board1[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int count = 0;
int k = COUNT;//将雷的个数给变量k
int flag = 0;//排雷起始次数的标志
while (1)//没被炸死就继续游戏,直到全部排查完
{
printf("请输入坐标:");
scanf("%d%d", &i, &j);
if(i>=1&&i<=9 && j>=1&&j<=9)//判断输入坐标合法性
{
if (board[i][j] == '1')//是否踩到雷
{
printf("恭喜你,你被炸死了\n");
break;//炸死结束游戏
}
else
{
count = CountBoard(board, i, j);//如果没被炸死,显示周围有几个雷
board1[i][j] = count;//表明周围有几颗雷
DisPlayboard(board1, ROW, COL);//在打印一下扫雷盘,查看排除雷的情况
}
flag++;//排雷一次没被炸死,次数+1
if (flag == row * col - k)//判断排雷的次数来控制最总是否排雷成功
{
printf("恭喜你,排雷成功\n");
break;
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
game.c完整代码
#include "game.h"
//初始化扫雷盘
void Initboard(char board[ROWS][COLS], int row, int col,char set)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
board[i][j] = set;
}
}
}
//打印扫雷盘
void DisPlayboard(char board[ROWS][COLS], int row, int col)
{
printf("----------扫雷游戏-----------\n");
int i = 0;
for (i = 0; i <= row; i++)
{
printf("%2d ", i);
}
printf("\n");
for (i = 1; i <=row; i++)
{
printf("%2d ", i);
int j = 0;
for (j = 1; j <=col; j++)
{
printf("%2c ", board[i][j]);
}
printf("\n");
}
}
//布置雷
void Setboard(char board[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = COUNT;//布置雷的个数,这里布置10个雷
while (count)
{
x = rand() % row + 1;
y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';//1代表雷,随机布置十个雷
count--;
}
}
}
//排查雷
int CountBoard(char board[ROWS][COLS],int x, int y)
{
return board[x][y] + board[x][y - 1] + board[x][y + 1] +
board[x - 1][y] + board[x - 1][y - 1] + board[x - 1][y + 1] +
board[x + 1][y] + board[x + 1][y - 1] + board[x + 1][y + 1]-8*'0';
//返回周围8个格子有几个雷
}
void Searchboard(char board[ROWS][COLS], char board1[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int count = 0;
int k = COUNT;//将雷的个数给变量k
int flag = 0;//排雷起始次数的标志
while (1)//没被炸死就继续游戏,直到全部排查完
{
printf("请输入坐标:");
scanf("%d%d", &i, &j);
if(i>=1&&i<=9 && j>=1&&j<=9)//判断输入坐标合法性
{
if (board[i][j] == '1')//是否踩到雷
{
printf("恭喜你,你被炸死了\n");
break;//炸死结束游戏
}
else
{
count = CountBoard(board, i, j);//如果没被炸死,显示周围有几个雷
board1[i][j] = count;//表明周围有几颗雷
DisPlayboard(board1, ROW, COL);//在打印一下扫雷盘,查看排除雷的情况
}
flag++;//排雷一次没被炸死,次数+1
if (flag == row * col - k)//判断排雷的次数来控制最总是否排雷成功
{
printf("恭喜你,排雷成功\n");
break;
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
完整版扫雷代码
#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9//用户实际操作扫雷盘行的大小
#define COL 9//用户实际操作扫雷盘列的大小
#define ROWS ROW+2//扫雷盘行的大小
#define COLS COL+2//扫雷盘列的大小
#define COUNT 10;//定义雷的个数
//初始化扫雷盘
void Initboard(char board[ROWS][COLS],int row, int col,char set);
//打印扫雷盘
void DisPlayboard(char board[ROWS][COLS], int row, int col);
//布置雷
void Setboard(char board[ROWS][COLS], int row, int col);
//排查雷
void Searchboard(char board[ROWS][COLS],char board1[ROWS][COLS], int row, int col);
//初始化扫雷盘
void Initboard(char board[ROWS][COLS], int row, int col,char set)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
board[i][j] = set;
}
}
}
//打印扫雷盘
void DisPlayboard(char board[ROWS][COLS], int row, int col)
{
printf("----------扫雷游戏-----------\n");
int i = 0;
for (i = 0; i <= row; i++)
{
printf("%2d ", i);
}
printf("\n");
for (i = 1; i <=row; i++)
{
printf("%2d ", i);
int j = 0;
for (j = 1; j <=col; j++)
{
printf("%2c ", board[i][j]);
}
printf("\n");
}
}
//布置雷
void Setboard(char board[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = COUNT;//布置雷的个数,这里布置10个雷
while (count)
{
x = rand() % row + 1;
y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';//1代表雷,随机布置十个雷
count--;
}
}
}
//排查雷
int CountBoard(char board[ROWS][COLS],int x, int y)
{
return board[x][y] + board[x][y - 1] + board[x][y + 1] +
board[x - 1][y] + board[x - 1][y - 1] + board[x - 1][y + 1] +
board[x + 1][y] + board[x + 1][y - 1] + board[x + 1][y + 1]-8*'0';
//返回周围8个格子有几个雷
}
void Searchboard(char board[ROWS][COLS], char board1[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int count = 0;
int k = COUNT;//将雷的个数给变量k
int flag = 0;//排雷起始次数的标志
while (1)//没被炸死就继续游戏,直到全部排查完
{
printf("请输入坐标:");
scanf("%d%d", &i, &j);
if(i>=1&&i<=9 && j>=1&&j<=9)//判断输入坐标合法性
{
if (board[i][j] == '1')//是否踩到雷
{
printf("恭喜你,你被炸死了\n");
break;//炸死结束游戏
}
else
{
count = CountBoard(board, i, j);//如果没被炸死,显示周围有几个雷
board1[i][j] = count;//表明周围有几颗雷
DisPlayboard(board1, ROW, COL);//在打印一下扫雷盘,查看排除雷的情况
}
flag++;//排雷一次没被炸死,次数+1
if (flag == row * col - k)//判断排雷的次数来控制最总是否排雷成功
{
printf("恭喜你,排雷成功\n");
break;
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
void menu()
{
printf("*********************************\n");
printf("*****输入1开始游戏 0退出游戏*****\n");
printf("*********************************\n");
}
void game()
{
//需要两个扫雷盘,这里建立两个数组,玩过扫雷的应该都知道,选定一个不是雷的时候
//出现数字,会表明以该格子为中心周围的8个格子有几个雷,但在扫雷盘边缘时,访问周围8个格子
//会出现越界,因此需要将在给用户看到的扫雷盘基础上将其扩大
char board[ROWS][COLS];//布置雷的操作数组
char board1[ROWS][COLS];//给用户扫雷的操作数组
//初始化扫雷盘
//用0,*区分两个扫雷盘,0是将要布置雷的扫雷盘,*代表用户要排查雷的盘
Initboard(board, ROWS, COLS,'0');
Initboard(board1, ROWS, COLS,'*');
//打印扫雷盘
//DisPlayboard(board, ROW, COL);
//DisPlayboard(board1, ROW, COL);//给用户玩时,最终可以将这一行和上面两行给注释掉
//布置雷
Setboard(board, ROW, COL);
//DisPlayboard(board, ROW, COL);
DisPlayboard(board1, ROW, COL);
//排查雷
Searchboard(board,board1,ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();//游戏菜单
printf("请输入一个数:>");
scanf("%d", &input);
switch (input)//选择是否开始游戏
{
case 0:
printf("退出游戏\n");
break;
case 1:
printf("开始游戏\n");
game();//进入游戏
break;;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
游戏展示
扫雷失败
这里给出了布置雷的棋盘,为了方便测试,当然给玩家是不用给出来的啦
扫雷成功
这里为了方便测试,直接特殊一点,直接将雷布置为80个雷
评价
此游戏相较于三子棋游戏来说,增加了一个扫雷盘,看似难度增加了一点,但明白其中的道理,其实两者难度差不多,合理运用函数,数组来实现,此游戏相较于普通扫雷还是增加了难度,小白还是授予水平限制,只能仿造写了这么一个扫雷小游戏,望大佬多多指点
经历过三子棋,扫雷游戏,我对函数,循环语句,数组,有了全新的认识,更加掌握了对这些知识的应用,也更提高了我对编程的兴趣。