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

目录
  • 前言
  • 1、扫雷是什么?
  • 2、程序框架
    • 2.1 主函数
    • 2.2 函数menu
    • 2.3 函数game
      • 2.3.1 函数init_board
      • 2.3.2 函数show_board
      • 2.3.3 函数set_mine
      • 2.3.4 函数find_mine
      • 2.3.5 函数get_mine_count
  • 3、头文件.h
  • 4、游戏试玩
  • 总结

前言

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

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语言 三子棋内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言数组实现三子棋应用实例

    本文实例为大家分享了C语言数组实现三子棋应用的具体代码,供大家参考,具体内容如下 三子棋:(拆分部分如下) test.c 测试游戏逻辑 game.h关于游戏相关的函数声明,符号声明 头文件的包含 game.c游戏相关函数的实现 游戏进行的过程:(4种) 1.玩家获胜--*(游戏结束) 2.电脑获胜--#(游戏结束) 3.平局--Q(游戏结束) 4.游戏继续--C IsWin函数 用来判断游戏的状态 game.c #include"game.h" #include<stdio.h&

  • C语言数组超详细讲解中篇三子棋

    目录 前言 1.三子棋是什么? 1.1 百度百科 1.2 游戏编程准备工作 2. 程序实现 2.1 搭建程序框架 2.2 模块化编程 2.2.1 源文件test.c 2.2.2 源文件play.c 2.2.3 头文件play.h 2.3 程序实现—拓展play函数 2.3.1 棋盘初始化与打印函数 2.3.2 玩家下棋函数 PlayMover 2.3.3 电脑下棋函数 ComputerMove 2.2.4 判断赢家函数 WhoIsWin 总结 前言 本文主要是对前面所学内容进行复习和练习,学习内

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

    目录 前言 1.扫雷是什么? 2.程序框架 2.1 主函数 2.2 函数menu 2.3 函数game 2.3.1 函数init_board 2.3.2 函数show_board 2.3.3 函数set_mine 2.3.4 函数find_mine 2.3.5 函数get_mine_count 3.头文件.h 4.游戏试玩 总结 前言 本文接着复习前面所学知识,以扫雷游戏为例. 1.扫雷是什么? 百度百科:<扫雷>是一款大众类的益智小游戏,于1992年发行.游戏目标是在最短的时间内根据点击格子

  • C语言操作符超详细讲解下篇

    目录 前言 赋值操作符 单目操作符 单目操作符介绍 sizeof 和 数组 关系操作符 逻辑操作符 条件操作符 逗号表达式 下标引用与函数调用和结构成员 [ ] 下标引用操作符 ( ) 函数调用操作符 访问一个结构的成员 表达式求值 隐式类型转换-整形提升 算术转换 操作符的属性 总结 前言 本文接着学习操作符的内容. 赋值操作符 赋值操作符就是能够重新赋值 int weight = 120;//体重 weight = 89;//不满意就赋值 double salary = 10000.0; s

  • C语言指针超详细讲解下篇

    目录 前言 指针运算 指针±整数 4.1 指针±整数 4.2 指针-指针 4.3 指针的关系运算 5.指针和数组 6.二级指针 7.指针数组 7.1 举例 1 7.2 举例 2 总结 前言 本文接着上一篇内容,继续学习指针相关知识点. 指针运算 指针±整数 指针-指针 指针的关系运算 4.1 指针±整数 #define VALUE 5 int main() { float values[VALUE]; float *vp; //指针+-指针,关系运算 for (vp = &values[0];

  • C语言函数超详细讲解下篇

    目录 前言 函数的声明和定义 函数声明 函数定义 举例 简单的求和函数 把加法单独改写成函数 添加函数声明 带头文件和函数声明 静态库(.lib)的生成 静态库文件的使用方法 函数递归 什么是递归? 递归的两个必要条件 练习1 一般方法 递归的方法 练习2 一般方法 递归方法 练习3 一般方法 递归方法 练习4 一般方法 递归方法 递归与迭代 递归隐藏的问题 如何改进 选递归还是迭代 总结 前言 紧接上文,继续学习函数相关内容. 函数的声明和定义 函数声明 告诉编译器有一个函数叫什么,参数是什么

  • C语言数组超详细讲解上

    目录 前言 1.一维数组的创建和初始化 1.1 一维数组的创建 1.2 一维数组的初始化 1.3 一维数组的使用 1.4 一维数组在内存中的存储 2.二维数组的创建和初始化 2.1 二维数组的创建 2.2 二维数组的初始化 2.3 二维数组的使用 2.4 二维数组在内存中的存储 3.数组越界 4.数组作为函数参数 4.1 冒泡排序函数的错误设计 4.2 数组名是什么? 4.3 对数组名的用法进行总结 4.4 冒泡排序函数的正确设计 总结 前言 本文主要介绍数组相关的内容,主要内容包括: 一维数组

  • C语言数据的存储超详细讲解下篇浮点型在内存中的存取

    目录 前言 浮点型在内存中的存储 浮点数存储的例子 浮点数存储规则 IEEE 754规定 IEEE 754对有效数字M的特别规定 IEEE 754对指数E的特别规定 存入内存是E的规定 从内存取出时E的规定 举例 1 举例 2 举例 3 判断两个浮点数是否相等? 总结 前言 本文接着学习数据的存储相关的内容,主要学习浮点型数在内存中的存储与取出. 浮点型在内存中的存储 常见的浮点数:3.14159.1E10 浮点数家族包括: float.double.long double 类型 浮点数表示的范

  • C语言指针超详细讲解上篇

    目录 前言 1.指针是什么 1.1 指针变量 1.2 指针是内存中一个最小单元的编号 2.指针和指针类型 2.1 指针±类型 2.2 指针的解引用 2.2.1 int* 类型的解引用 2.2.2 char* 类型的解引用 3.野指针 3.1 野指针成因 3.1.1 指针未初始化 3.1.2 指针越界访问 3.1.3 指针指向的空间释放 3.2 如何规避野指针 总结 前言 本文开始指针相关内容的学习,主要内容包括: 指针是什么 指针和指针类型 野指针 指针运算 指针和数组 二级指针 指针数组 1.

  • C语言函数超详细讲解上篇

    目录 前言 1.函数是什么? 2.C语言中函数的分类 2.1 库函数 2.1.1 如何学会使用库函数 2.1.2 自定义函数 3.函数的参数 3.1 实际参数(实参) 3.2 形式参数(形参) 4.函数的调用 4.1 传值调用 4.2 传址调用 4.3 练习 4.3.1 判断一个数是不是素数 4.3.2 判断一年是不是闰年 4.3.3 二分查找 4.3.4 数值自增增加1 5.函数的嵌套调用和链式访问 5.1 嵌套调用 5.2 链式访问 总结 前言 本文主要学习函数的相关内容. 1.函数是什么?

  • C语言数据结构超详细讲解单向链表

    目录 1.链表概况 1.1 链表的概念及结构 1.2 链表的分类 2. 单向链表的实现 2.1 SList.h(头文件的汇总,函数的声明) 2.2 SList.c(函数的具体实现逻辑) 2.2.1 打印链表 2.2.2 搞出一个新节点(为其他函数服务) 2.2.3 链表尾插 2.2.4 链表头插 2.2.5 链表尾删 2.2.6 链表头删 2.2.7 查找节点 2.2.8 在pos位置之前插入 2.2.9 在pos位置之后插入 2.2.10 删除pos位置 2.2.11 删除pos之后位置 2.

随机推荐