重生之我在C语言玩扫雷

思路

实现扫雷小游戏的设计,首先要有两个棋盘(一大一小,用数组实现),一个隐藏雷的位置,一个给玩家看(没有任何提示价值,不会影响游戏的公正性),两个数组同时存在但同时之只展示一种,若玩家未踩雷,则只展示隐藏雷的数组,已扫的位置置为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);

  • 33
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值