C语言项目——简易版扫雷小游戏

目录

1.前言

2.游戏主体的实现

2.1 使用menu函数实现主界面的打印

2.2 使用game函数实现游戏

2.2.1 用初始化棋盘函数初始化两个棋盘

 2.2.2 将初始化后的棋盘进行打印

 2.2.3 在棋盘中布置雷

2.2.4 使玩家能够排查雷

 2.2.5 统计小方块周围雷的个数

 2.3 游戏胜利的判断

 3.总代码

1.  game.h —— 函数的定义与声明

 2.  game.c ——游戏主体模块的实现

 3.  test.c ——游戏菜单以及函数的引用


1.前言

 扫雷作为大家耳熟能详的游戏相信不少人玩过,肯定有很多人会好奇它是如何实现的,所以今天我们将运用数组与函数的知识来完成这个C语言小游戏, 通过这个项目, 相信大家一定能通过它掌握用函数,数组等工具并用其构建起一个小项目

     让我们先来回忆一下扫雷:

    efc4bad982884b54ae6de6438f8202f0.png   

以9×9为例,81方格个中存放着10个雷,以一个小方格为中心的一圈内存在多少雷,这个方格就显示多少雷,所以我们要利用提示一步一步的把10个雷排查完,才能获得游戏胜利

 所以我们应该怎么去实现呢🤔🤔?

1.利用数组, 定义若干个二维数组,进行初始化,雷的存放

2.利用函数,将我们所需的功能分模块编写,既简明清晰,又能提升我们的效率

所以我们可以定义 2个.c文件用于存放游戏模块以及代码的实现,用.h文件进行声明所用函数

game.h test.c game.c

2.游戏主体的实现

2.1 使用menu函数实现主界面的打印

我们将其放入test.c中

void menu()
{
	printf("*********************\n");
	printf("****0.exit 1.play****\n");
	printf("*********************\n");
}

 再通过switch和do...while语句实现玩家的选择

int main()
{
	int input = 0;
	do
	{
		menu();
        srand((unsigned int)time(NULL));//生成随机数
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 0:printf("退出游戏");
			break;
		case 1:game();
			break;
		default:printf("输入错误, 请重新输入\n");
		}
	} while (input);
	return 0;
}

2.2 使用game函数实现游戏

在实现之前,我们想象一个空的9×9雷盘,有雷的地方我们布置为1,没有雷的地方为零,这样在后续对数组数据的处理中我们便可以直接相加

但此时我们会发现在边缘区域查找雷的时候可能会发现这些情况:

1.数组越界我们无法统计周围雷的信息

2.当我们统计完其中一个小方格周围的雷数时,放进小方格所对应数组中,在下一个小方格排雷过程中可能会产生歧义

所以我们可以将雷盘扩大为11×11,同时定义2个二维数组一个存放雷的信息, 一个用与存放排查雷的信息

所以我们可以先在game.h中定义行与列的大小(方便日后改变雷盘大小)

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

2.2.1 用初始化棋盘函数初始化两个棋盘

先定义两个函数 一个用来初始化雷的信息 一个用来隐藏雷的信息

Initboard(mine, ROWS, COLS, '0');//初始化为0
Initboard(show, ROWS, COLS, '*');//初始化为*

并在game.h中定义 在game.c中实现

 两个棋盘的初始化:

void Initboard(char arr[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
			arr[i][j] = set;
	}
}

 2.2.2 将初始化后的棋盘进行打印

定义两个函数,一个用来隐藏雷的信息, 一个用来显示雷的信息

Displayboard(show, ROW, COL);//只需打印9×9中的内容
//Displayboard(mine, ROW, COL);//用于查看雷的布局 在后续查看雷是否成功放置可以使用

同样在game.h中定义 在game.c中实现

 打印棋盘:

void Displayboard(char arr[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
    printf("*********扫雷*********\n");
	//打印列号
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);//打印行号
		for (j = 1; j <= col; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
    printf("*********扫雷*********\n");
}

结果:

 2.2.3 在棋盘中布置雷

定义一个函数用于布置雷

Setmine(mine, ROW, COL);
Displayboard(show, ROW, COL);

同样在game.h中声明,在game.c中实现

 用于随机生成雷

void Setmine(char arr[ROWS][COLS], int row, int col)
{
	//生成雷
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';
			count--;
		}
	}
}

  成功生成10个雷

2.2.4 使玩家能够排查雷

定义一个函数用于排查雷

Findmine(mine, show, ROW, COL);

同样在game.h中声明,在game.c中实现

 函数的实现

void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
    int win = 0;
	
	while (win < row * col - EASY_COUNT)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (arr[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				Displayboard(show, ROW, COL);
				break;
			}
			else
			{
				//非雷,统计雷
				int n = Getminecount();
                show[x][y] = n + '0';
                Displayboard(show, ROW, COL);
                win++;
			}
		}
		else
			printf("坐标非法,请重新输入");
	}

其中统计雷用Getminecount函数实现

  • 小知识点:数字加上字符‘0’ 可以转为相应的数字字符
  • 同理数字字符减去字符‘0’ 可以得到相应的数字

 2.2.5 统计小方块周围雷的个数

定义一个函数用于统计雷数,并用一个整形变量接收,然后转为字符型放在show数组中

int n = Getminecount(mine, x, y);

同样在game.h中声明,在game.c中实现

函数的实现

int Getminecount(char mine[ROWS][COLS],  int x, int y)
{
	return (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] + mine[x + 1][y] + mine[x + 1][y - 1] - 8 * '0');
}

 2.3 游戏胜利的判断

在此处我们可以在game.h 中定义一个 EASY_COUNT 用于存放雷的个数 当我们后续测试游戏胜利的代码时,可以直接改变EASY_COUNT的值,更方便调试

判断胜利的实现

if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		Displayboard(mine, ROW, COL);
	}

 3.总代码

1.  game.h —— 函数的定义与声明

#define _CRT_SECURE_NO_WARNINGS 1

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

#define ROW 9
#define COL 9
#define EASY_COUNT 10

#define ROWS ROW+2
#define COLS COL+2

//初始化棋盘
void Initboard(char arr[ROWS][COLS], int rows, int cols, char set);

//打印棋盘
void Displayboard(char arr[ROWS][COLS], int row, int col);

//设置雷
void Setmine(char arr[ROWS][COLS], int row, int col);

//排查雷
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

 2.  game.c ——游戏主体模块的实现

#include"game.h"

//初始化棋盘
void Initboard(char arr[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
			arr[i][j] = set;
	}
}

//展示棋盘
void Displayboard(char arr[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("*********扫雷*********\n");
	//打印列号
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);//打印行号
		for (j = 1; j <= col; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
	printf("*********扫雷*********\n");

}

//设置雷
void Setmine(char arr[ROWS][COLS], int row, int col)
{
	//生成雷
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';
			count--;
		}
	}
}

//获取周围有几个雷
int Getminecount(char mine[ROWS][COLS],  int x, int y)
{
	return (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] + mine[x + 1][y] + mine[x + 1][y - 1] - 8 * '0');
}

//排查雷
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;

	while (win < row * col - EASY_COUNT)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				Displayboard(mine, ROW, COL);
				break;
			}
			else
			{
				//非雷,统计雷
				int n = Getminecount(mine, x, y);
				show[x][y] = n + '0';
				Displayboard(show, ROW, COL);
				win++;
			}
		}
		else
			printf("坐标非法,请重新输入");
	}

	//游戏胜利
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		Displayboard(mine, ROW, COL);
	}
}

 3.  test.c ——游戏菜单以及函数的引用

#include"game.h"

void menu()
{
	printf("*********************\n");
	printf("****0.exit 1.play****\n");
	printf("*********************\n");
}
void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];

	//初始化棋盘
	Initboard(mine, ROWS, COLS, '0');//初始化为0
	Initboard(show, ROWS, COLS, '*');//初始化为*
	//打印棋盘
	//Displayboard(show, ROW, COL);//只需打印9×9中的内容
	//Displayboard(mine, ROW, COL);//用于查看雷的布局

	//布置雷
	Setmine(mine, ROW, COL);
	Displayboard(show, ROW, COL);
    //Displayboard(mine, ROW, COL);//用于查看雷的布局
	//排查雷
	Findmine(mine, show, ROW, COL);
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 0:printf("退出游戏");
			break;
		case 1:game();
			break;
		default:printf("输入错误, 请重新输入\n");
		}
	} while (input);
	return 0;
}
  •  运行截图

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值