《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
首先我们需要创建一个菜单栏函数,实现于用户交互
//用户交互页面
void Menu()
{
printf("游戏规则:输入行和列来排查雷区,如果踩中雷,被炸死,哈哈哈~~~\n");
printf("如果没有踩中,会显示当前格子周围雷的数目。当所有不是雷的格子被排查光时,游戏获胜\n");
printf("********************************\n");
printf("********** 1.play *********\n");
printf("********** 2.exit *********\n");
printf("********************************\n");
printf("输入 1 开始游戏;输入 0 退出游戏\n");
}
这里我们需要用到一个学过的循环语句:do-while循环
int main()
{
srand((unsigned int)time(NULL));//用于产生随机数
int input;
do
{
Menu();//打印用户交互页面
scanf("%d", &input);
switch (input)
{
case 1:
printf("游戏开始->\n");
Game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误!请重新输入\n");
break;
}
} while (input);
return 0;
}
这里需要建立两个数组,一个用来存放布置好的雷的信息,另一个用来存放查出雷的信息。我们要建立的是9 * 9的棋盘,但是我们需要建立11 * 11的二维数组,为什么呐,因为当我们判断一个在角落的棋格周围雷的数目时,如果仅仅只是一个9 * 9的数组,判断时会越界。因此我们需要数组向外开大一格,但只在里面9 * 9的部分建立棋盘
如图
//创建数组
char mine[ROWS][COLS] = {
0 };//存放布置好的雷的信息
char show[ROWS][COLS] = {
0 };//存放查出雷的信息
我们将存放布置好的雷的信息的数组全部初始化为‘0’
将存放查出雷的信息的数组全部初始化为‘#’
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char c)
{
for (int i = 0; i <rows; i++)
{
for (int j = 0; j < cols; j++)
board[i][j] = c;
}
}
刚刚我们说了,我们建立的是一个11 * 11的数组,但我们用到的只是9 * 9,周围的一圈就浪费了呀。为了弘扬中华民族勤俭节约的良好美德,我们将周围一圈存放棋盘的行和列,利用了数组,又让下棋时更加直接看出行和列。
//打印棋盘
void PrintBoard(char board[][COLS],int row, int col)
{
printf("-----------扫雷游戏----------\n");
for (int i = 0; i <=col; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d ", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("-----------扫雷游戏----------\n");
}
我们将‘1’作为雷,安放到棋盘中
//布置雷
void SetMine(char board[ROWS][COLS])
{
int count = COUNT;
while (count)
{
int i = rand() % ROW + 1;
int j = rand() % COL + 1;
if (board[i][j] == '0')
{
board[i][j] = '1';
count--;
}
}
}
这里我们用到了ASCII表的知识,‘0’在ASCII表上的值为48,‘1’为49,我们将(i,j)周围八个字符的ASCII值想加,减去8 * ‘0’的ASCII的值,就可以得到周围有几个‘1’,即得到周围有几个雷
//判断周围有几个雷
int GetMineCount(char mine[ROWS][COLS], int i,int j)
{
return mine[i - 1][j - 1] +
mine[i - 1][j] +
mine[i - 1][j + 1] +
mine[i][j - 1] +
mine[i][j + 1] +
mine[i + 1][j - 1] +
mine[i + 1][j] +
mine[i + 1][j + 1] - 8 * '0';
}
//排雷
void FintMine(char mine[ROWS][COLS], char show[ROWS][COLS],int row,int col)
{
int i, j;
int win = 0;
while (win<col*row-COUNT)
{
printf("请输入需要排查的行和列:");
scanf("%d%d", &i, &j);
if (i >= 1 && j >= 1 && i <= row && j <= col)//判断输入的行与列是否合法
{
if (mine[i][j] == '1')
{
printf("很不幸,你被炸死了\n");
PrintBoard(mine, ROW, COL);
break;
}
else
{
int count = GetMineCount(mine, i, j);
show[i][j] =count+'0';
win++;
PrintBoard(show, ROW, COL);//显示该格子周围有几个雷
}
}
else
{
printf("输入错误!请重新输入\n");
}
}
if (win == col * row - COUNT)
{
printf("恭喜你获胜了!\n");
}
}
为了方便代码的管理与测试,我将全部代码分为了三部分
1.头文件:用于函数的申明
2.game.c文件:用于函数的实现
3.text.c文件:代码的测试
头文件
#pragma once
#include
#include
#include
#define ROW 9
#define COL 9
#define ROWS 11
#define COLS 11
#define COUNT 10
//用户交互页面
void Menu();
//游戏实现
void Game();
//初始化棋盘
void InitBoard(char board[ROWS][COLS],int rows,int cols,char c);
//打印棋盘
void PrintBoard(char board[ROWS][COLS],int row,int col);
//布置雷
void SetMine(char board[ROWS][COLS]);
//排雷
void FintMine(char mine[ROWS][COLS], char[ROW][COL],int row,int col);
game.c文件
#include "game.h"
//用户交互页面
void Menu()
{
printf("游戏规则:输入行和列来排查雷区,如果踩中雷,被炸死,哈哈哈~~~\n");
printf("如果没有踩中,会显示当前格子周围雷的数目。当所有不是雷的格子被排查光时,游戏获胜\n");
printf("********************************\n");
printf("********** 1.play *********\n");
printf("********** 2.exit *********\n");
printf("********************************\n");
printf("输入 1 开始游戏;输入 0 退出游戏\n");
}
//游戏实现
void Game()
{
char mine[ROWS][COLS] = {
0 };//存放布置好的雷的信息
char show[ROWS][COLS] = {
0 };//存放查出雷的信息
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '#');
//PrintBoard(mine, ROW, COL);
PrintBoard(show, ROW, COL);
SetMine(mine, ROW, COL);
//PrintBoard(mine, ROW, COL);
FintMine(mine, show, ROW, COL);
}
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char c)
{
for (int i = 0; i <rows; i++)
{
for (int j = 0; j < cols; j++)
board[i][j] = c;
}
}
//打印棋盘
void PrintBoard(char board[][COLS],int row, int col)
{
printf("-----------扫雷游戏----------\n");
for (int i = 0; i <=col; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d ", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("-----------扫雷游戏----------\n");
}
//布置雷
void SetMine(char board[ROWS][COLS])
{
int count = COUNT;
while (count)
{
int i = rand() % ROW + 1;
int j = rand() % COL + 1;
if (board[i][j] == '0')
{
board[i][j] = '1';
count--;
}
}
}
//判断周围有几个雷
int GetMineCount(char mine[ROWS][COLS], int i,int j)
{
return mine[i - 1][j - 1] +
mine[i - 1][j] +
mine[i - 1][j + 1] +
mine[i][j - 1] +
mine[i][j + 1] +
mine[i + 1][j - 1] +
mine[i + 1][j] +
mine[i + 1][j + 1] - 8 * '0';
}
//排雷
void FintMine(char mine[ROWS][COLS], char show[ROWS][COLS],int row,int col)
{
int i, j;
int win = 0;
while (win<col*row-COUNT)
{
printf("请输入需要排查的行和列:");
scanf("%d%d", &i, &j);
if (i >= 1 && j >= 1 && i <= row && j <= col)//判断输入的行与列是否合法
{
if (mine[i][j] == '1')
{
printf("很不幸,你被炸死了\n");
PrintBoard(mine, ROW, COL);
break;
}
else
{
int count = GetMineCount(mine, i, j);
show[i][j] =count+'0';
win++;
PrintBoard(show, ROW, COL);//显示该格子周围有几个雷
}
}
else
{
printf("输入错误!请重新输入\n");
}
}
if (win == col * row - COUNT)
{
printf("恭喜你获胜了!\n");
}
}
text.c文件
#include "game.h"
int main()
{
srand((unsigned int)time(NULL));//用于产生随机数
int input;
do
{
Menu();//打印用户交互页面
scanf("%d", &input);
switch (input)
{
case 1:
printf("游戏开始->\n");
Game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误!请重新输入\n");
break;
}
} while (input);
return 0;
}
好了,这次的小游戏分享就到这了。但是扫雷这个游戏不仅仅是这么一点点东西,其实它还可以继续优化,比如:周围无雷展开一盘(用递归实现)、可以标记认为是雷的格子等等。这些就交给各位读者朋友了去发现和创造了。
最后,如果本文章对你有一点点的帮助,那请点上一个小赞,您的支持与鼓励,将是我继续写作的不竭动力,非常感谢~~