C语言数组超详细讲解下篇扫雷

 更新时间:2022年04月13日 17:15:48   作者:初学C语言者  
数组是一组有序的数据的集合,本篇将带你结合数组来实现扫雷小游戏,上手实练更快的能够掌握数组使用,感兴趣的朋友来看看吧

前言

本文接着复习前面所学知识,以扫雷游戏为例。

1、扫雷是什么?

百度百科:《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。

在这里插入图片描述

2、程序框架

程序整体的框架可以搬用上篇三子棋的,这种框架也可以当作一种通用的形式,加以运用。

2.1 主函数

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//产生随机数
	do
	{
		menu();//菜单提示
		printf("请输入 ==> ");//输入1或0,
		scanf("%d", &input);
		switch (input)//根据输入选择是否玩游戏
		{
		case 1:
			game();//玩游戏的具体实现
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择!\n");
			break;
		}
	} while (input);

	return 0;
}

2.2 函数menu

输出提示菜单,提醒玩家,1是玩游戏,0是退出游戏

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

2.3 函数game

数组mine,初始化后放入字符 ‘0’

  • mine数组后续放入10个雷,有雷的位置用字符 ‘1’ 表示,没有雷的位置仍然是字符 ‘0’
  • 10个雷的位置随机生成

数组show,初始化后放入字符 ‘*’

  • 字符 ‘*’ 是将生成雷的位置遮挡住,不让玩家看见
  • show数组放入棋盘中关于具体坐标周围的雷的信息
  • 如果坐标周围有雷,将统计雷的个数,并显示在这个坐标上
void game()
{
	printf("开始玩游戏!\n");
	//扫雷游戏的实现
	//mine数组是用来存放布置好的雷的信息
	//就10个雷在什么位置
	char mine[ROWS][COLS] = { 0 };//'0'
	//show数组是用来存放排查出的雷的信息
	//坐标周围有几个雷
	char show[ROWS][COLS] = { 0 };//'*'

	//初始化棋盘
	init_board(mine, ROWS, COLS, '0');
	init_board(show, ROWS, COLS, '*');
	//打印棋盘
	//show_board(mine, ROW, COL);//全是字符'0'
	//show_board(mine, ROW, COL);//全是'*'
	//布置雷
	set_mine(mine, ROW, COL);//雷的数组
	//show_board(mine, ROW, COL);这是显示10个雷在哪里
	show_board(show, ROW, COL);//输出*暂时掩盖雷在哪里
	//排查雷
	find_mine(mine, show, ROW, COL);
}

2.3.1 函数init_board

init_board初始化参数是将棋盘初始化,让整个棋盘显示字符 ‘0’ 和 ‘*’

//初始化棋盘    参数:行数 列数  行数 列数 字符0或* 
void init_board(char arr[ROWS][COLS], int rows, int cols, char set)
{//set表示初始化传进来的字符是0 还是 *
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = set;
		}
	}
}

2.3.2 函数show_board

show_board是展示棋盘的,可以看到棋盘里面雷的信息,以及后续扫雷时,棋盘的具体状态

//展示棋盘
void show_board(char arr[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("------------扫雷------------\n");
	for (i = 0; i <= col; 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.3.3 函数set_mine

函数set_mine是布置雷的,会在棋盘内随机在10个坐标位置产生雷

//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//布置10个雷
	int x = 0;//行坐标
	int y = 0;//列坐标
	while (count)//直到10个雷布置完成,退出循环
	{
		x = rand() % row + 1;//取模是0-8,加1就是1-9
		y = rand() % col + 1;
		if (mine[x][y] == '0')//是空的,就放雷,否则重新随机产生坐标位置
		{
			mine[x][y] = '1';//布置雷
			count--;
		}
	}
}

2.3.4 函数find_mine

函数find_mine是排查雷,每次玩家排雷都先输入一个坐标,然后判断坐标上的字符是否为1:

  • 1为雷,游戏结束
  • 不是1,统计坐标周围8个位置雷的个数,以字符放入形式显示在坐标上
//排查雷
void find_mine(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)//在1-9的坐标范围内
		{
			if (mine[x][y] == '1')//确定坐标为字符'1',就是雷
			{
				printf("很遗憾,被炸死了\n");
				show_board(mine, ROW, COL);//显示所有雷的位置
				break;
			}
			else//不是字符1,坐标就不是雷,显示坐标周围有雷的个数
			{
				int count = get_mine_count(mine, x, y);//函数计算类的个数
				show[x][y] = count + '0';//周围有雷的个数+'0'就转换成字符了
				show_board(show, ROW, COL);//打印出来,每次扫雷后的棋盘
				win++;//扫了一次雷就++
			}
		}
		else//超过坐标范围
		{
			printf("坐标非法,重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)//扫雷次数==9*9-10 71次就结束
	{
		printf("恭喜你,排雷成功\n");
		show_board(mine, ROW, COL);//显示雷的信息
	}
}

2.3.5 函数get_mine_count

函数get_mine_count统计雷的个数:

  • 字符 ’1‘代表有雷,字符 ’0‘代表没有, ’1‘- ’0‘为数字1,代表1个雷
  • 坐标周围8个坐标上的字符相加 - 8 * ‘0’,结果就是有雷的个数,是整形
//统计坐标周围有雷的个数
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{//坐标周围的8个地方减去'0',再相加的个数就是类的个数
	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';
}

3、头文件.h

#include <stdio.h>
#include <stdlib.h>//库函数
#include <time.h>//与系统时间相关

#define ROW 9//棋盘真实的行数
#define COL 9
#define ROWS ROW+2 //棋盘放大范围,便于棋盘边的位置遍历
#define COLS COL+2
#define EASY_COUNT 10 //10个雷的个数
//初始化
void init_board(char arr[ROWS][COLS], int rows, int cols, char set);
//打印
void show_board(char arr[ROWS][COLS], int row, int col);
//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col);

4、游戏试玩

运行结果见下图,基本满足了游戏功能。

在这里插入图片描述

完整代码放在gitee中:

扫雷完整代码

总结

本文只涉及了较为基础的扫雷游戏,等后面学习更复杂的知识后,可以对扫雷游戏进行完善。扫雷游戏整体编写思路完全可以参考三子棋来实现。

到此这篇关于C语言数组超详细讲解下篇扫雷的文章就介绍到这了,更多相关C语言 三子棋内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ 自由存储区是否等价于堆你知道吗

    C++ 自由存储区是否等价于堆你知道吗

    自由存储是C++中通过new与delete动态分配和释放对象的抽象概念,而堆(heap)是C语言和操作系统的术语,是操作系统维护的一块动态分配内存
    2021-08-08
  • C++ 超详细分析多态的原理与实现

    C++ 超详细分析多态的原理与实现

    这篇文章主要介绍了C++多态的原理与实现,多态是一种面向对象的设计思路,本身和C++不是强绑定的,其他语言当中一样有多态,只不过实现的方式可能有所不同。下面来一起了解更多详细内容吧
    2022-03-03
  • C语言:自定义类型详解

    C语言:自定义类型详解

    这篇文章主要介绍了C语言自定义函数详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-09-09
  • Vs Code中C/C++配置launch.json和tasks.json文件详细步骤

    Vs Code中C/C++配置launch.json和tasks.json文件详细步骤

    使用VSCode开发C/C++程序,需要配置tasks.json/launch.json,下面这篇文章主要给大家介绍了关于Vs Code中C/C++配置launch.json和tasks.json文件的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • C语言中的结构体的入门学习教程

    C语言中的结构体的入门学习教程

    这篇文章主要介绍了C语言中的结构体的入门学习教程,以struct语句定义的结构体是C语言编程中的重要基础,需要的朋友可以参考下
    2015-12-12
  • C++类的静态成员初始化详细讲解

    C++类的静态成员初始化详细讲解

    通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
    2013-09-09
  • C++中4种强制类型转换的区别总结

    C++中4种强制类型转换的区别总结

    C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。下面这篇文章主要给大家介绍了C++中4种强制类型转换的区别,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • 详解C++编程中运算符的使用

    详解C++编程中运算符的使用

    这篇文章主要介绍了详解C++编程中运算符的使用,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C语言链接属性的实践应用

    C语言链接属性的实践应用

    C语言中链接属性决定如何处理在不同文件中出现的标示符,下面这篇文章主要给大家介绍了关于C语言链接属性的实践应用,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-03-03
  • c++将数组名作为函数参数对数组元素进行相应的运算

    c++将数组名作为函数参数对数组元素进行相应的运算

    这篇文章主要介绍了c++将数组名作为函数参数对数组元素进行相应的运算,需要的朋友可以参考下
    2014-05-05

最新评论