扫雷---C语言

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

目录

前言:

1.认识扫雷

1.1游戏构思

1.2碎碎念

2.扫雷接口实现

2.1菜单打印

2.2创建标识符常量和初始化数组

2.3打印棋盘

2.4随机埋雷

2.5排查雷

3.源码

3.1头文件和函数原型声明game.h

3.2游戏函数实现game.c 

3.3测试代码文件test.c 


❤博主CSDN:啊苏要学习

  ▶专栏分类:C语言◀

  C语言的学习,是为我们今后学习其它语言打好基础,C生万物!

  开始我们的C语言之旅吧!✈


前言:

  继三子棋小游戏,我们继续来实现一个扫雷游戏。即使学校里有许多作业没完成,也依旧阻挡不了博主总结写博客的态势!

1.认识扫雷

  扫雷游戏简单来说就是在一个棋盘上,玩家选择未知的小格子,这个格子如果是雷,扫雷失败游戏结束,如果不是雷,就在这个格子里显示基于这个小格子一周未显示的格子存在的雷的个数

  随着我们一直排雷,最后把棋盘上所有不是雷的格子选出来,游戏就胜利了

1.1游戏构思

  这个游戏需要用什么去实现呢?我们先在网上看一下扫雷游戏的是长啥样的,好确定实现需要的元素

扫雷---C语言

  (存储和初始化)要有这个9*9的棋盘,我们可以使用一个9行9列的二维数组,然后为这个数组做一个初始化的接口函数。(埋雷)初始化完后,我们自己决定用什么符号表示雷(比如可以使用数字1来表示是雷),然后往棋盘里随机布置雷的存储位置,也就是把数组里的对应元素改成表示雷的符号

  (显示棋盘)还有一个重要的点是:显示棋盘,在选择玩游戏之后,第一事是先把棋盘打印出来给玩家看由于我们现在没有使用界面化的工具(没有像上图那样有那些蓝色方格子),为了让棋盘没有被排查过的格子有些神秘感,最开始我们将棋盘初始化为字符'*'(星)


  这时候读者有没有发现如果仅使用一个二维数组会有些冲突的地方呢我们请看到埋雷那一部分,我们说假设用数字1来表示埋的雷,现在在显示棋盘的时候又说要用*来表示未排查过的格子,那么未被排查过的又是雷格子该怎么表示?使用一些其它的符号吗?那玩家玩上一局发现规律后就完全通关了。那既然这样,我们就使用两个一模一样的二维数组吧,一个用来显示,一个用来表示雷的信息。因为我们使用*字符来初始化显示棋盘,那干脆用字符数组吧,埋雷的棋盘用字符'1'表示雷。

  总结创建两个9行9列的字符数组,一个是用来显示的,一个使用来放雷的信息的显示的我们将它初始化为'*',在经过排查后,'*'变成表示该格子周围一圈8个格子潜藏的雷的个数(字符3和数字3虽然不是同一个东西,但我们能用来表示是3个的意思)埋藏雷的信息的棋盘我们不需要打印出来(相当于是一个后台,玩家通过对界面显示的棋盘进行操作,前台的操作对应后台,形成对接这种感觉~),我们就把埋雷的棋盘叫雷盘吧,雷盘最初我们就假设初始化字符'0',埋雷的时候,把该是雷的位置里的'0'改成'1'就可以了

  (排雷)那么还有一个问题就是,如何联系雷盘与显示棋盘,也就是说,在排雷的时候,我们根据显示的棋盘输入一个未排查的坐标后,应该找到对应的雷盘上的坐标,计算出周围雷的个数后,返回来覆盖掉显示棋盘位置上的'*'

  我们看下面这种情况:

扫雷---C语言

  但是我们的数组只有9行9列,黄色部分超出了数组范围,如果对其进行访问就造成了非法访问内存,程序会挂掉,那该怎么做我们不妨将数组扩大一圈,变成成11行11列(因为横向最顶部,最底部多了一行,相当于加了两行,加了最左列和最右列,相当于加了两列)。雷盘和显示盘在初始化的时候,11行11列都初始化,虽然说显示棋盘只用的部分是9*9,但我们也选择初始化11行11列(因为这样就不会在初始化两个棋盘的时候,传参的行列不一致)在显示显示棋盘的时候依旧是9*9的部分

1.2碎碎念

  首先,如果读者能读到这里,那么先为你叫好,毕竟前面那么多的构思文字都看得下来,说明你是一个很有耐心的读者。哈哈,那么接下来是实现扫雷的接口函数部分啦:

2.扫雷接口实现

2.1菜单打印

  和三子棋一样,博主就直接写出来了:

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

void game()
{
	printf("扫雷游戏\n");
}

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("这是一个扫雷游戏,请选择>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//接着就是实现game函数
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}
	} while (input);
	return 0;
}

2.2创建标识符常量和初始化数组

game.h

扫雷---C语言  ROW和COL是给棋盘真正有用的部分(9*9)设的, 当我们在排查雷或打印棋盘,不需要用(11*11) 

test.c

扫雷---C语言

game.c

扫雷---C语言

2.3打印棋盘

  打印的是显示棋盘9*9的部分:

void Display(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("-----扫雷游戏-----\n");
    //打印一行列数
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
    
	for (i = 1; i <= row; i++)
	{
        //在打印一行显示棋子之前打印该行的行数
		printf("%d ", i);
        //打印棋子
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);//第1行到第9行是棋盘的有效部分
		}							   //第0行和第10行是外面一圈
		printf("\n");
	}
}

扫雷---C语言

  这里需要补充一点的是:我们打印出来的辅助玩家输入的坐标行和数组的元素是不是对应的关系定义两个都是11行11列的数组的,行的下标和列的下标都是从0-10。我们看下面的图:

扫雷---C语言

  打印完棋盘后,现在就是在雷盘上埋雷啦~,得先有雷才能排雷嘛。

2.4随机埋雷

void SetMine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//埋雷是一个循环,用一个未埋的雷数来控制循环
	while (count)
	{
		//随机生成1-9的x,y坐标
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		//判断是否是可以埋雷的位置
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;//成功埋一颗雷,剩余雷数减一
		}
	}
}

扫雷---C语言

  既然雷已经埋完了,现在我们再来把排雷的接口函数实现一下吧。

2.5排查雷

  因为显示用的棋盘和存储雷的信息的棋盘它们是一模一样的,所以它们的坐标是相对应的。

//获取雷的个数
int Get_MineCount(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');
}

void FindMine(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)//win是排掉不是雷的个数等于棋盘减去雷的个数时游戏胜利,不用再继续输入坐标排雷了
	{
		printf("请输入排查坐标:>");
		scanf("%d%d", &x, &y);
        //判断坐标合法性
		if ((x >= 1 && x <= 9) && (y >= 1 && y <= 9))
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,排雷失败,你被炸死了\n");
				Display(mine, row, col);
				break;
			}
			else
			{
				int count = Get_MineCount(mine, x, y);//获取附近雷的个数
				show[x][y] = count + '0';
				Display(show, row, col);
				win++;
			}
		}
		else
		{
			printf("输入坐标不合法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		Display(mine, row, col);
	}
}

  将排查的位置周围一圈都加起来,减去8个字符'0'的ASCII码值,等于字符1的个数字符1的ASCII码值是49,字符0的ASCII码值是48,比如现在排查的位置周围有3颗雷,那么一圈加下来就是8个字符0加上3,我们减去8个字符0,让Get_MineCount返回数字3。那么show数组对应的坐标要赋值成3+'\0'是为什么呢?因为这是字符为元素的数组,加上字符0使其成为相应的数字字符,打印出来也可以表示雷的个数。

  好啦,这样就实现我们的简单版的扫雷游戏啦,还有一些功能我们没有实现的就是,当我们排查一个坐标的时候,展开一大片,这是需要使用递归实现的还有标记的功能,图形化界面等等,我们还是一样,博主学有余力的时候再出一篇博客

扫雷---C语言

  由于没有递归展开一片的功能,博主玩胜利一把需要输入71个坐标,哈哈~

3.源码

3.1头文件和函数原型声明game.h

game.h
#define _CRT_SECURE_NO_WARNINGS 1

#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

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void Display(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

3.2游戏函数实现game.c 

game.c

#include "game.h"

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

void Display(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("-----扫雷游戏-----\n");
	//从零开始可以使其对齐
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);//第1行到第9行是棋盘的有效部分
		}							   //第0行和第10行是外面一圈
		printf("\n");
	}
}

void SetMine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//埋雷是一个循环,用一个未埋雷数来控制循环
	while (count)
	{
		//随机生成1-9的x,y坐标
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		//判断是不是可以埋雷的位置,不能重复埋雷
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;//成功埋一颗雷,剩余雷数减一
		}
	}
}

int Get_MineCount(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');
}

void FindMine(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 <= 9) && (y >= 1 && y <= 9))
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,排雷失败,你被炸死了\n");
				Display(mine, row, col);
				break;
			}
			else
			{
				int count = Get_MineCount(mine, x, y);//获取附近雷的个数
				show[x][y] = count + '0';
				Display(show, row, col);
				win++;
			}
		}
		else
		{
			printf("输入坐标不合法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		Display(mine, row, col);
	}
}

3.3测试代码文件test.c 

test.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

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

void game()
{
	char mine[ROWS][COLS];//雷盘
	char show[ROWS][COLS];//显示盘
	InitBoard(mine, ROWS, COLS, '0');//将11行11列的雷盘都初始化成字符0
	InitBoard(show, ROWS, COLS, '*');
	Display(show, ROW, COL);
	SetMine(mine, ROW, COL);
	FindMine(mine, show, ROW, COL);
}

int main()
{
	int input = 0;
	//使用rand()生成随机数必须要调用一次srand
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("这是一个扫雷游戏,请选择>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//接着就是实现game函数
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}
	} while (input);
	return 0;
}

  讲到这里,结束~ 


结语:希望读者读完有所收获!在学C的路上,祝福我们能越来越C!✔

  读者对本文不理解的地方,或是发现文章在内容上有误等,请在下方评论区留言告诉博主哟~,也可以对博主提出一些文章改进的建议,感激不尽!最后的最后!

  ❤求点赞,求关注,你的点赞是我更新的动力,一起努力进步吧。文章来源地址https://www.toymoban.com/news/detail-448980.html

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

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

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

相关文章

  • 扫雷小游戏【C语言】

    目录 前言 一、基本实现逻辑 二、实现步骤 1. 我们希望在进入游戏时有一个菜单让我们选择 2. 我们希望可以重复的玩(一把玩完了还可以接着玩) 3. 采用多文件形式编程  4.要扫雷先得有棋盘(创建棋盘R*N) 5.初始化棋盘  6.打印棋盘 7.设置雷 8.排查雷 三、全部源码: 上期

    2024年02月11日
    浏览(56)
  • C语言扫雷小游戏

    扫雷的玩法:在一个9×9(初级)、16×16(中级)、16×30(高级)或自定义大小的方块矩阵中随机布置一定量的地雷(初级为10个,中级为40个,高级为99个),再由玩家逐个翻开方块,翻开的地方将显示周围八个雷的个数。以找出所有地雷为最终游戏目标。如果玩家翻开的方块

    2024年02月05日
    浏览(53)
  • C语言:扫雷小游戏

    文接上一篇博文C语言:三子棋小游戏。本篇博文是使用C语言来实现扫雷小游戏的。这里不对扫雷的规则进行赘述。玩家通过键盘输入坐标来探雷。博主在实现扫雷之前从未看过扫雷实现的相关视频,所以这里实现的扫雷完全是博主的原生思路,具有逻辑性。下面详细介绍一

    2024年02月09日
    浏览(56)
  • 初阶c语言:趣味扫雷游戏

    目录 前言  制作菜单 构建游戏选择框架 实现游戏功能 模块化编程:查看前节三子棋的内容 初始化雷区 ​编辑 优化棋盘 随机埋入地雷 点击后的决策  实现此功能代码 game();的安排   《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点

    2024年02月11日
    浏览(38)
  • C语言小游戏——扫雷

            结合前边我们所学的C语言知识,本期我们将使用C语言实现一个简单的小游戏——扫雷 目录 前言 总体框架设计 多文件分装程序 各功能模块化实现 初始化棋盘  棋盘打印 埋雷  判赢与排雷 游戏逻辑安排 总结         和三子棋相同,游戏开始时不需要任何判

    2024年02月06日
    浏览(45)
  • 【C语言】扫雷游戏完整代码实现

    目录 1.game.h 2.game.c 3.progress.c 4.运行结果

    2024年02月21日
    浏览(44)
  • c语言小游戏之扫雷

    目录 一:游戏设计理念及思路 二:初步规划的游戏界面 三:开始扫雷游戏的实现 注:1.创建三个文件,test.c用来测试整个游戏的运行,game.c用来实现扫雷游戏的主体,game.h用来函数声明和包含头文件 2.为方便定位坐标,在展示数组时添加行号和列号 四:谢谢观看  听说看到

    2024年01月23日
    浏览(47)
  • C语言实现简单的扫雷游戏

    目录 1 - test.c 2 - game.c 3 - game.h 代码里的注释感觉已经很清楚啦,就不多讲解啦 感谢各位大佬的支持!!!

    2024年01月22日
    浏览(46)
  • 探秘C语言扫雷游戏实现技巧

    本篇博客会讲解,如何使用C语言实现扫雷小游戏。 使用2个二维数组mine和show,分别来存储雷的位置信息和排查出来的雷的信息,前者隐藏,后者展示给玩家。假设盘面大小是9×9,这2个二维数组都要开大一圈,也就是大小是11×11,这是为了更加方便的数边角上雷的个数,防止

    2024年02月10日
    浏览(44)
  • C语言之扫雷游戏实现篇

    目录 主函数test.c 菜单函数 选择循环 扫雷游戏实现分析 整体思路  问题1 问题2  问题3 问题4  游戏函数(函数调用)  创建游戏盘数组mine 创建游戏盘数组show 初始化游戏盘数组InitBoard 展示游戏盘DisplayBoard 游戏盘置雷SetMine 游戏盘排雷FindMine test.c总代码 头文件函数声明game

    2024年02月11日
    浏览(38)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包