玩儿转C语言——初级扫雷易懂详解

目录

    • 传统艺能
    • 过渡区
    • 正片开始
    • 上菜单
    • 游戏主体
    • 初始化
    • 打印雷区
    • 埋雷大师
    • 扫雷专家
    • 雷区舞王

传统艺能

小编是大一菜鸟不赘述,欢迎大佬指点江山(QQ:1319365055)
此前博客点我!点我!请搜索博主 【知晓天空之蓝】点我!点我!请搜索博主 【知晓天空之蓝】或扫码进入!
乔乔的gitee代码库(打灰人 )欢迎访问,点我!
在这里插入图片描述

(https://blog.51cto.com)感谢支持!

过渡区

现在是北京时间2:38,白天事情还是那么多,夜生活又是写博客,昨天没写也是因为没把扫雷整通透,反正明天早上一二节也没课,现在就是我最享受的时刻,一个人,一盏灯,一杯咖啡,没有寝室的喧闹,后台放着最爱的歌,向往着最精彩的明天

玩儿转C语言——初级扫雷易懂详解_第1张图片

正片开始

一雷不扫,何以扫天下?

今天主要是实现初级的扫雷游戏,方法比较通俗易懂,制作方面不侧重包装而注重功能实现,只是简单对“扫雷”进行简单表达,后期会进行优化和提升。

接受三子棋洗礼后,其实扫雷和上一篇的三子棋大同小异,但其实真正写过才知道扫雷要比三子棋简单一点点,因为三子棋在空间上操作更多,会更加依赖二维数组的使用,所以过程会更加繁琐。下面就来康康扫雷的具体流程:
为方便使用还是先将数组两个元素在头文件中宏定义一下,也方便后期修改:

# define ROW ROW2+2
# define COL COL2+2
# define ROW2 9
# define COL2 9

上菜单

void menu()
{
printf("------------------------------------\n");
printf("-------      M e n u     -----------\n");
printf("-------                  -----------\n");
printf("-------1.P    L    A    Y-----------\n");
printf("-------0.E    X    I    T-----------\n");
printf("------------------------------------\n");
printf("------------------------------------\n");
}

简简单单的小菜单,这是一个菜单函数,由switch语句实现选择功能:

void test()
{
	int input = 0;   //输入的值存入input以进行判断
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择菜单:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
		{
			printf("开始扫雷:");
		    saolei();  //进入游戏主体
			break;
		}
		case 0:
		{
			printf("即将退出……");
			break;
		}
		default:         //对付非指定值输入
		{
			printf("玩儿呢这是?\n");
			break;
		}		
		}
	} while (input);     //可反复游玩
}

游戏主体

void saolei()
{
	char board[ROW][COL] = { 0 }; //实际矩阵
	char real[ROW][COL] = { 0 };  //玩家视角矩阵

	Start(board, ROW, COL, '0');  //雷区初始化
	Start(real, ROW, COL, '*');
	Set(board, ROW, COL);  //布雷(埋雷)
	Show(board, ROW2, COL2);
	Show(real, ROW2, COL2);  //布局(雷区`在这里插入代码片`)展现
	Find(board, real, ROW, COL);  //逻辑判断
		
}

初始化

首先数组的创建上就与三子棋大不相同,基于游戏本身规则的特性,我们需要实际的设计雷阵和呈现给玩家的雷阵,这也是扫雷的一大特色。因为初始化方式不同,对应的功能也不一样,我们就创建了名为 board 和 real 的数组。

在 game.c中用Start函数进行定义:

void Start(char board[ROW][COL], int row, int col,char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = set;
		}
		printf("\n");
	}
}

这里用一个for循环的嵌套实现数组的初始化,这里的“ set ”是我指定好的两种字符,我们制作需要全零以便埋雷,而玩家需要一个“ * ”来达到猜测的目的。

打印雷区

我们先把我们需要的和玩家的打出来对比一下如下:下为玩家视角。
玩儿转C语言——初级扫雷易懂详解_第2张图片
用 Show 函数实现如下:

void Show(char board[ROW2][COL2], int row2, int col2)
{
	int i = 0;
	int j = 0;
	for (i = 0; i <= col2;i++)
	{
		printf("%d ", i);//打印行列对应数字
	}
	printf("\n");
	for (i = 1; i <= row2; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col2; j++)
		{
			printf("%c ", board[i][j]);//存入%c以埋雷
		}
		printf("\n");
		
	}
}

埋雷大师

void Set(char board[ROW][COL], int row, int col)
{
	int count = degree;
	while (count)
	{
		int x = rand() % row + 1;  //生成0~9随机数
		int y = rand() % col + 1;  //生0~9成随机数
		if (board[x][y] == '0')
		{
			board[x][y] = '1';  //判断,是空格就可以埋雷
			count--;//埋十颗
		}
	}
}

这里的重点就只有随机数的应用。这里的随机数是伪随机数,rand函数生成,需要在主函数部分进行初始化,用到 “srand”函数,以时间戳作为随机数的生成标准,不做赘述,不了解的可详见上一篇三子棋的讲解,记住要引用头文件。

扫雷专家

==一雷不扫,何以扫天下?==扫雷的标准是成功的开山斧,逻辑到位了一切都是信手拈来。判断输赢不难,看有没有踩雷,排没排完的简单逻辑谁不会写?重点是没踩雷也没排完的过程:

当我们走到一个“安全区”时,我们显示出来的是周围8个单位格子的雷数和,我们设置一个 Amount 函数,利用周围8个单位格的返回值进行输入,这里注意,我们算出的返回值是一个整型,但我放入数组的是一个字符类型,将一个数转换成他对应的字符类型怎么办呢?很简单只需+‘ 0 ’即可,由此可知,我们在算8个单位格之和返回值时会事先 -8* ‘ 0 ’。

static Amount(char board[ROW][COL], int x, int y) // 限制为本源文件使用
{
	return board[x + 1][y]
		+ board[x + 1][y + 1]
		+ board[x][y + 1]
		+ board[x - 1][y + 1]
		+ board[x - 1][y]
		+ board[x - 1][y - 1]
		+ board[x][y - 1]
		+ board[x + 1][y - 1]-8*'0';  //总和计算

}
void Find(char board[ROW2][ROW2], char real[ROW2][COL2], int row, int col)
{
	int x = 0;
	int y = 0;
	int i = 0;
	int win = 0;

	while (win<row*col-10)
	{
		printf("请输入排查坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x][y] == '1')   //踩雷判断
			{
				printf("B  O  O  M !!!!\n");
				printf("Game Over\n");
				Show(board,row-2,col-2);
				break;
			}
			else    //未踩雷的雷数计算
			{
				i = Amount(board, x, y);
				real[x][y] = i+'0';
				Show(real,row-2,col-2);
				win++;
			}
		}
		else  //判断越界
		{
			printf("无效坐标!重新输入\n");
		}
	}
	if (win == row * col - 10)    //胜利判断
	{
		printf("Congratulatin,You Win !!!\n");
	}

}

雷区舞王

完整代码,参上:

test.c

# include"saolei.h"

void menu()
{
printf("------------------------------------\n");
printf("-------      M e n u     -----------\n");
printf("-------                  -----------\n");
printf("-------1.P    L    A    Y-----------\n");
printf("-------0.E    X    I    T-----------\n");
printf("------------------------------------\n");
printf("------------------------------------\n");
}

void saolei()
{
	char board[ROW][COL] = { 0 };//扫雷矩阵
	char real[ROW][COL] = { 0 };//排雷矩阵

	Start(board, ROW, COL, '0');//初始化
	Start(real, ROW, COL, '*');
	Set(board, ROW, COL);//布置
	Show(board, ROW2, COL2);
	Show(real, ROW2, COL2);//布局
	Find(board, real, ROW, COL);
		
}
void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择菜单:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
		{
			printf("开始扫雷:");
		    saolei();
			break;
		}
		case 0:
		{
			printf("即将退出……");
			break;
		}
		default:
		{
			printf("玩儿呢这是?\n");
			break;
		}		
		}
	} while (input);
}

int main()
{
	test();
	return 0;
}          

game.c

# define _CRT_SECURE_NO_WARNINGS 
# include"saolei.h"

void Start(char board[ROW][COL], int row, int col,char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = set;
		}
		printf("\n");
	}
}

void Show(char board[ROW2][COL2], int row2, int col2)
{
	int i = 0;
	int j = 0;
	for (i = 0; i <= col2;i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row2; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col2; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
		
	}
}
void Set(char board[ROW][COL], int row, int col)
{
	int count = degree;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

static Amount(char board[ROW][COL], int x, int y)
{
	return board[x + 1][y]
		+ board[x + 1][y + 1]
		+ board[x][y + 1]
		+ board[x - 1][y + 1]
		+ board[x - 1][y]
		+ board[x - 1][y - 1]
		+ board[x][y - 1]
		+ board[x + 1][y - 1]-8*'0';

}
void Find(char board[ROW2][ROW2], char real[ROW2][COL2], int row, int col)
{
	int x = 0;
	int y = 0;
	int i = 0;
	int win = 0;

	while (win<row*col-10)
	{
		printf("请输入排查坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x][y] == '1')
			{
				printf("B  O  O  M !!!!\n");
				printf("Game Over\n");
				Show(board,row-2,col-2);
				break;
			}
			else
			{
				i = Amount(board, x, y);
				real[x][y] = i+'0';
				Show(real,row-2,col-2);
				win++;
			}
		}
		else
		{
			printf("无效坐标!重新输入\n");
		}
	}
	if (win == row * col - 10)
	{
		printf("Congratulatin,You Win !!!\n");
	}

game.h

#pragma once

# define ROW ROW2+2
# define COL COL2+2
# define ROW2 9
# define COL2 9
# define degree 10

# include
# include
# include 

void menu();
void saolei();
void Start(char board[ROW][COL], int row, int col,char set);
void Show(char board[ROW2][COL2], int row2, int col2);
void Set(char board[ROW][COL], int row2, int col2);
void Find(char board[ROW][ROW], char real[ROW][COL], int row, int col);

实战效果:(模拟踩雷)
玩儿转C语言——初级扫雷易懂详解_第3张图片

现在是北京时间4:32,这波是熬夜冠军哈哈,躺平了家人们。

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