扫雷相信大家也都应该玩过,在这里还是简单介绍一下:
《扫雷》是一款大众类的益智小游戏,游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
每个格子上显示的数字即表示该格子周围雷的个数
那么我们接下来带领大家实现一个大小为9*9的扫雷游戏:
最终实现游戏的完整代码,我们放在三个文件中,方便对我们的代码进行管理。
这三个文件分别是:
(1)test.c
用于对游戏逻辑的测试
(2)game.h
游戏实现相关的函数声明,符号声明,头文件的包含
(3)game.c
游戏实现相关函数的实现
全部的代码我们放在最后供大家参考
我们先在test.c文件对扫雷游戏的整体流程进行一个实现,测试一下逻辑是否正确,实现游戏功能的函数我们先不具体实现:
#include "game.h"
//打印菜单函数
void menu()
{
printf("**********************************\n");
printf("****** 1. play *******\n");
printf("****** 0. exit *******\n");
printf("**********************************\n");
}
//游戏实现函数
play_game()
{
printf("扫雷\n");
}
int main()
{
int elect = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &elect);
switch (elect)
{
case 1:
play_game();
break;
case 0:
printf("退出游戏!!!\n");
break;
default:
printf("选择错误,请重新选择!!!\n");
break;
}
} while (elect);
return 0;
}
既然要实现一个9X9的扫雷,我们就需要一个9X9大小的棋盘,那我们是不是可以考虑使用一个9X9的二维数组呢?
但是,如果我们就把大小设置程9*9的二维数组,会发现其实存在一些问题:
要实现扫雷的话我们就要统计一下每个格子周围雷的个数
所以,我们不妨把这个数组搞大点,用一个11X11的二维数组,外边的两圈我们不放雷就行了,这样就不会越界访问了;
现在有一个数组来放雷了,但是在游戏过程中我们是不是还需要打印雷的数量信息便于玩家排雷,所以我们再搞一个11X11的二维数组来表示雷的数量信息:
那接下来我们就定义这样两个数组并对他们按要求进行初始化;
首先,我们为了以后如果想修改棋盘大小比较方便,我们在头文件game.h 中用关键字define定义两个标识符常量:
记得在test.c和game.c中别忘了引用头文件“game.h”。
现在初始化好了,那我们定义一个打印棋盘的函数:
调用并运行一下:
现在棋盘已经设计好了,我们就可以在棋盘上布置雷了,我们规定一下,每一局我们布置10个雷:
设计一个布置雷的函数:
我们的思路是随机生成两个1~9的随机数作为雷的坐标,然后在该位置放雷,这里又用到了rand函数来生成随机数
当然记得调用srand设置随机数生成器srand((unsigned int)time(NULL)),在main函数中调用一次即可;
使用srand函数时需要包含#include
雷布置好了,那我们现在就可以排查雷了。
排查的话,我们是不是要在mine数组里面排查,因为雷是布置在这个数组里的,然后我们把排查到的信息存放到show数组中,这个数组是用来显示排查出的雷的信息的
然后我们来定义排查雷的函数,思路是这样的:
可以正常玩了!!!
(1)test.c
用于对游戏逻辑的测试
#include "game.h"
//打印菜单函数
void menu()
{
printf("**********************************\n");
printf("****** 1. play *******\n");
printf("****** 0. exit *******\n");
printf("**********************************\n");
}
//游戏实现函数
play_game()
{
//创建两个字符数组
char mine[ROWS][COLS] = { 0 }; //用于布置雷
char show[ROWS][COLS] = { 0 }; //用于显示排查的雷的信息
//初始化棋盘
InitBoard(mine, ROWS, COLS, '0'); //全部初始化为'0'
InitBoard(show, ROWS, COLS, '*'); //全部初始化为'*'
//打印棋盘
//print_board(mine, ROW, COL);
//print_board(show, ROW, COL);
//布置雷
set_mine(mine, ROW, COL);
//print_board(show, ROW, COL);
//排查雷
print_board(show, ROW, COL);
find_mine(mine, show, ROW, COL);
}
int main()
{
int elect = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:");
scanf("%d", &elect);
switch (elect)
{
case 1:
play_game();
break;
case 0:
printf("退出游戏!!!\n");
break;
default:
printf("选择错误,请重新选择!!!\n");
break;
}
} while (elect);
return 0;
}
(2)game.h
游戏实现相关的函数声明,符号声明,头文件的包含
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
//函数声明
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);//初始化棋盘的函数
void print_board(char board[ROWS][COLS], int row, int col);//打印棋盘
void set_mine(char mine[ROWS][COLS], int row, int col);//布置雷
//排查雷
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
(3)game.c
游戏实现相关函数的实现
#include "game.h"
//初始化数组的函数实现
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
//打印棋盘
void print_board(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
//打印列号
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i); //打印行号
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n"); //打印完一行需要换行
}
}
//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col)
{
int count = 10;//10个雷
while (count)
{
int x = rand() % row + 1;//生成1~9的随机数
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
//计算雷的个数
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
return (mine[x - 1][y] +
mine[x - 1][y - 1] +
mine[x][y - 1] +
mine[x + 1][y - 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] +
mine[x][y + 1] +
mine[x - 1][y + 1] - 8 * '0');
}
//排查雷
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while (win < row * col - EASY_COUNT)
{
printf("请输入要排查雷的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//坐标被排查过
if (show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
print_board(mine, ROW, COL);
break;
}
else
{
int count = get_mine_count(mine, x, y);
show[x][y] = count + '0';
print_board(show, ROW, COL);
win++;
}
}
else
{
printf("该坐标已经被排查过了\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
print_board(mine, ROW, COL);
}
}