扫雷小游戏 --基础练习 (C语言实现) -- 详解

文章目录

  • 前言
  • 1.扫雷思路
  • 2.扫雷代码实现
    • 2.1主函数构建:
    • 2.2 初始化扫雷棋盘
    • 2.3随机布置雷
    • 2.4扫雷
  • 扫雷总代码
  • 总结

✨✨✨学习的道路很枯燥,希望我们能并肩走下来!

编程真是一件很奇妙的东西。你只是浅尝辄止,那么只会觉得枯燥乏味,像对待任务似的应付它。但你如果深入探索,就会发现其中的奇妙,了解许多所不知道的原理。知识的力量让你沉醉,甘愿深陷其中并发现宝藏。


扫雷小游戏 --基础练习 (C语言实现) -- 详解_第1张图片

前言

本篇通过扫雷小游戏,加强对循环,选择,分支的练习,对于初学者小游戏能提高我们的兴趣,让我们一起操作起来吧!如有错误,请在评论区指正,让我们一起交流,共同进步!

本文开始
扫雷这个大家所熟知的小游戏,你是否玩过呢,他是你记忆中的一部分?
今天让我们来实操一下,如何用代码写出简单的扫雷,这里的扫雷,不能像真正的扫雷一样,只是大概思路相同,简单编写一个10个雷的简易模式,如果想让扫雷更加真实,请根据这篇文章,自我思考,自己编写一下吧!

1.扫雷思路

让我们先从 扫雷棋盘的格式 入手:

扫雷小游戏 --基础练习 (C语言实现) -- 详解_第2张图片

扫雷的区域构建肯定需要用到二维数组,但怎么考虑呢?
对于9*9的扫雷棋盘我们构建完够用吗?
构建扫雷棋盘我们还应该考虑到对于你选定的位置周围的8个方格如何计算,方格数是否满足?
我们通过以下图片来分析一下.

扫雷小游戏 --基础练习 (C语言实现) -- 详解_第3张图片

如何构建扫雷棋盘

对于黑方块所选内容为正常我们需考虑的,使用二维数组对于 红方块内容,则是会 出现越界访问的问题,如何解决呢,这里需要我们主动设置一个更大的扫雷棋盘,满足我们的要求.
需要 9 * 9 扫雷棋盘 --> 9 * 9的二维数组 -->考虑用11*11扫雷棋盘 (如图外层绿色方框)

放置雷,如何安放呢,怎么更好统计呢?
设置两个扫雷棋盘
①这里使用会使用两个扫雷棋盘(两个数组),一个mine数组用来放置雷信息,一个show数组用来放置排查出雷的信息
②开始设置:mine数组(设计者自己观察调整的扫雷棋盘)全初始化 ’0‘,布置为雷时改为 ’1‘;show数组(玩家观看)全初始化为 ’*‘,排雷后,玩家输入的位置改为数字字符(8个方格有几个雷),如:’3‘;

扫雷小游戏 --基础练习 (C语言实现) -- 详解_第4张图片

这里会有小伙伴问为什么用两个扫雷棋盘?

如果只有一个扫雷棋盘,计算出玩家所在周围有1个雷,会与开始放置的雷(1为雷)所重复,没法判断是雷(1),还是所处位置周围的雷(1);

为什么不用 *,#直接在一个棋盘表示?

2.扫雷代码实现

对于扫雷代码,我们一般不放在一个.c文件下,会显得思路不够简洁,代码整体太乱!

所以我们一般分为三个:
①text.c 扫雷游戏的测试逻辑
②game.h 游戏函数的声明
③game.c 游戏函数的实现

先构建扫雷游戏的测试逻辑

2.1主函数构建:

制作简易菜单(menu);选择输入是否开始游戏(switch);设置游戏循环条件(do while)

#include"game.h"

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("请选择(0/1):>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default :
			printf("输入错误,请重新输入\n");
			break;
		}

	} while (input);
	return 0;
}

当我们构建完主函数,接下来主要构建game()函数
game():
①创建扫雷棋盘
②初始化扫雷棋盘
③布雷
④排雷

[注]由于怕越界,创建扫雷棋盘都以11*11创建

2.2 初始化扫雷棋盘

初始化两个扫雷棋盘除了初始化内容不同,其他代码相同,为了使代码简便,我们只把需要初始化的参数传给函数即可,简化了代码

#include"game.h"
void init_board(char board[ROWS][COLS], int rows, int cols,int ret)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			//只需所要的初始化的值传过来就行
			mine[i][j] = ret;
		}
	}
}
//打印扫雷棋盘
void display_board(char mine[ROWS][COLS], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf("%c ", mine[i][j]);
		}
		printf("\n");
	}
}

 

开始打印扫雷棋盘:

扫雷小游戏 --基础练习 (C语言实现) -- 详解_第5张图片

扫雷棋盘虽然创建好了,但是不容易看每行坐标,我么来加上序号看一下!

扫雷棋盘优化:

  • 打印扫雷棋盘时先打印一行从0-9
    再打印数据时,每一行前面打印 i (i从1-9)
    形成类似坐标的样子方便观察
#include"game.h"
void display_board(char board[ROWS][COLS], int row, int col)
{
//row--行,col--列
	int i = 0;
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		int j = 0;
		//打印数据开始,先打印每一行行号1-9
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

代码结果:

扫雷小游戏 --基础练习 (C语言实现) -- 详解_第6张图片

2.3随机布置雷

这里用到之前文章讲的随机函数,产生随机值
rand(),srand(),time();
如果不了解随机值的产生,可以点开这篇文章看一下哦!

猜数字游戏里关于rand,srand的使用说明
[注]

  • 这里利用全局变量EASY_COUNT来控制布雷数量,如果想更改雷的数量,可以改变全局变量,来改变程序中的雷的数量(一改所有EASY_COUNT都改)
  • 这为了让电脑产生的随机值在1-9范围内,我们需要rand()%row,rand()%col,获取0-8以内的值,再+1获得1-9以内的值

代码示范:

void set_mine(char mine[ROWS][COLS], int row, int col)
{
	//布置10个雷
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
//本来余9是得到0-8的数,+1是得到1-9的数,正好与设置的序号对应
		int y = rand() & col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}

}

2.4扫雷

这是玩家所能操作的棋盘,需要玩家输入位置,就开始了扫雷
[注]

  • 扫雷游戏结束范围,找到所以不是雷的位置,游戏结束
    例如:以9 * 9扫雷棋盘为例,想要全部扫完雷,需要找到9 * 9(所有方格范围)-10(雷的个数)=71()不是雷的个数
  • 玩家输入扫雷范围满足:
    ①输入范围满足扫雷区域 (1<=x<=9,1<=y<=9)
    ②输入位置没有重复
    ③输入位置没有雷
  • 扫雷返回值的计算

代码示范:


int get_mine_count(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 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)
		{
			if (show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf("踩到了雷,被炸死了\n");
					display_board(mine, ROW, COL);
					break;
				}
				else
				{
					int count = get_mine_count(mine, x, y);
					show[x][y] = count + '0';
   //show中需要存字符数字,需要加上'0'字符0,如:'a'+2=‘c'
					display_board(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("该坐标已经被排除过了\n");
			}
		}
		else
		{
			printf("坐标超出范围,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		display_board(mine, ROW, COL);
	}
}

扫雷总代码

//game.h
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 80
#include
#include
#include

//初始化
void init_board(char board[ROWS][COLS], int rows, int cols,int ret);


//打印
void display_board(char board[ROWS][COLS], int row, int col);


//布雷
void set_mine(char mine[ROWS][COLS], int row, int col);
//排雷
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

//text.c
//#include"game.h"

void menu()
{
	printf("**********************\n");
	printf("*******  1.play ******\n");
	printf("*******  0.exit ******\n");
	printf("**********************\n");
}
void game()
{
	//printf("扫雷\n");
	//创建布雷区域
	char mine[ROWS][COLS] = { 0 };
	//创建显示雷有几个的棋盘--玩家眼中的区域
	char show[ROWS][COLS] = { 0 };
	//初始化雷区域全为字符0,‘0’
	//如何定义一个函数让两个全部初始化,只需要把初始化的内容传参传过去,就可以不要重复写一样的代码了
	init_board(mine, ROWS, COLS, '0');
	//display_board(mine, ROW, COL);
	//打印发现这样不容易观看,我们可以考虑为它们打印序号
	//初始化扫雷区域为‘*’
	init_board(show, ROWS, COLS, '*');
	//display_board(show, ROW, COL);

	//布雷
	set_mine(mine, ROW, COL);
	display_board(mine, ROW, COL);
	//排雷
	display_board(show, ROW, COL);
	find_mine(mine,show, ROW, COL);


}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{

		menu();
		printf("请选择(0/1):>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}

	} while (input);
	return 0;
}

//game,c
//#include"game.h"
void init_board(char board[ROWS][COLS], int rows, int cols, int ret)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}
void display_board(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		int j = 0;
		//打印数据开始,先打印每一行行号1-9
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

void set_mine(char mine[ROWS][COLS], int row, int col)
{
	//布置10个雷
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;//本来余9是得到0-8的数,+1是得到1-9的数,正好与设置的序号对应
		int y = rand() & col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}

}

int get_mine_count(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 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)
		{
			if (show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf("踩到了雷,被炸死了\n");
					display_board(mine, ROW, COL);
					break;
				}
				else
				{
					int count = get_mine_count(mine, x, y);
					show[x][y] = count + '0';//show中需要存字符数字,需要加上'0'字符0,'a'+2=‘c'
					display_board(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("该坐标已经被排除过了\n");
			}
		}
		else
		{
			printf("坐标超出范围,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		display_board(mine, ROW, COL);
	}
}

总结

✨✨✨各位读友,本篇分享到内容是否更好的让你理解了扫雷小游戏的乐趣,让你对代码的兴趣有了提升呢?如果文章对你有帮助希望给个赞鼓励一下吧!!
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!
扫雷小游戏 --基础练习 (C语言实现) -- 详解_第7张图片

你可能感兴趣的:(c语言,java,算法,学习,软件工程)