C实现扫雷小游戏(简易版)

你知道,有些鸟儿是注定不会被关在牢笼里的,它们的每一片羽毛都闪耀着自由的光辉。——《肖申克的救赎》


目录

1、设计框架

2、设计流程

2.1菜单

2.2初始化雷阵

2.3生成雷 

2.4玩家输入坐标

2.5显示有多少个雷

3、所有程序的源码

3.1game.h

3.2game.c

3.3test.c


前言:

大家好,我是拳击哥。今天给大家展现的是C语言实现扫雷小游戏教程和源码的展示,相信大家都知道扫雷游戏的规则,那怎么用C语言实现呢?下面我就来讲解。


1、设计框架

首先,我们要有一个菜单来选择我是开始游戏还是退出游戏。其次我们要设计控制开始或退出后程序的走向。设计完菜单后,我们要初始化雷阵,然后玩家排雷。每排一次我们要判断雷阵周围有几个雷,直到所有的雷都被排完了我们就胜利了,反之排到雷了我们就输了。有了以上思想后,我们再来看程序流程与代码吧。


2、设计流程

我们要设计五个函数

  • 菜单
  • 初始化雷阵
  • 生成雷
  • 玩家输入坐标
  • 显示周围有多少个雷

在编上述几个函数之前,我们先创建三个文件。为了程序的条理清晰,我们要模块化程序,因此创建三个文件。分别为:test.c、game.c、game.h这三个文件

game.h头文件我们把上述几个模块函数的声明放在里面,包括库函数的头文件,我们都可以放在里面。等到game.c和test.c文件要用的时候,我们直接引用game.h头文件就行。


2.1菜单

菜单就是一个简易的黑框款,里面有开始、退出两个选择。选择1就开始,选择0就退出。它的代码为:

//test.c
void menu()
{
	printf("+------------------+\n");
	printf("|------1.开始------|\n");
	printf("|------0.退出------|\n");
	printf("+------------------+\n");
}

菜单函数我命名为menu,并且把这个函数放在了test.c里面。


2.2初始化雷阵

我们初始化雷阵我们需要两个雷盘,一个是用来排雷的雷盘,一个是显示给用户看的雷盘。排雷的雷阵里面我们可以设置雷的个数,并且用户是看不到这个雷阵的。我设置的雷盘是9*9的雷盘我们来看代码:

//game.h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define EasyGame 20

#define H 9
#define L 9

#define HS H+2
#define LS L+2

//game.h
void InitB(char board[HS][LS], int h, int l, char rat);

//test.c
void test()
{
	char mine[HS][LS] = { 0 };
	char show[HS][LS] = { 0 };
	InitB(mine, HS, LS, '0');
	InitB(show, HS, LS, '*');

	PrintB(mine, H, L);
	PrintB(show, H, L);
	

	SetB(mine, H, L);

	FindB(mine, show, H, L);
}

//game.c
void InitB(char board[HS][LS], int h, int l, char rat)
{
	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < l; j++)
		{
			board[i][j] = rat;
		}
	}
}

我给初始化雷阵函数起名为InitBmine是排雷雷阵,show是用户展现雷阵。那么我在test.c里面初始化这两个雷阵并且调用InitB函数来修改雷阵,mine雷阵我设置全为‘0’,show雷阵我设置全为‘*’。注意是字符类型的。InitB函数的InitB函数的定义放在game.c里面,InitB函数的声明放在game.h里面。

可能有的朋友说不是9*9的雷阵为啥传参给InitB是11*11,因为我们在判断周围有多少雷的时候假设我们输入的是第9行的坐标那么9*9的雷阵就越界了,因此我传给InitB的是雷阵是9*9我们只需要在9*9里面生成雷就好了,外面那一层里面始终是字符'0'。这样判断的时候不会造成数组越界。


2.3生成雷 

生成雷我们在排雷雷阵mine里面生成,你可以任意设置你想要的雷数。

//game.h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define EasyGame 20

#define H 9
#define L 9

#define HS H+2
#define LS L+2

//game.h
#define EasyGame 20

//game.h
void SetB(char mine[HS][LS], int h, int l);

//test.c
void test()
{
	char mine[HS][LS] = { 0 };
	char show[HS][LS] = { 0 };
	
	SetB(mine, H, L);
}

//game.c
void SetB(char mine[HS][LS], int h, int l)
{
	int count = EasyGame;
	while(count)
	{
		int x = rand() % h + 1;
		int y = rand() % l + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

我给生成雷函数名为SetB,EasyGame是雷数,我设置的是20个你也可以修改。 设置雷就把原来初始化雷为'0'改成'1',注意是字符0和1。


2.4玩家输入坐标

玩家输入坐标,首先得判断这个坐标之前有没有被输入过。再判断是不是雷,是雷就被炸死了。不是雷就显示用户雷阵中该坐标周围有几个雷,这时候就需要调用一个找到该坐标附近雷数的函数get_mine

//game.h
void FindB(char mine[HS][LS], char show[HS][LS], int h, int l);

//game.c
int get_mine(char mine[HS][LS], int x, int y)
{
	return (mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1]) - 8 * '0';
}

//game.c
void FindB(char mine[HS][LS], char show[HS][LS], int h, int l)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win<(h*l-EasyGame))
	{
		printf("请输入您要排查的坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= h && y >= 1 && y <= l)
		{
			if (show[x][y] != '*')
			{
				printf("坐标已重名,请重新输入:>\n");
				continue;
			}
			if (mine[x][y] == '1')
			{
				printf("很遗憾你被炸死了...\n");
				PrintB(mine, H, L);
				break;
			}
			else
			{
				int n=get_mine(mine, x, y);
				show[x][y] = n+'0';
				PrintB(show, H, L);
				win++;
			}
		}
		else
		{
			printf("请输入正确的坐标:>\n");
		}
	}
	if (win == (h * l - EasyGame))
		printf("恭喜你,排雷成功!\n");
}

判断坐标有没有输入过。只要show雷阵里面的该坐标(输入的坐标)!=*就证明这个坐标未输入过,当然如果恰好你输入的是雷就被炸死了,没有就显示周围的雷数。 


2.5显示有多少个雷

get_mine函数是怎么判断呢,假设我输入的坐标是5,5我要知道该坐标周围有几个雷这时候。把周围8个坐标加起来然后减去8*'0',假设周围有3个雷那么就是5*'0'+3*'1'-8*'0'得到的就是数字3,数字3再加字符'0'就得到了字符'3'然后赋值给show雷阵中的该坐标,这样就达成了显示该坐标有几个雷。

win是每输入一次坐标就自增一次,直到win<(h*l-EasyGame)也就是win等于没有雷的坐标总数时退出循环。

最后判断输赢的是行乘以列然后减去EasyGame,如果win等于h*l-EasyGame那么所有的雷就找到了。


3、所有程序的源码

3.1game.h

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define EasyGame 20

#define H 9
#define L 9

#define HS H+2
#define LS L+2

void InitB(char board[HS][LS], int h, int l, char rat);

void PrintB(char show[HS][LS], int h, int l);

void SetB(char mine[HS][LS], int h, int l);

void FindB(char mine[HS][LS], char show[HS][LS], int h, int l);

3.2game.c

#include"game.h"

void InitB(char board[HS][LS], int h, int l, char rat)
{
	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < l; j++)
		{
			board[i][j] = rat;
		}
	}
}


void PrintB(char show[HS][LS], int h, int l)
{
	printf("-----扫雷游戏------\n");
	for (int i = 0; i <= l; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 1; i <= h; i++)
	{
		printf("%d ", i);
		for (int j = 1; j <= l; j++)
		{
			printf("%c ", show[i][j]);
		}
		printf("\n");
	}
	printf("-----扫雷游戏------\n");
}

void SetB(char mine[HS][LS], int h, int l)
{
	int count = EasyGame;
	while(count)
	{
		int x = rand() % h + 1;
		int y = rand() % l + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

int get_mine(char mine[HS][LS], int x, int y)
{
	return (mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1]) - 8 * '0';
}

void FindB(char mine[HS][LS], char show[HS][LS], int h, int l)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win<(h*l-EasyGame))
	{
		printf("请输入您要排查的坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= h && y >= 1 && y <= l)
		{
			if (show[x][y] != '*')
			{
				printf("坐标已重名,请重新输入:>\n");
				continue;
			}
			if (mine[x][y] == '1')
			{
				printf("很遗憾你被炸死了...\n");
				PrintB(mine, H, L);
				break;
			}
			else
			{
				int n=get_mine(mine, x, y);
				show[x][y] = n+'0';
				PrintB(show, H, L);
				win++;
			}
		}
		else
		{
			printf("请输入正确的坐标:>\n");
		}
	}
	if (win == (h * l - EasyGame))
		printf("恭喜你,排雷成功!\n");
}

3.3test.c

#include"game.h"

void test()
{
	char mine[HS][LS] = { 0 };
	char show[HS][LS] = { 0 };
	InitB(mine, HS, LS, '0');
	InitB(show, HS, LS, '*');

	PrintB(show, H, L);

	SetB(mine, H, L);

	FindB(mine, show, H, L);
}

void menu()
{
	printf("+------------------+\n");
	printf("|------1.开始------|\n");
	printf("|------0.退出------|\n");
	printf("+------------------+\n");
}

int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请输入您选择的数:>");
		scanf("%d", &input);
		switch (input)
		{
		case 0:printf("您已退出游戏!\n"); break;
		case 1:test(); break;
		default:printf("请输入正确的数字:>\n"); break;
		}
	} while (input);
	return 0;
}

本期博客就到这里结束了,如有不懂可在评论区留言

 Never Give Up


  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只爱打拳的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值