个人主页:小田爱学编程
系列专栏:c语言从基础到进阶
关注博主,随时获取更多关于c语言的优质内容!
欢迎来到小田代码世界~
喜欢的小伙伴记得一键三连哦 ૮(˶ᵔ ᵕ ᵔ˶)ა
目录
一、扫雷游戏
二.游戏的分析和设计
1.数据结构的分析
2.文件结构设计
三、游戏的实现
game.h
game..c
test.c
四、小白答疑
五、游戏呈现
六、大佬扩展
把前面学的一些知识给整合起来,做一个简单的扫雷游戏,扫雷游戏想必大家都玩过,但是这个游戏的底层逻辑是啥呢?下面的这个扫雷游戏有点简单,大佬勿喷
扫雷游戏网页版 - Minesweeperhttps://www.minesweeper.cn/#google_vignette基本规则:左键翻开这一格,右键标记地雷,双击左键(或者左右键一起点)可以看到这个数字的可点击范围,你点出了一个数字,是1,就说明它周围的8的格子里有1个雷,是2就有两个雷,是3就有三个雷···以此类推。如果你把数字周围的雷全扫出后还有空格,不必再一格一格翻开,直接双击左键就可以了。但如果你标记错了雷,那就会"boom!"一切重新开始。
在扫雷的过程中,布置的雷的个数和排查雷的个数,以及不是雷的个数都需要我们去存储,存储当然会想到数组,不是雷的个数使用排除法只需要把全部的个数存储起来,使用排除法即可。我们首先布置一个9*9的数组,在这个数组中用1代表雷,而没有布置雷的时候放0
char mine=[9][9]={0};存储出雷的信息
这样的设置却存在一个问题,我们都知道如果这个地方安全,会以其为中心,周围8个都是其排查对象,所以我们就要去扩大数组,也就是去扩大棋盘
char mine=[11][11]={0};存储出雷的信息
假如我们排查出了一个位置后,这个位置不是雷,周围有雷,那么周围排查出来雷的个数该怎么存储呢?如果存储在布置雷的数组中,这样雷的信息和雷的个数就乱了。
有什么方法:1.我们可以用数字和字符进行区分但是还是比较杂,不够方便
2.我们专⻔给⼀个棋盘(对应⼀个数组mine)存放布置好的雷的信息,再
给另外⼀个棋盘(对应另外⼀个数组show)存放排查出的雷的信息。
而且为了保持神秘 ,我们专⻔给⼀个棋盘(对应⼀个数组mine)存放布置好的雷的信息,再
给另外⼀个棋盘(对应另外⼀个数组show)存放排查出的雷的信息,所以我们要设置出两个数组 。上代码
char mine[11][11]={0};
char show[11][11]={0};
多文件的形式对函数的声明和定义
1.test.c 文件中写游戏的测试逻辑
2.game.c文件中写游
戏
中函数的实现等
3.game.h文件中写游戏需要的数据类型和函数声明
#pragma once
#include
#include
#include
#define EASY_COUNT 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//初始化棋盘
void InitBoard(chan board[ROWS][COLS],int rows,int cols,char set);
//这里的set是一个集合,由二维数组创建的一个的x*x的一个棋盘
//打印棋盘
void Dispayboard(char board[ROWS][COLS],int row ,int col)
//布置雷
void Setminw(chae board(ROWS)(COLS),int row,int col);
//排查雷
void FindMine(char mine[Rows][COLS],char show[ROWS][COLS],int row,int col);
#include "game.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 DisplayBoard(char board[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 ", board[i][j]);
}
printf("\n");
}
}
void SetMine(char board[ROWS][COLS], int row, int col)
{
//布置10个雷
//⽣成随机的坐标,布置雷
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
static int GetMineCount(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 FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{
intx,y,win;
while(win");
scanf("%d %d",&x,&y);
if(x>=1&&x<=row&&y>=1&&y<=col)
{
if(mine[x][y]='1')
{
printf("很遗憾,你被炸死了\n")
DispayBoard(mine,ROW,COL);
break;
}
else{
//该位置不是雷,就统计这个坐标周围雷的个数
int count=GetMineCount(mine,x,y);
show[x][y]=count+'0';
Dispayboard(show,ROW,COL)
win++
}
}
else
{
printf("坐标非法,重新输入\n");
}
}
if(win==row*col-EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DispayBoard(mine,ROW,COL);
}
#include"game.h"
void menu()
{
printf("***********************\n");
printf("***** 1. play *****\n");
printf("***** 0. exit *****\n");
printf("***********************\n");
}
void game()
{
char mine[ROWS][COLS]; //存放布置好的雷
char show[ROWS][COLS]; //存放排查出的雷的信息
//初始化棋盘
//1. mine数组最开始是全'0'
//2. show数组最开始是全'*'
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//打印棋盘
//DisplayBoard(mine, ROW, COL);
DisplayBoard(show, ROW, COL);
//1. 布置雷
SetMine(mine, ROW, COL);
//DisplayBoard(mine, ROW, COL);
//2. 排查雷
FindMine(mine, show, ROW, COL);
}
int main()
{
int input=0;
scrand((unsighed int(time)(NULL);
do
{
menu();
printf("请选择:>" );
scanf("%d",&input);
swich(input)
{
case 1:
game()
break;
case 0;
printf("退出游戏\n");
break;
这样就实现了扫雷游戏的简单实现,但是想必各位小伙伴有很多问题:
.
1.这里的行和列可以从1循环开始吗?
如果从1开始,会有这个结果
2.这里是什么意思
我们在前面说过了为了神秘,使用字符来定,但是数字和字符怎么转换呢?3
3.这里是什么意思
为了统计周围周围有几个0
第二个实践,虽然不太好,但也尽力了,以后会改进。
今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,您的支持就是我前进的动力!