C语言两百行代码实现简易扫雷

这篇具有很好参考价值的文章主要介绍了C语言两百行代码实现简易扫雷。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C语言两百行代码实现简易扫雷


前言

扫雷应该是我们接触到的第一个电脑游戏,用c语言实现扫雷对初学者来说是一个不错的锻炼
编写扫雷只需要用到数组、函数和生成随机数的知识,所以比较适合成为编程学习者编写的第一个小游戏。

如果不熟悉生成随机数的知识,可以去我的上一篇文章看看《C生成随机数》


一.代码实现

第一部分是源码复制就可以使用,每一个自定义函数在第二部分设计思路中都有详细解释,结合代码实现设计思路理解会有一个更好的效果

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS 11
#define COLS 11
#define MINE_NUMBER 10



void reset(char arr[ROWS][COLS], char ch)//将数组的每一个元素赋值为给定值
{
	for (int i = 0; i < ROWS; i++)
	{
		for (int j = 0; j < COLS; j++)
		{
			arr[i][j] = ch;
		}
	}
}

void setmine(char arr[ROWS][COLS])//利用生成随机数的知识使用随机的行号列标在mine数组放置地雷直到将宏定义的地雷数放置完
{
	int mine_number = MINE_NUMBER;
	int row = rand() % 9 + 1;//生成一到九的行号
	int col = rand() % 9 + 1;//生成一到九的列标

	while (mine_number > 0)
	{
		if (arr[row][col] == '0')//用来不是地雷的地方才能放置地雷
		{
			arr[row][col] = '1';//安装地雷
			mine_number--;
		}
		else
		{
			row = rand() % 9 + 1;
			col = rand() % 9 + 1;
		}

	}
}

void display(char arr[ROWS][COLS])
{
	for (int i = 0; i <= COL; i++)
	{
		printf(" %d  ", i);//打印行号
	}
	printf("\n\n");
	for (int i = 1; i <= ROW; i++)//第一个和第二个for进去分别打印一行数组和一条分割线
	{                             //数组行为:(空格)元素(空格)|(空格)元素(空格)|(空格)元素(空格)  
								  //分割线为: -      -      -   |   -      -     -   |   -     -      -
		printf(" %d  ", i);//打印列标

		for (int j = 1; j <= COL; j++)
		{

			printf(" %c ", arr[i][j]);
			if (j < COL)
			{
				printf("|");//为了美观,不打印最后一个'|'
			}

		}
		printf("\n");
		printf("    ");


		for (int k = 1; k <= COL; k++)
		{
			printf("---");
			if (k < COL)
			{
				printf("|");//为了美观,不打印最后一个'|'
			}

		}
		printf("\n");
	}
}







char nearmine(char mine[ROWS][COLS], int row, int col)//返回所选坐标字符型的地雷数量
{
	return (mine[row - 1][col - 1] + mine[row - 1][col] + mine[row - 1][col + 1] + mine[row][col - 1] + mine[row][col + 1]
		+ mine[row + 1][col - 1] + mine[row + 1][col] + mine[row + 1][col + 1] - 7 * '0');
}

int player_move(char mine[ROWS][COLS], char show[ROWS][COLS])//首先输入合法坐标然后玩家移动,每一步结果只有两个:踩到雷还有没踩到

{
	int row = 0, col = 0;
	int flag = 1;
	do//输入合法坐标,在行号列标范围内,并且没有被走过
	{
		printf("\n---------------------------------------输入坐标,中间用空格隔开:>");
		scanf("%d %d", &row, &col);
		if (row >= 1 && row <= 9 && col >= 1 && col <= 9 && show[row][col] == '*')
			flag = 0;
		else
			printf("输入错误\n");
	} while (flag);
	if (mine[row][col] == '1')//踩到雷,返回-1
		return -1;
	else
	{
		show[row][col] = nearmine(mine, row, col);//nearmine将会返回字符型的地雷数
												  //将用来展示的show数组的相应坐标的元素赋值为周围的地雷数
		return 1;
	}

}

void meau()//菜单
{
	printf("------------------\n");
	printf("|     1.play     |\n");
	printf("|----------------|\n");
	printf("|     0.exit     |\n");
	printf("------------------\n");

}


void game()
{

	char mine[ROWS][COLS];//mine:地雷
	char show[ROWS][COLS];
	reset(mine, '0');//初始化mine为全零
	reset(show, '*');//初始化reset为全*
	setmine(mine);//安置地雷
	//display(mine);
	display(show);//展现
	int count = 0;

	do
	{
		int move = player_move(mine, show);
		if (move == -1)//踩到雷游戏结束
		{
			printf("\n---------------------------------------踩到地雷,游戏结束>\n");
			display(mine);
			break;

		}
		else if (move == 1)//没有踩到雷则步数count加一
		{
			count++;
			if (count == ROW * COL - MINE_NUMBER)//判断是否走完了步数,走完了游戏就成功了
			{
				printf("\n---------------------------------------排除地雷,游戏结束>\n");
				display(mine);
				break;

			}

		}

		display(show);

	} while (1);



}

int main()
{
	int input = 0;
	srand((unsigned)time(NULL));
	do
	{
		meau();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game(); break;
		case 0:
			break;
		default:
			printf("输入错误,请重新输入\n"); break;

		}

	} while (input);
	return 0;



}

二.设计思路

main()函数搭建框架

1.main()函数搭建框架:像所有的电脑游戏一样,我们需要一个菜单,通过菜单选择进入游戏和退出游戏,当一盘游戏结束时可以再次选择进入或者退出,菜单用printf()打印就可以解决,循环的进入游戏用do while()循环就可以解决

void meau()//菜单
{
	printf("------------------\n");
	printf("|     1.play     |\n");
	printf("|----------------|\n");
	printf("|     0.exit     |\n");
	printf("------------------\n");

}


void game()
{
    char mine[ROWS][COLS] = {0};//mine:地雷
	char show[ROWS][COLS] = {0};//show: 展示。0
	
  ········
}

int main()
{
	int input = 0;
	srand((unsigned)time(NULL));
	do
	{
		meau();
		scanf("%d", &input);
		switch (input)
		{
		case 1 :
			game(); break;
		case 0 :
			break;
		default:
			printf("输入错误,请重新输入\n"); break;

		}

	} while (input);
	return 0;

	
	
}

当我们输入1,进入case 1时,将运行game()函数,game函数中的代码为具体游戏的实现
我们需要一个容器来存放游戏数据,二维数组是最好的选择,我们创建一个字符数组mine存放数据,一般扫雷游戏都是9X9的棋盘界面,所以我们可以设置行数和列数都为9,但在实际代码运行中9行9列还是不够的,会出现数组下标越界,所以最好在原来的上下左右各放一行将原来的9x9数组包起,所以我们实际需要一个11x11的数组,由于我们经常会使用,不妨对它宏定义一下

#define ROW 9
#define COL 9

#define ROWS 11
#define COLS 11

考虑到扫雷游戏中每选择一步如果没有踩雷,都会修改字符数组mine[ROW][COL]的相应元素来显示周围的地雷个数,这种修改会对游戏造成影响,所以不妨再定义一个数组show[ROW][COL],专门显示地雷数量,将判断和显示分离开

char mine[ROW][COL]:存放放置地雷和非地雷数据,我们用字符‘0’表示安全区;字符‘1’表示地雷,通过赋值填满数组
char show[ROW][COL]:当初用来展示的数组,初始化时全部赋值为字符‘*’,每选择一步,就在相应元素处返回周围地雷个数(mine数组相应元素周围‘1’的个数)

reset ( )函数

reset() :我们完成一局扫雷,还想下该怎么办?这时候我们构造一个函数reset(),将mine和show数组的每一个元素重置为‘0’和‘*’

该函数实际功能就是把接收到的数组中全部元素赋值为给定符号

reset()函数,遍历数组,赋值为给定字符

void reset(char arr[ROWS][COLS], char ch)//将数组的每一个元素赋值为给定值
{
	for (int i = 0; i < ROWS; i++)
	{
		for (int j = 0; j < COLS; j++)
		{
			arr[i][j] = ch;
		}
	}
}

dis_play( )函数

dis_play( ):我们扫雷肯定需要“雷区”来显示我们的数据,我们通过构造一个函数dis_play()将数组打印出来来实现这一功能

dis_play()功能就是借助’|'和‘_’等特殊字符,将数组以类棋盘形式打印出来

void display(char arr[ROWS][COLS])//借助于‘|’和‘-’,将数组以游戏界面的显示打印出来
{
	for (int i = 0; i <= COL; i++)
	{
		printf(" %d  ", i);//打印行号
	}
	printf("\n\n");
	for (int i = 1; i <= ROW; i++)//第一个和第二个for进去分别打印一行数组和一条分割线
	{                             //数组行为:(空格)元素(空格)|(空格)元素(空格)|(空格)元素(空格)  
								  //分割线为: -      -      -   |   -      -     -   |   -     -      -
		printf(" %d  ", i);//打印列标

		for (int j = 1; j <= COL; j++)
		{

			printf(" %c ", arr[i][j]);
			if (j < COL)
			{
				printf("|");//为了美观,不打印最后一个'|'
			}

		}
		printf("\n");
		printf("    ");


		for (int k = 1; k <= COL; k++)
		{
			printf("---");
			if (k < COL)
			{
				printf("|");//为了美观,不打印最后一个'|'
			}

		}
		printf("\n");
	}

}



运行代码,打印雷区
C语言两百行代码实现简易扫雷

运行代码,打印show
C语言两百行代码实现简易扫雷

setmine( )函数

setmine( ):经过reset()初始化后的mine数组中是没有地雷的,我们需要利用生成随机数的知识放置地雷,这时我们构建一个函数完成

使用头文件#include<stdlib.h>中的rand()函数可以生成一个0~32767的伪随机数,但使用rand()前先要使用srand()设置伪随机数起点
起点只要写一次,我们将srand((unsigned)time(NULL))定义在主函数,此处是一种固定的写法,time()函数需要引<time.h>头文件
将rand()%9+1即%ROW+1可以生产1~9这九个随机数,可以用来做数组的行号和列标

int main()
{
	int input = 0;
	srand((unsigned)time(NULL));//设置起点的固定写法
	do
	{
		meau();
		scanf("%d", &input);
		switch (input)
		{
		case 1 :
			game(); break;
		case 0 :
			break;
		default:
			printf("输入错误,请重新输入\n"); break;

		}

	} while (input);
	return 0;

	
	
}

void setmine(char arr[ROWS][COLS])//利用生成随机数的知识使用随机的行号列标在mine数组放置地雷直到将宏定义的地雷数放置完
{
	int mine_number = MINE_NUMBER;
	int row = rand() % 9 + 1;//生成一到九的行号
	int col = rand() % 9 + 1;//生成一到九的列标

	while (mine_number > 0)
	{
		if (arr[row][col] == '0')//用来不是地雷的地方才能放置地雷
		{
			arr[row][col] = '1';//安装地雷
			mine_number--;
		}
		else
		{
			row = rand() % 9 + 1;
			col = rand() % 9 + 1;
		}

	}
	

运行代码–setmine()前
C语言两百行代码实现简易扫雷

运行代码–setmine()后
C语言两百行代码实现简易扫雷

player_move( )函数

player_move( ):扫雷用的棋盘打印好了,地雷放置好了下面要实现的就是移动这一个操作了,扫雷的移动只有两个结果:踩到雷还有没踩到雷,游戏扫胜利就是把除了雷之外的地块都走一次。另外,当我们每一次没有踩到雷时,要返回这个地块周围的地雷数>>

player_move()函数函数分为两个功能,第一个功能实现合法输入,输入的行号列标都应该在1~9这个范围中,另外,之前排除过的部分就不能再踩了。第二功能实现判断,踩到了雷就返回-1,没有踩到就返回1,并且应该赋值周围地雷雷数给show数组的相应元素,这个操作我们可以构造nearmine()函数完成,由于是字符型数组,nearmine()函数也要返回字符型的数字

char nearmine(char mine[ROWS][COLS], int row, int col)//返回所选坐标周围8格字符型的地雷数量
{
   //return 周围8格地雷数的ascll码值用下面这种方法就可以完成
	return (mine[row - 1][col - 1] + mine[row - 1][col] + mine[row - 1][col + 1] + mine[row][col - 1] + mine[row][col + 1]
		+ mine[row + 1][col - 1] + mine[row + 1][col] + mine[row + 1][col + 1] - 7 * '0');
}

int player_move(char mine[ROWS][COLS], char show[ROWS][COLS])//首先输入合法坐标然后玩家移动,每一步结果只有两个:踩到雷还有没踩到
                                                             
{
	int row = 0, col = 0;
	int flag = 1;
	do//输入合法坐标,在行号列标范围内,并且没有被走过
	{
		printf("\n---------------------------------------输入坐标,中间用空格隔开:>");
		scanf("%d %d", &row, &col);
		if (row >= 1 && row <= 9 && col >= 1 && col <= 9 && show[row][col] == '*')
			flag = 0;
		else
			printf("输入错误\n");
	} while (flag);
	if (mine[row][col] == '1')//踩到雷,返回-1
		return -1;
	else
	{
		show[row][col] = nearmine(mine, row, col);//nearmine将会返回字符型的地雷数
		                                          //将用来展示的show数组的相应坐标的元素赋值为周围的地雷数
		return 1;
	}



}

game( )

在game()函数我们编写程序去接收player_move( )函数返回的“-1”和“1”,接收到“1”,踩到地雷,游戏结束
接收到“1”,步数count++,并且判断conut是否等于非地雷地块的数量,一旦相等,游戏胜利,并且结束

void game()
{
	
	char mine[ROWS][COLS] ;//mine:地雷
	char show[ROWS][COLS] ;
	reset(mine,'0');//初始化mine为全零
	reset(show,'*');//初始化reset为全*
	setmine(mine);//安置地雷
	//display(mine);
	display(show);//展现
	int count = 0;
	
	do
	{
		int move = player_move(mine, show);
		if (move==-1)//踩到雷游戏结束
		{
			printf("\n---------------------------------------踩到地雷,游戏结束>\n");
			display(mine);
			break;

		}
		else if (move == 1)//没有踩到雷则步数count加一
		{
			count++;
			if (count == ROW * COL - MINE_NUMBER)//判断是否走完了步数,走完了游戏就成功了
			{
				printf("\n---------------------------------------排除地雷,游戏结束>\n");
				display(mine);
				break;

			}

		}
		
		display(show);
		
	} while (1);

	

}

整理不易,如果有帮助的话,那就给个三联吧,谢谢文章来源地址https://www.toymoban.com/news/detail-452010.html

到了这里,关于C语言两百行代码实现简易扫雷的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言实现扫雷完整算法详解~(附完整代码~)

    扫雷是一个常见小游戏,那么如何用C语言实现扫雷呢?学习了二维数组之后,我们可将扫雷的网格区域存储为二维数组,从而使用C语言实现扫雷。 目录 1.算法基本思路 2.算法详解 1.初始化数组与打印数组 2.设置雷 3.排查与标记 4.CountMine函数计算周围雷的个数  5.ExpandMine函数

    2024年02月05日
    浏览(39)
  • 【C语言】代码实现 扫雷 游戏及进阶功能(初学者详解)

    扫雷游戏的起源可以追溯到20世纪60年代,当时这款游戏是由IBM开发出来的。在80年代初,微软公司将其收归旗下,并将其作为Windows操作系统自带的一款游戏。自此以后,扫雷成为了Windows用户最喜欢的休闲游戏之一,也受到了全球范围内的玩家喜爱。 现在,我们使用C语言,来

    2024年01月20日
    浏览(48)
  • C语言300行代码实现扫雷(可展开+可标记+可更改困难级别+内附图形界面版本)

    扫雷是一个经典的游戏,是一个益智类小游戏,在80、90年代曾风靡一时,当然现在也是十分受欢迎; 废话不多说; 让我们来了解一下如何用C语言去实现它吧!!!(❁´◡`❁) 运行环境:VS2019 图形化界面版本 先实现一个初级版本的: 1、我们得有一个9*9的棋盘; 2、我们在棋

    2024年01月25日
    浏览(43)
  • GoLang 百行代码实现小项目《家庭收支软件》

    GoLang 百行代码实现的小项目《家庭收支软件》是一个简单的家庭收支记账软件,可以通过命令行界面记录和显示收支明细。 在代码中,定义了两个结构体类型: record (代表一条收支记录)和 software (代表记账软件): record 结构体包含了记录的名称、金额、累计总额和描述

    2024年02月07日
    浏览(26)
  • C语言200行代码实现简易三子棋

    三子棋应该是是我们最早接触到的棋类游戏,用C语言实现三子棋对初学者来说是一种不错的锻炼 编写三子棋只需要用到数组、函数和生成随机数的知识,所以比较适合成为编程学习者编写的第一个小游戏。 第一部分是源码复制就可以使用,每一个自定义函数在第二部分 设计

    2024年02月04日
    浏览(40)
  • 两百行C++代码实现yolov5车辆计数部署(通俗易懂版)

    本文是文章传统图像处理方法实现车辆计数的后续。这里用OpenCV实现了基于yolov5检测器的单向车辆计数功能,方法是撞线计数。该代码只能演示视频demo效果,一些功能未完善,离实际工程应用还有距离。 实现流程: (1)训练yolov5模型,这里就没有自己训练了,直接使用官方

    2024年02月06日
    浏览(70)
  • Python三百行代码实现一简约个人博客网站(全网最小巧)

    这是全互联网最小巧的博客,没有比这更小的了。虽然小巧,但功能一点儿也不弱,支持文章的分页展示,文章表格,图片和代码语法高亮。文章无限制分类,访问量统计,按时间和按点击量排序,展示最新文章,最热文章,文章留言评论等功能。 如果你也想拥有一个属于自

    2024年02月04日
    浏览(55)
  • C语言小项目 -- 扫雷游戏完整代码(递归展开 + 选择标记)

    大家好,今天我们将一起用C语言实现一个经典小游戏 – 扫雷,Let is go ! 扫雷游戏相信大家都玩过,上图就是一个网页版的扫雷,它的规则是玩家选择一个方格,若此方格没有地雷,那么该方格会显示与它相邻的八个方格中雷的个数,若此方格有地雷,那么游戏失败,当玩

    2024年02月05日
    浏览(55)
  • C语言初阶之扫雷代码详解(含递归展开)

    主要分为下面几个过程: 1、建立棋盘 2、初始化棋盘 3、设置棋盘雷数 4、打印棋盘 5、玩家找雷 6、判定胜负 文件名:game.h 代码如下: 在game头文件中,首先包含会使用到的库头文件,这里的ROW以及COL是雷区的行和列大小,也就是说这是玩家实际能看到的行数及列数,而RO

    2024年02月03日
    浏览(36)
  • go语言实现扫雷

    源码如下 如下显示效果 长按鼠标左键划过格子会有提示,与windows扫雷效果一致。 左键既是单击,点数字时也是双击,右键标雷。 在界面输入,1 + 回车 = 初级,2 + 回车 = 中级,3 + 回车 = 高级 在界面输入, 11 22 33 + 回车 = 高度11,宽度22,总雷数33 。可以自定义数据 如果想在浏览器

    2024年03月13日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包