扫雷详解(数组的综合应用)

目录

前言

 1.菜单

 2.初始化

小                                                提                                            示

  3.打印游戏画面 

4.布雷

 5.排雷

1.确认坐标的合法性

2.检测是否已经为已排坐标

3.判断是否为炸弹

4.显示数字

5.游戏结束声明

test.c

game.c

 game.h​


前言

扫雷即数组于游戏之中的应用,与三字棋不同,其难点在于排雷之时细节的繁琐和打印数组时丧失全无的方向感,而产生的小错误往往很难发现。因此在写的时候必须十分谨慎,不然找错误的时候就会非常痛苦。希望这个博客能都对大家有点帮助。

扫雷详解(数组的综合应用)_第1张图片

 1.菜单

一样,怎么好看怎么来,为了我们玩完一把之后还能再玩下去,do while循环就是因此而存在的,因其特性可以至少运行一次,然后我们再使用input作为参数当input为0时循环结束。同样我们这次也是要使用随机值来布雷,因而要在主函数中对rand用时间戳进行定义。然后用switch来进行选择,根据input的不同语句的入口也不一样,使用break 将各各区域分隔开,避免走入其他语句之中。

扫雷详解(数组的综合应用)_第2张图片

扫雷详解(数组的综合应用)_第3张图片

 2.初始化

跟三字棋一样,为了更好的管理,我们建立test.c game.c 和 game.h 文件来将内容分隔开,这样更加方便与不同语句的处理和应用。

这时候让我们回想一下扫雷游戏的基本内容,有一个游戏界面在格子内部还藏有地雷,当我们要将界面打印,又要在内部藏有地雷,就需要使用到二维数组;显然只有一个数组是不够的。我们可以用一个数组来存储地雷,一个数组打印出来给玩家观看。同时玩家选择一个坐标之后,对该坐标是否为地雷进行判断,那么问题来了,在判断的时候沿边缘坐标的格子我们如何判断其周围的地雷数量呢?那我们得将棋盘拓展开来方便于我们的判断,但实际打印出来的得还是9X9的棋盘。

扫雷详解(数组的综合应用)_第4张图片扫雷详解(数组的综合应用)_第5张图片

 所以刚开始我们对两个数组先进行初始化。

 然后在game.h内进行声明,记得引头文件~(自己的头文件用双引号)~可以把stdio.h放在game.h里面就不用引好多次了。

扫雷详解(数组的综合应用)_第6张图片

ROW COL 为原来棋盘大小,ROWS COLS为拓展棋盘大小

小                                                提                                            示

 在game.h里面定义需要用大写(血和泪的教训)如果自己定义常量的时候记得这一点!!!!!

此时我们的界面还是空的,现在要对这个数组进行初始化,我们需要传四个参数,各个数组、行数、列数、初始化所定义的字符,我们这里将内数组 雷定义为1非雷定义为0,将外数组全定义为  * 号打印出来作为我们的游戏界面。

设置一个函数,在game.h声明,在game.c中定义。用row col 和set 来接收我们传过来的行、列、要定义的字符。

 两个for循环全选整个数组并将其定义成我们想要的字符扫雷详解(数组的综合应用)_第7张图片

这样我们数据的初始化就完成了!!

  3.打印游戏画面 

如果只是普通的把数组打印出来的话,只需要两个for循环全选然后一个一个打印就可以了,但是我们想在标头加上行号和列号的话,就要加上一些修饰。需要在两个for循环前在加上一个循环用于打印列号,在每一列的打印中加上行号的打印。并且要打印的是9X9的游戏界面,所以用的row和col也是9而不是11。

扫雷详解(数组的综合应用)_第8张图片

 如果没有换行的操作的话,就会变成这样

 或者  这样

扫雷详解(数组的综合应用)_第9张图片

 还有可能出现这种情况

扫雷详解(数组的综合应用)_第10张图片

 是由于把%c顺手打成了%d扫雷详解(数组的综合应用)_第11张图片

4.布雷

只需要根据设置雷的数量生成该数量的随机数,并检测其合法性之后将其放置在内侧的数组之中,就是这个常量的设置,在头文件中要用大写来定义,害我写的时候老是报错。

扫雷详解(数组的综合应用)_第12张图片

 5.排雷

之后就来到扫雷游戏中最关键的一步了。提示玩家排雷后,接收玩家输入的坐标进行进一步的检测。

1.确认坐标的合法性

当下我们打印出来的界面是这个样子的,即坐标从1开始到9结束,即我们坐标的合法范围。

扫雷详解(数组的综合应用)_第13张图片

2.检测是否已经为已排坐标

同时还要检查是否已排,需从外数组检查该坐标的字符是否为  *  即使阻止通过不断循环来寻找程序的漏洞。

3.判断是否为炸弹

外数组于内数组是相互对应的,在内数组检测该坐标是否为炸弹,若是则退出游戏并打印内界面让玩家死得明白(doge)

扫雷详解(数组的综合应用)_第14张图片

4.显示数字

经过三轮选择后的数据,即是可以继续走下去的数据,我们需要找出他周围的炸弹数并将其打印在外界面上。同时,我们数组之中存放的是字符类型的数据。一个数加上字符0的ASCII码值之后就是该数字的字符形式了。

 同时我们在这个函数上实现检测地雷数的函数。

扫雷详解(数组的综合应用)_第15张图片

 一个一个将数列内值取出,外函数中每有一个1,我们刚好用数列将其表达出来减去8个0即转换成ASCII码传回原函数之后再找回相对应的数并替换到外数组上,再将画面打印给玩家看,我们一次排雷便算完成了。

5.游戏结束声明

一次游戏,一共有row X col的格子扣掉地雷的数量便得到了一共需要排雷几次,将参数带入循环,则成为了游戏结束的凭据。扫雷详解(数组的综合应用)_第16张图片

 最后祝贺玩家取得胜利,并打印出内界面,告诉玩家地雷的位置。如此我们的扫雷游戏就写完了。将完整的代码放在下面供参考。

test.c

扫雷详解(数组的综合应用)_第17张图片

game.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

void iniboard(char board[ROWS][COLS], int row, int col,int set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = set;
		}
	}
}
void display_board(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}
void putboom(char board[ROWS][COLS], int row, int col)
{
	int n = EASY_COUNT;
	while (n)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			n--;
		}
	}
}
int showaround(char back[ROWS][COLS], int x, int y)
{
	return (back[x + 1][y] +
		back[x][y + 1] +
		back[x + 1][y + 1] +
		back[x - 1][y - 1] +
		back[x - 1][y + 1] +
		back[x + 1][y - 1] +
		back[x - 1][y] +
		back[x][y - 1]-8*'0');
}
void checkboom(char back[ROWS][COLS], char out[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = 0;
	while (1)
	{
		printf("请排雷:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (out[x][y] = '*')
			{
				if (back[x][y] == '1')
				{
					printf("很遗憾,游戏结束。\n");
					display_board(back, ROW, COL);
					break;
				}
				else
				{
					int ret = showaround(back, x, y);
					out[x][y] = ret + '0';
					display_board(out, ROW, COL);
					count++;
				}
			}
			else
			{
		      printf("该坐标已经被排查过了。");
			}
		}
		else
			printf("输入错误,请重新输入\n");
		if (row * col - EASY_COUNT == count)
		{
			printf("恭喜你,取得胜利!\n");
			display_board(back, ROW, COL);
			break;
         }
	}
}

 game.h扫雷详解(数组的综合应用)_第18张图片

你可能感兴趣的:(开发语言,c语言)