C语言小游戏之扫雷完整版

C语言小游戏之扫雷完整版C语言小游戏之扫雷一.游戏介绍二.游戏步骤及实现的功能1.初始化雷盘2.打印雷盘3.随机布置雷4.玩家排雷5.防止玩家第一次被炸死6.统计所选位置周围八个位置中雷的个数7.拓展已选位置周围的区域8.标记雷及取消标记一.游戏介绍看到这张图片,相信很多小伙伴都非常熟悉,很多小伙伴都玩过扫雷这个小游戏,扫雷是一款益智类游戏,在放松娱乐的同时可以锻炼各位小伙伴的智商。游戏规则:如上图,玩家需要在不被炸死的前提下找出图中雷的位置,若能找出所有雷,则游戏胜利,若不幸踩到雷则被炸死。注:先介绍,后文会有完整代码

大家好,又见面了,我是你们的朋友全栈君。

一.游戏介绍

在这里插入图片描述

看到这张图片,相信很多小伙伴都非常熟悉,很多小伙伴都玩过扫雷这个小游戏,扫雷是一款益智类游戏,在放松娱乐的同时可以锻炼各位小伙伴的智商。

游戏规则:如上图,玩家需要在不被炸死的前提下找出图中雷的位置,若能找出所有雷,则游戏胜利,若不幸踩到雷则被炸死。

注:先介绍程序实现的主要功能,后文会有完整代码

二.游戏步骤及实现的功能

(一) 游戏步骤

  1. 程序开始执行时玩家需要选择是否开始游戏,输入1则游戏开始,输入0则退出游戏
    在这里插入图片描述
  2. show地图出现后玩家开始选择进行选择,输入1则开始选择区域,输入2则可以标记自己认为是雷的区域,输入3则可以取消原先被标记的区域
    在这里插入图片描述
  3. 当所有非雷区域全部被排出来后则游戏胜利
//遍历show地图,以便判断最后的胜利
int Travel(char show[ROWS][COLS], int row, int col)
{ 
   
	int i = 0;
	int j = 0;
	int win = 0;
	for (i = 1; i <= row; i++)
	{ 
   
		for (j = 1; j <= col; j++)
		{ 
   
			if (show[i][j] == '*' || show[i][j] == '!')
			{ 
   
				win++;
			}
		}
	}
	return win;
}

以下为效果图:
在这里插入图片描述
(二)实现的功能

  1. 初始化雷盘
  2. 打印雷盘
  3. 随机布置雷
  4. 玩家开始排雷
  5. 防止玩家第一次被雷炸死.
  6. 统计所选位置周围八个位置中雷的个数
  7. 递归拓展已选位置周围的区域
  8. 标记雷及取消标记

1.初始化雷盘

初始化雷盘时需要构造两个二维数组,一个数组(mine数组)里面是存放雷的,用于实现各种功能,另一个数组(show数组)是给玩家操作时看的,看不到雷的具体位置。
由于需要统计每个位置周围八个区域中雷的个数,在统计最边缘的位置时为了利于功能的实现,在初始化雷盘时构建的二维数组mine数组的行和列比show数组多两行两列

//初始化雷盘
//主函数中函数的调用
//Initboard(mine, ROWS, COLS,'0');
//Initboard(show, ROWS, COLS, '*');
void Initboard(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;
		}
	}
}

初始化雷盘时,mine数组全部初始化为字符‘0’,show数组全部初始化为字符‘*’

2.打印雷盘

玩家需要通过打印出的show数组雷盘进行游戏,打印雷盘时将行号和列号全部打印出来有利于玩家进行操作

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{ 
   
	int i = 0, j = 0;
	//打印列号
	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 ", board[i][j]);
		}
		printf("\n");
	}
}

雷盘打印如下:
在这里插入图片描述

3.随机布置雷

在show数组中,用字符‘0’表示无雷区域,用字符‘1’表示有雷区域,由于第一个步骤中已经将show数组全部初始化为字符‘0’了,故只需使用srand和rand函数生成随机数,使得雷的分布为随机位置。

//随机布置雷
void SetMine(char board[ROWS][COLS], int row, int col)
{ 
   
	int x = 0, y = 0;
	int count = EASY_COUNT;
	while (count)
	{ 
   
		x = rand() % row+1;
		y = rand() % col+1;
		if (board[x][y] != '1')
		{ 
   
			board[x][y] = '1';
			count--;
		}
	}
}

4.玩家排雷

玩家根据show数组展示出的地图开始排雷,选择自己认为不是雷的区域

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{ 
   
	int ch = 0;
	int flag_count = 0;
	int win = 0;
	int fch = 1;//用来标记玩家是否为第一次排雷
	while (1)
	{ 
   
		menu1();
		scanf("%d", &ch);
		if (ch == 1)
		{ 
   
			int x = 0, y = 0;
			printf("请开始排雷:>");
			scanf("%d%d", &x, &y);
			//判断坐标合法
			if (x <= row && x > 0 && y > 0 && y <= col)
			{ 
   
				//判断玩家是否是第一次排雷
				if (fch == 1 && mine[x][y] == '1')
				{ 
   
				    //是第一次排雷
					ChangePlace(mine, row, col, x, y);
					fch++;
				}
				else 
				{ 
   
				    //判断是否踩雷
					if (mine[x][y] == '1')
					{ 
   
						printf("游戏结束\n");
						printf("恭喜你,踩到雷了\n");
						DisplayBoard(mine, row, col);
						break;
					}
					else
					{ 
   
						broad(mine, show, x, y);
						DisplayBoard(show, row, col);
					}
					fch++;
				}	
			}
			else
			{ 
   
				printf("输入坐标不合法,请重新输入\n");
			}
		}
		else if (ch == 2)
		{ 
   
			printf("请开始标记雷:>\n");
			//标记雷的函数
			//原先的博客不能改变实参flag_count,此处已改正
			flag_count = Flagmine(show, row, col, flag_count);
			DisplayBoard(show, row, col);
		}
		else if (ch == 3)
		{ 
   
			printf("请选择要取消标记的位置:>\n");
			//取消标记的函数
			flag_count = Cancelflag(show, row, col, flag_count);
			DisplayBoard(show, row, col);
		}
		//遍历show地图(改进)
		win=Travel(show, row, col);
		if (win == EASY_COUNT)
			break;
	}
	if (win == EASY_COUNT)
	{ 
   
		printf("恭喜你,游戏胜利\n");
	}
}

5.防止玩家第一次被炸死

如果玩家第一次就踩雷,则提示玩家重新选择,并将该位置的雷重新随机布置。

//防止玩家第一次排雷被炸死
void ChangePlace(char mine[ROWS][COLS], int row, int col, int x, int y)
{ 
   
		x = rand() % row;
		y = rand() % col;
		mine[x][y] = '1';
		printf("第一次就踩雷了,重新选择\n");
}

在这里插入图片描述

6.统计所选位置周围八个位置中雷的个数

统计已选位置周围八个位置中含有雷的个数,并在该位置上数字的形式打印出来。

//计算坐标周围雷的个数
int get_mine(char mine[ROWS][COLS], int x, int y)
{ 
   
	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';
}

此处由于数组mine中存放的是字符’0’,而不是数字0,故当统计完八个位置后需要减去字符’0’之后返回为数字。

7.递归拓展已选位置周围的区域

递归的方式拓展式排雷。

//拓展周围不是雷的区域
void broad(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{ 
   
	//判断坐标是否越界
	if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1)
		return;
	//判断是否已经被排除
	if (show[x][y] != '*')
	{ 
   
		return;
	}
	int count = get_mine(mine, x, y);
	if (count > 0)
	{ 
   
		show[x][y] = count + '0';
		return;
	}
	//递归拓展地图
	else if (count == 0)
	{ 
   
		show[x][y] = '0';
		broad(mine, show, x - 1, y);
		broad(mine, show, x - 1, y - 1);
		broad(mine, show, x, y - 1);
		broad(mine, show, x + 1, y - 1);
		broad(mine, show, x + 1, y);
		broad(mine, show, x + 1, y + 1);
		broad(mine, show, x, y + 1);
		broad(mine, show, x - 1, y + 1);
	}
}

如果只能一个一个雷的排,将会使得此游戏无法进行,故当选择一个位置a后对a周围八个区域进行排除,若其中一个位置b周围八个位置仍没有雷,就继续对b周围的八个位置进行排雷,以此递归的方式不断排除。
效果如下:
在这里插入图片描述

8.标记雷及取消标记

玩家可以通过输入坐标对自己觉得是雷的位置进行标记,标记后为‘!’,如果觉得不是也可以取消标记,取消标记后恢复为‘*’

//标记雷
int Flagmine(char show[ROWS][COLS], int row, int col,int flag_count)
{ 
   
	int x = 0, y = 0;
	//判断标记数与雷数是否相等
	if (flag_count == EASY_COUNT)
	{ 
   
		printf("标记的雷数和实际存在的雷数相等,无法再标记\n");
		return;
	}
	printf("请输入你要标记位置的坐标:>\n");
	scanf("%d%d", &x, &y);
	//判断坐标是否合法
	if (x > 0 && x <= row && y > 0 && y <= col)
	{ 
   
		//判断该坐标是否仍未被排除
		if (show[x][y]=='*')
		{ 
   
			show[x][y] = '!';
			flag_count++;
		}
		else 
		{ 
   
			printf("该位置不可能是雷,请重新输入\n");
		}
	}
	else
	{ 
   
		printf("该坐标不合法,请重新输入:>\n");
	}
	return flag_count;
}

//取消标记
int Cancelflag(char show[ROWS][COLS], int row, int col, int flag_count)
{ 
   
	int x = 0;
	int y = 0;
	scanf("%d%d", &x, &y);
	//判断坐标是否合法
	if (x > 0 && x <= row && y > 0 && y <= col)
	{ 
   
		//判断该位置是否被标记过
		if (show[x][y] == '!')
		{ 
   
			show[x][y] = '*';
			flag_count--;
		}
		else
			printf("该位置未被标记过,无需取消标记\n");
	}
	else
	{ 
   
		printf("该坐标不合法,请重新输入:>\n");
	}
	return flag_count;
}

图中‘!’即为标记区域
在这里插入图片描述
综上,此程序基本实现了扫雷小游戏的功能,有一定的娱乐性,各位小伙伴感兴趣的话可以玩一把。

源代码链接:扫雷完整版源代码

感兴趣的小伙伴也可以直接点击此处开始玩游戏,体验一把扫雷.exe,赶紧开始你的扫雷之旅吧。

各位大佬有建议可以多多交流,欢迎评论区讨论。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/144416.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SaaS管理软件_软件saas

    SaaS管理软件_软件saas山寨SaaS今天又有一个人问我SaaS了,而且显然看了不少资料,也总结与思索了许多。但他与我交流后,我觉得有些话我也要总结总结,我对SaaS的一些观点和想法也清晰了不少,所以记了下来。大家都把SaaS定位在中小企业的身上。这个观点我也认同。因为我遇到的客户恰恰层次比较清晰:1进货卖货当渠道的经销商。本身自己不生产不设计,只是他从厂家进货,然后自己卖了,中间打个价差而已。他们主要的业务就…

    2022年9月23日
    3
  • 一步一步写算法(之排序二叉树)[通俗易懂]

    一步一步写算法(之排序二叉树)[通俗易懂]【声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing@163.com】   前面我们讲过双向链表的数据结构。每一个循环节点有两个指针,一个指向前面一个节点,一个指向后继节点,这样所有的节点像一颗颗珍珠一样被一根线穿在了一起。然而今天

    2022年7月25日
    12
  • handlersocket mysql,MySQL插件HandlerSocket

    handlersocket mysql,MySQL插件HandlerSocketHandlerSocket是MySQL的一个插件,用来实现NoSQL功能,用于跳过MySQL的SQL层面,直接访问内部的InnoDB存储引擎。wgethttp://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-client-5.5.11-1.rhel4.i386.rpmwgethttp://dev.mysql.com/get/Downloads/…

    2022年8月24日
    7
  • idea2021.3.2 激活码 激活licens sever(JetBrains全家桶)

    (idea2021.3.2 激活码 激活licens sever)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月27日
    1.1K
  • SQLite的使用——图片存储

    SQLite的使用——图片存储在上篇有说到SQLite的文本存储,文本的增删改查,在本篇中主要说SQLite对单张图片的存储。简单介绍:SQLiteOpenHelper是一个抽象类。SQLiteOpenHelper中有两个抽象方法,分别是onCreate()和onUpgrade()。SQLiteOpenHelper中还有两个非常重要的实例方法,getReadableDatabase()和getWritableD…

    2022年7月12日
    30
  • maven 项目打jar包 并包含所有依赖「建议收藏」

    maven 项目打jar包 并包含所有依赖「建议收藏」背景:基于最近项目部署,需要打jar包,然后涉及接口调用,反复测试,出现了各种问题,最后找到合理方案,特做以下总结:一、延伸知识:Springboot打jar包命令1.把之前打过的包通通干掉mvnpackageclean-Dmaven.test.skip=true2.重新打包mvnpackage-Dmaven.test.skip=true3.Springboot的打包插件<build><plugins>&

    2022年6月19日
    83

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号