- 我是一名大一新生,今天是我发表博客的第一天,将通过已学知识来讲解一下如何使用C语言来编写扫雷小游戏.希望大家有所收获,互相进步.
- 游戏介绍:
- 游戏整体框架
- 游戏具体功能及实现:
- 雷盘的定义
- 雷盘的初始化
- 布置雷
- 排查雷
- 获取周围雷的个数
- 打印雷盘
- 游戏完整代码:
- 1、test.c
- 2、game.h
- 3、game.c
- 游戏效果展示
1:游戏介绍:扫雷即是将雷盘中中的所有雷清排出来,每回合选择一个坐标,若此处有雷,则玩家被炸死退出游戏;若此处没有雷则继续并且显示此处周围(即一圈8个位置)有多少个雷,当所有雷被玩家拍排出来时,游戏胜利.
2:游戏整体框架
- 相信大家经过一学期的学习已经有了不错的知识储备,当然还要养成良好习惯,为以后在公司团队合作编程打下基础,因此我们把扫雷游戏分成三个文件(1个头文件,2个源文件)来编写:
- test.c:游戏逻辑的测试,包含游戏菜单的打印,游戏设计的基本逻辑的展示。
- game.c:游戏功能的具体实现,这部分是整个游戏的核心代码,一般不会展示给用户。
- game.h:相关头文件的包含、符号的声明以及函数的声明。
游戏具体功能及实现:
1.首先我们把游戏的雷盘做好:
当我们排查2位置时,如果2处不是雷,那么我们就会依次检查1周围8个坐标是否有地雷,如果有,就会把地雷的数量显示在2位置处;但是当我们排查1位置时,我们发现, 数组排查雷时会发生越界,所以为了避免这种,我们就需要增加一系列限制条件,这样是比较麻烦的,所以我们可以:在定义数组长度时我们直接在上下左右四个方向各多给一行的空间,并把这些空间中的数据初始化为非雷.(如下,可以看下面显示情况)
2.初始化雷盘:
因为我们有两个雷盘,所以使用函数来初始化更加方便,set就是雷盘上的元素符号
3.布置雷:
- 注意:随机生成坐标的rand函数的种子srand函数只需要在函数中声明一次。
- 我们在布置雷的时候需要检查判断该位置是否已经有雷,避免重复布置。
4:开始排查雷:
1.输入坐标2.判断坐标是否合法3.判断坐标是否已经排查过(避免重复)4.开始判断有无雷(初学者小心忘了break)
注意:白色箭头(在运行时一遍又一遍排除会使控制台冗长不易操作观看)
所以我们可以通过清屏操作在每一次操作后把之前的部分清除,方便操作
5.获取周围雷的个数:传参为一个整形数据
6.打印雷盘:
游戏完整代码:
game.h头文件
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_setcount 10//雷数量
void initboard(char arr[ROWS][COLS], int rows, int cols, char set);
void setmine(char arr[ROWS][COLS], int row, int col);
void display(char arr[ROWS][COLS], int row, int col);
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//初始化
void initboard(char arr[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++)
{
arr[i][j] = set;
}
}
}
//打印结果
void display(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
printf("-----扫雷游戏-----\n");
//打印列的序号
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
//打印雷区
for (i = 1; i <= row; i++)
{
printf("%d ", i);//打印行的序号
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
//布置雷
void setmine(char arr[ROWS][COLS], int row, int col)
{
int count = EASY_setcount;
while (count)
{
int x = rand() % row + 1;//随机生成坐标
int y = rand() % col + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
static int getminecount(char mine[ROWS][COLS], int x, int y)
{
int i = 0, j = 0;
int count = 0;
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
count += (mine[i][j] - '0');
}
}
return count;
}
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0, y = 0;
int win = 0;
while (win<row*col- EASY_setcount)
{
printf("输入坐标:");
scanf("%d%d", &x, &y);
if (x > 0 && x <= row && y>0 && y <= col)
{
if (show[x][y] == '*')
{
if (mine[x][y] == '1')
{
system("cls");
printf("很遗憾,你被炸死了\n");
display(mine, ROW, COL);
break;
}
else
{
//则告诉玩家此地周围有几个雷
system("cls");
int count = getminecount(mine, x, y);
show[x][y] = (count + '0');
display(show, ROW, COL);
win++;
}
}
else
{
printf("该坐标已经被排查了,重新输入坐标\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
if (win == ROW * COL - EASY_setcount)
{
system("cls");
printf("恭喜你,排雷成功\n");
display(mine, ROW, COL);
}
}
test.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
//目录
printf("********************\n");
printf("****** 1.play ******\n");
printf("****** 0.exit ******\n");
printf("********************\n");
}
void game()
{
//使用二维数组定义雷盘,ROWS行,COLS列
char mine[ROWS][COLS] = { 0 };//实际的
char show[ROWS][COLS] = { 0 };//显示出来的
//初始化mine和show
initboard(mine, ROWS, COLS, '0');
initboard(show, ROWS, COLS, '*');
//随机布置雷
setmine(mine, ROW, COL);
//打印出来,display
//display(mine, ROW, COL);
display(show, ROW, COL);
//开始排查雷
findmine(mine, show, ROW, COL);
}
//基本框架
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("输入错误,请重新选择\n");
break;
}
} while (input);//0就结束循环了
}
int main()
{
test();
return 0;
}
希望对大家有所帮助!下面是我的gitee账号,大家可以互相交流
阿刘c语言 (aliuc-language) - Gitee.com
谢谢观看!