思路
实现扫雷小游戏的设计,首先要有两个棋盘(一大一小,用数组实现),一个隐藏雷的位置,一个给玩家看(没有任何提示价值,不会影响游戏的公正性),两个数组同时存在但同时之只展示一种,若玩家未踩雷,则只展示隐藏雷的数组,已扫的位置置为0,若玩家踩雷,则显示已踩雷,游戏结束并显示所有雷的分布;然后要初始棋盘;再生成十个雷的位置;扫雷,若扫中则本局游戏结束,若没扫中则扫的地方的符号变成相邻地方有雷的数量。
注:文章末有该游戏全代码
1.创建文件
此次扫雷游戏需要创建三个文件分别为game.h , game.c , text.c
头文件game.c用于对函数的声明
源文件text.c用于游戏主函数及游戏测试
源文件game.c用于功能的具体实现
2.菜单的打印
在text.c文件中创建一个menu函数用于打印菜单内容。
创建test函数用于实现菜单功能的实现。
该功能的实现运用了do while循环与switch语句,通过用户的输入进入对应的功能实现不同的效果。
此代码的缺点是用户只能输入数字,无法输入字母等其他符号。
3.游戏逻辑
当用户输入1时将进入game函数,game函数功能的实现分为图中四个部分。
3.1初始化棋盘
该扫雷游戏是9*9大小的棋盘
ps1 首先game()函数中创建两个数组mine,show分别为存放雷的信息,存放被查出的雷的信息。
ps2 在头文件game.h中定义ROW,COL,ROWS,COLS的值,便于后续更改棋盘的大小。
9*9的棋盘却要创建11*11的ROWS*COLS是为了便于后续统计边缘上非雷棋子周围雷的个数
棋盘的初始化
创建一个Initboard函数分别初始化两个棋盘
最终用户看到的只是Initboard(show,ROWS,COLS,'*')函数展示出的棋盘
在头文件game.h中对该函数进行声明
在源文件game.c中对Initboard函数的功能具体化实现
通过两个for循环初始化棋盘
3.2打印棋盘
初始化棋盘之后需要进行打印棋盘
在头文件game.h中对该函数进行声明
在源文件game.c中将该函数进行具体化实现
此时我们可以给棋盘加上坐标,将函数改为如图
3.3布置雷
在game()函数中创建setmine()函数
在源文件game.h中对该函数进行声明
声明过后在game.c中对该函数进行实现
此处用到了随机数,需在源文件text.c中的text()函数中添加
srand((unsigned)time(NULL)) 以及在头文件game.h中添加#include<time.h>
此时如果想查看随机生成雷的位置,
需要将函数DispalyBoard(mine, ROW, COL)挪动到函数setmine(mine,ROW,COL)之后
3.4排查雷
在源文件text.c中的game()函数中创建Findmine()函数
在头文件game.h中对该函数进行声明
在game.c中对该函数进行具体实现
统计周围雷的个数
至此该游戏已经完成
缺点:该代码只实现了最基本的扫雷,无法做到传统扫雷的计时,插旗以及扫到的坐标周围雷的数量为0时空出一片无雷区的功能。
4.全代码
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"mine.h"
//初始化棋盘
void Initboard(char board[ROWS][COLS], int rows, int cols,char set)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for ( j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
//打印棋盘
void DispalyBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
for (i = 0; i <=row; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)//因为展现给用户9*9的棋盘即可,所以i=1,i<=row(9)
{
printf("%d ",i);
int j = 0;
for (j = 1; j <= col; j++)//和上述解释相同
{
printf("%c ", board[i][j]);
}
printf("\n");//换行
}
}
//布置雷是在棋盘上随机找十个坐标
void setmine(char mine[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;//雷的个数
int x = 0;
int y = 0;
while (count)
{
//利用随机数生成雷的坐标
x = rand()%row+1;//范围1-9
y = rand()%col+1;//范围1-9
if (mine[x][y] != '1')//如果随机的位置没有雷即不为1 布置一个雷
{
mine[x][y] = '1';
count--; //布置一个雷之后,雷的个数-1 直到-为0后不再进行循环
}
}
}
//排查雷
int get_mine_count(char mine[ROWS][COLS], int x,int y)
{
return mine[x - 1][y - 1] +
mine[x - 1][y] +
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 Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int win = 0;
int x = 0;
int y = 0;
while (1)
{
printf("请输入你要排查的坐标》");
scanf("%d %d",&x,&y);
if (x>=1 &&x<=row&&y>=1&&y<=col)//判断坐标是否越界
{
if (mine[x][y] == '1')//判断这个位置是不是雷 //如果是雷,就炸死,游戏结束
{
printf("很遗憾你被炸死了");
DispalyBoard(mine, ROW, COL);//死亡之后,打印雷的分布图
break;
}
else //如果不是,就统计这个位置周围的雷的个数,直到获胜或炸死
{
int count = get_mine_count(mine, x, y);
show[x][y] = count + '0';
DispalyBoard(show, ROW, COL);//获胜之后,打印雷的分布图
win++;
}
}
else
{
printf("输入的坐标有误");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你排雷成功\n");
DispalyBoard(mine, ROW, COL);
}
}
text.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"mine.h"
void menu()//目录
{
printf(" <欢迎来到扫雷游戏> \n");
printf("************************\n");
printf("********1.play**********\n");
printf("********0.exit**********\n");
printf("************************\n");
}
void game()
{
char mine[ROWS][COLS] = {0};//存放雷的信息
char show[ROWS][COLS] = {0};//存放排查出的雷的信息
//初始化棋盘
Initboard(mine,ROWS,COLS,'0');
Initboard(show, ROWS, COLS, '*');
//打印棋盘
DispalyBoard(show, ROW, COL);
//布置雷
setmine(mine,ROW,COL);
DispalyBoard(mine, ROW, COL);
//排查雷
Findmine(mine, show, ROW, COL);
}
void test()
{
//打印目录
int sel = 0;
srand((unsigned)time(NULL));
do
{
menu();
scanf("%d", &sel);
switch (sel)
{
case(1):
printf("欢迎来到扫雷游戏!\n");
game();
break;
case(0):
printf("退出扫雷游戏\n");
break;
default:
printf("输入错误请重新输入\n");
break;
}
} while (sel);
return 0;
}
int main()
{
test();
return 0;
}
game.h
#pragma once
#include<stdio.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
#include<time.h>
//初始化棋盘
void Initboard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DispalyBoard(char board[ROWS][COLS],int row,int col);
//布置雷
void setmine(char mine[ROWS][COLS], int row, int col);
//排查雷
void Findmine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);