IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> C语言简单实现扫雷 -> 正文阅读

[数据结构与算法]C语言简单实现扫雷

首先还是先来看一下效果

棋盘中的格子用“*”表示,字符1表示地雷,玩家输入坐标,如果是地雷,提示玩家失败并显示地雷在格子的分布,如果不是地雷,此格显示数字,数字表示周围的地雷的个数

同井字棋游戏一样,扫雷依旧是分三个文件game.h声明函数,game.c实现函数功能,test.c测试

目录

1.创建开始菜单

2.打印棋盘

2.1建立棋盘

2.2棋盘初始化

2.3放地雷

2.4打印棋盘

?3.判断输赢


1.创建开始菜单

逻辑和上一篇的井字棋相同便不再过多阐述,代码如下:

//test.c代码
void menu()
{
	printf("++++++++++++++++++\n");
	printf("+     1.play     +\n");
	printf("+     0.exit     +\n");
	printf("++++++++++++++++++\n");
	printf("请输入:\n");
}
void test()

{
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:printf("START\n"); game(); break;
		case 0:printf("END\n"); break;
		default:printf("输入错误\n"); break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

?我们的重点依旧是game函数的实现

2.打印棋盘

2.1建立棋盘

棋盘依旧是用二维数组来建立,但在初始化棋盘之前我们需要思考要建立多大的棋盘

游戏中的棋盘大小为10*10的大小,那么char board[10][10]?

但这个大小在后续函数功能实现的时候会很麻烦,如图:

?如果边界处的坐标元素不是地雷,那么它就要显示周围的地雷的个数,函数会访问周围8个坐标元素,但显然边界周围的元素不足8个,这就会造成越界访问,那么函数就要添加判断条件坐标是否处于边界,处于边界后又是不是处于四个角落中,这样工作量又增加了

索性在建立棋盘的时候在实际棋盘大小周围再加一圈大小,即12*12。在使用时只使用中间的棋盘,这样写函数时也就不需要写过多的判断条件了

在建立棋盘的时候创建两个数组mine和show,功能如下:

?代码:

//game.h文件代码
#include<stdio.h>
#define ROW 10
#define COL 10
#define ROWS ROW+2
#define COLS COL+2

game函数代码
void game()
{
    char mine[ROWS][ROWS] = { 0 };
	char show[ROWS][COLS] = { 0 };
}

2.2棋盘初始化

创建函数init,棋盘mine初始化成字符“0”,show初始化成“*”,那函数返回值类型应该为char,参数有数组名、行数、列数以及想要设置的字符,实现逻辑依旧是嵌套的for循环

//game.h文件代码
void init(char board[ROWS][COLS], int rows, int cols, char set);


//game.c文件代码
void init(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0, j = 0;
	for ( i = 0; i < rows; ++i)
	{
		for ( j = 0; j < cols; ++j)
		{
			board[i][j] = set;
		}
	}
}

//test.c代码
void game()
{
    char mine[ROWS][ROWS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	init(mine, ROWS,COLS,'0');
	init(show, ROWS,COLS,'*');
}

2.3放地雷

创建函数set_mine,需要确定放置地雷的个数,且地雷都需要放置mine中心的10*10大小内,地雷的位置需随机放置

//game.h
void set_mine(char mine[ROWS][COLS], int row, int col,int number);//注意这里是row和col,和定义的ROW和COL对应,二者的值为10

因为地雷位置需随机放置,那么就又要使用rand(),在使用之前依旧是要设置srand()

//game.c
void set_mine(char mine[ROWS][COLS], int row, int col, int number)
{
	
	int i = number;
	while (i)
	{
		int x = rand() % row + 1;//因为是12*12大小使用中间的10*10大小作为棋盘
		int y = rand() % col + 1;//所以值需要从1开始,从0开始地雷就放置在棋盘外了
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			i--;
		}
	}
}
//test函数中do...while循环外添加  srand((unsigned int)time(NULL));
//在game.h中引用头文件<stdlib.g>和<time.h>

2.4打印棋盘

需要打印的是数组show中间的10*10大小的元素,使用时注意参数

//game.h
void set_mine(char mine[ROWS][COLS], int row, int col,int number);

//game.c
void display(char board[ROWS][COLS], int row, int col)
{
	for (int i = 1; i <=row; ++i)
	{
		for (int j = 1; j <=col; ++j)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

?3.判断输赢

创建函数find_mine,玩家输入坐标,如果该坐标藏有地雷,提示玩家失败,显示地雷分布后结束游戏,否则显示该坐标周围的地雷的个数,当棋盘除地雷之外的所有位置都被玩家找出来后提示玩家获胜

建立棋盘时创建了两个数组,所以find_mine参数也需要两个数组

//game.h
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

那么在坐标元素不是地雷时如何显示周围地雷个数?

我们用“1”来表示地雷,“0”表示没有,那么周围的数字加起来就正好是地雷的个数,但“1”和“0”都是字符型数据,所以需要在后面-‘0’使其变成int型数据,之后显示时+'0'改回字符

//game.c
int mine_count(char mine[ROWS][COLS], 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 find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0, y = 0;
	printf("输入坐标\n");
	scanf("%d%d", &x, &y);
	int count = 0;
	while (count < row * col - NUMBER)
	{
		if (mine[x][y] == '1')
		{
			printf("you lose\n");
			display(mine, ROW, COL);
			break;
		}
		else
		{
			int n = mine_count(mine, x, y);
			show[x][y] = n + '0';//函数返回类型为int,+'0'改为字符型
			count++;
			display(show, ROW, COL);
		}
	}
	if (count == row * col - NUMBER)
	{
		printf("you win\n");
		display(mine, ROW, COL);
	}
		
}

到这扫雷的代码基本上完成了,感谢观看,完

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-15 16:07:29  更:2021-11-15 16:08:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:29:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码