c语言实现扫雷小游戏1

🏷️前言

扫雷小游戏是电脑自带的一个趣味小游戏,相信许多小伙伴对它都有所了解,那么如和使用C语言来编写出一个扫雷游戏呢?
接下来,我将详细为大家讲解如和用C语言来实现一个简化版扫雷小游戏,如果觉得内容对你有所帮助,请点个赞支持一下吧!💓
在这里插入图片描述

📕游戏整体思路

  1. 创建三个文件test.c 、扫雷.c 、 扫雷.h
  2. 在test.c文件中写出游戏的大体框架
  3. 在扫雷.c文件中编写游戏的具体实现过程
  4. 在扫雷.h文件中将所使用到的函数进行声明

📙代码讲解

📖游戏框架

  1. 引用扫雷.h头文件
  2. 初始化随机函数种子
  3. 游戏选项至少执一次,所以用do…while循环来实现游戏整体框架的构建
  4. 调用menu()函数打印游戏的菜单
  5. 通过使用switch选择语句来判断玩家所选择的游戏状态
  6. 调用game()函数实现游戏过程

代码如下:(代码中附有讲解)

#define _CRT_SECURE_NO_WARNINGS
#include "扫雷.h"
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");
			break;
		}
	} while (input);
	return 0;
}

📖具体实现过程

📜游戏菜单的打印

定义一个menu()函数来实现菜单的打印:

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

📜game函数的定义

  1. 定义两个数组a和b用来储存游戏数据:
char a[ROWS][COLS] = { 0 };
char b[ROWS][COLS] = { 0 };

由于计算排查坐标周围雷的数量时,当排查边上的坐标时会发生数组越界,所以在定义数组时,将数组扩大一圈。
在这里插入图片描述

  1. 调用init_board函数初始化棋盘:
init_board(a, ROWS, COLS, '0');
init_board(b, ROWS, COLS, '*');
  1. 调用set_a函数在数组a中布置雷:

set_a(a, ROW, COL);

  1. 调用display_board函数打印棋盘,在布置雷以及每一次排雷之后都打印一次棋盘b:

display_board(b, ROW, COL);

  1. 调用find_a函数进行排雷:

find_a(a, b, ROW, COL);

代码如下:

void game()
{
	//定义两个数组,一个(a)用来存放布置好的雷的信息,另外一个(b)用来存放排查出的雷的信息
	char a[ROWS][COLS] = { 0 };
	char b[ROWS][COLS] = { 0 };

	//初始化棋盘
	//a初始化为全'0'
	//b初始化为全'*'
	init_board(a, ROWS, COLS, '0');
	init_board(b, ROWS, COLS, '*');

	//布置雷
	set_a(a, ROW, COL);

	//打印棋盘
	display_board(b, ROW, COL);

	//排雷
	find_a(a, b, ROW, COL);
}

📜初始化棋盘与打印棋盘

定义两个函数init_board和display_board,分别用于初始化棋盘和棋盘的打印:

//初始化棋盘
void init_board(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 display_board(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;

	//打印列号
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		//打印行号
		printf("%d ", i);

		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

📜布置雷

定义一个函数set_a,用来在数组a中布置雷:
布置雷可以用rand()函数生成两个随机数来当作布置雷的坐标;使用rand()之前需要在主函数中调用srand()生成时间戳,使用系统时间初始化!

void set_a(char a[ROWS][COLS], int row, int col)
{
	//随机布置10个雷
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;

		//在未被占用的格子中放置雷
		if (a[x][y] == '0')
		{
			a[x][y] = '1';
			count--;
		}
	}
}

📜排雷

定义一个函数find_a,用来进行排雷

void find_a(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;

	//总共有81个格子,当排除71个格子都没有被炸死,则游戏胜利
	while (win < (row * col - EASY_COUNT))
	{
		printf("请输入要排查的坐标:>");
		scanf("%d %d", &x, &y);

		//判断坐标的合法性以
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			//判断坐标是否被排查过
			if (b[x][y] == '*')
			{
				//判断是否踩雷
				if (a[x][y] == '1')
				{
					printf("很遗憾,你被炸死了!\n");
					display_board(a, ROW, COL);
					break;
				}
				else
				{
					int count = get_a_count(a, x, y);
					b[x][y] = count + '0';
					display_board(b, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("该坐标已经被排查过了!\n");
			}
		}
		else
		{
			printf("该坐标非法,请重新输入!\n");
		}
	}
	if (win == (row * col - EASY_COUNT))
	{
		printf("恭喜你,排雷成功!\n");
		display_board(a, ROW, COL);
	}
}

📜计算玩家排查坐标周围有多少颗雷

定义一个函数get_a_count,用来计算排查坐标周围的雷的数量:
注意:二维数组中所存的值是字符型,通过将周围的八个字符型加起来后减去八个‘0’的ARC2码值将其转换为整型
在这里插入图片描述

int get_a_count(char a[ROWS][COLS], int x, int y)
{
	return (a[x - 1][y - 1] +
		a[x - 1][y] +
		a[x - 1][y + 1] +
		a[x][y + 1] +
		a[x + 1][y + 1] +
		a[x + 1][y] +
		a[x + 1][y - 1] +
		a[x][y - 1] - 8 * '0');
}

📖在头文件中声明函数

将所用到的函数在扫雷. h 文件中进行声明:

#define ROW 9  //扫雷时打印在屏幕上的行数
#define COL 9  //扫雷时打印在屏幕上的列数
#define ROWS ROW+2  //数组的行数
#define COLS COL+2  //数组的列数

#define EASY_COUNT 10  //布置雷的个数

#include<stdio.h>

//菜单
void menu();

//玩游戏
void game();

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

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

//布置雷
void set_a(char a[ROWS][COLS], int row, int col);

//计算周围有几颗雷
int get_a_count(char a[ROWS][COLS], int x, int y);

//排雷
void find_a(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col);

📘完整代码

1. 扫雷.h文件

#define ROW 9  //扫雷时打印在屏幕上的行数
#define COL 9  //扫雷时打印在屏幕上的列数
#define ROWS ROW+2  //数组的行数
#define COLS COL+2  //数组的列数

#define EASY_COUNT 10  //布置雷的个数

#include<stdio.h>

//菜单
void menu();

//玩游戏
void game();

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

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

//布置雷
void set_a(char a[ROWS][COLS], int row, int col);

//计算周围有几颗雷
int get_a_count(char a[ROWS][COLS], int x, int y);

//排雷
void find_a(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col);

2. 扫雷.c文件

#define _CRT_SECURE_NO_WARNINGS

#include "扫雷.h"


//打印菜单
void menu()
{
	printf("****************************\n");
	printf("********** 1.play **********\n");
	printf("********** 0.exit **********\n");
	printf("****************************\n");
}



//玩游戏
void game()
{
	//游戏数据存储需要两个 9*9 的数组,但为了防止使用时数组越界,使用 11*11 的数组
	//一个(a)用来存放布置好的雷的信息,另外一个(b)用来存放排查出的雷的信息
	char a[ROWS][COLS] = { 0 };
	char b[ROWS][COLS] = { 0 };

	//初始化棋盘
	//a初始化为全'0'
	//b初始化为全'*'
	init_board(a, ROWS, COLS, '0');
	init_board(b, ROWS, COLS, '*');

	//打印棋盘
	//display_board(a,ROWS,COLS);
	//display_board(b,ROWS,COLS);
	//

	//布置雷
	set_a(a, ROW, COL);

	//打印棋盘
	//display_board(a, ROW, COL);
	display_board(b, ROW, COL);

	//排雷
	find_a(a, b, ROW, COL);
}



//初始化棋盘
void init_board(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 display_board(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;

	//打印列号
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		//打印行号
		printf("%d ", i);

		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}



//布置雷
void set_a(char a[ROWS][COLS], int row, int col)
{
	//随机布置10个雷
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;

		//在未被占用的格子中放置雷
		if (a[x][y] == '0')
		{
			a[x][y] = '1';
			count--;
		}
	}
}



//计算周围有几颗雷
int get_a_count(char a[ROWS][COLS], int x, int y)
{
	return (a[x - 1][y - 1] +
		a[x - 1][y] +
		a[x - 1][y + 1] +
		a[x][y + 1] +
		a[x + 1][y + 1] +
		a[x + 1][y] +
		a[x + 1][y - 1] +
		a[x][y - 1] - 8 * '0');
}



//排雷
void find_a(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;

	//总共有81个格子,当排除71个格子都没有被炸死,则游戏胜利
	while (win < (row * col - EASY_COUNT))
	{
		printf("请输入要排查的坐标:>");
		scanf("%d %d", &x, &y);

		//判断坐标的合法性
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			//判断坐标是否被排查过
			if (b[x][y] == '*')
			{
				//判断是否踩雷
				if (a[x][y] == '1')
				{
					printf("很遗憾,你被炸死了!\n");
					display_board(a, ROW, COL);
					break;
				}
				else
				{
					int count = get_a_count(a, x, y);
					b[x][y] = count + '0';
					display_board(b, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("该坐标已经被排查过了!\n");
			}
		}
		else
		{
			printf("该坐标非法,请重新输入!\n");
		}
	}
	if (win == (row * col - EASY_COUNT))
	{
		printf("恭喜你,排雷成功!\n");
		display_board(a, ROW, COL);
	}
}

3. test.c文件

#define _CRT_SECURE_NO_WARNINGS

#include "扫雷.h"

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	
	do
	{
		//打印菜单
		menu();

		printf("请选择:>");
		scanf("%d", &input);

		//游戏实现
		switch (input)
		{
		case 0:
			printf("退出游戏!\n");
			break;
		case 1:
			game();
			break;
		default:
			printf("输入错误,请重新输入!\n");
			break;
		}
	} while (input);
	return 0;
}

📗运行截图

在这里插入图片描述

最后,如果觉得内容对你有所帮助,就请点个赞支持一下吧!

在这里插入图片描述

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是李不是鲤

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

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

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

打赏作者

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

抵扣说明:

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

余额充值