扫雷【C语言】

本文详细介绍了如何使用C语言编写一个简单的扫雷游戏,包括初始化棋盘、打印棋盘、埋雷、计算周围雷数以及排雷过程。同时涉及到了伪随机数生成和使用time函数获取随机种子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     扫雷作为无人不晓的游戏,可以说非常火。其实利用数组函数就能写一个简单版的扫雷!

目录

初始化棋盘

打印棋盘

埋雷

周围雷数

排雷 

整体代码

test.c

game.h

game.c 

实现随机数


我建议创建多个项目这样方便管理而且更简洁。我在这里创建了这3个。

     test.c:测试函数。

     game.c:函数实现。

     game.h:函数声明和定义常量。

初始化棋盘

     我们要做一个9×9的棋盘,并且要用到两个二维数组一个是明面(xing)一个是暗面(digital)。虽然要做9×9的棋盘但是我们要定义11×11的数组(关于为什么这样到后面就知道了)要是char类型。数组中的行和列我把它定义为常量(方便后期更改)。

#define line 9//行
#define column 9//列

#define lines line + 2
#define columns column + 2

     初始化函数其实很简单只需要遍历一遍,再把值赋进去就行。

//初始化棋盘
void Initialize(char function[lines][columns], int Lines, int Columns, char n)
{
	for (int i = 0; i < Lines; i++)
	{
		for (int j = 0; j < Columns; j++)
		{
			function[i][j] = n;//赋值
		}
	}
	
}

注:这里的n是表示要赋的值。有两种:' * '是明面的(xing数组),' " '是暗面的(digital数组)。 

打印棋盘

     在打印棋盘时用的是xing数组,遍历一遍即可。如果直接打印那我们在后期玩的时候就会不知道坐标。所以我们还要给数组行和列排序。

//打印棋盘
void Print(char function[lines][columns], int Line, int Column)
{
    printf("--------扫雷-------\n");
	int b = 1;
	for (int k = 0; k <= Line; k++)//数组行排序
	{
		printf("%d ", k);
	}
	printf("\n");
	for (int i = 1; i <= Line ; i++)//打印棋盘
	{
		printf("%d ", b);//数组列排序
		for (int j = 1; j <= Column ; j++)
		{
			printf("%c ", function[i][j]);
		}
        b++;
		printf("\n");
	}
}

埋雷

    雷是随机分布的具体是怎么实现,我就不在此多说了,如果想看的可以到文章的最后看。大家看我写的就行。雷的数量我把它定义为常量(方便后期更改)。

//雷
#define thunder 10

     在test.c中加上srand((unsigned int)time(NULL))(头文件<stdlib.h>,<time.h>)。因为thunder是一个常量不能被更改,所以要定义一个变量。

//埋雷
void Bury(char function[lines][columns], int Line, int Column)
{
	int num = thunder;
	while (num)
	{
		int x = rand() % line + 1;
		int y = rand() % column + 1;
		if (function[x][y] == '"')//判断这个地方是不是雷
		{
			function[x][y] = '!';//'!'代表雷
			num--;
		}
	}
}

     x,y怎么理解呢?

     一个数除9会余0~8中的随机一位,加上一后x和y的范围就是1~9。

周围雷数

     选中一个坐标后我们要计算它周围8个格子中有几个雷要怎么做呢?

     其实只需要把周围8个格子相加(虽然是char类型,计算时是用ASCII码值计算),然后减去8个' " '的ASCII码值,最后乘-1(!比"要大一位所以减后是负数)。因为是11×11的棋盘不用担心边缘的位置发生非法访问。

//周围雷数
char First_difference(char digital[lines][columns], int x, int y)
{
	return (digital[x - 1][y - 1] + digital[x - 1][y] + digital[x - 1][y + 1] +
            digital[x][y - 1] + digital[x][y + 1] + 
            digital[x + 1][y - 1] + digital[x + 1][y] + digital[x + 1][y + 1] - 34 * 8) * -1;
}

排雷 

     排雷肯定是个循环,但是要循环多少次呢?那就要看有多少不是雷了。

     如果在排雷中不幸排到雷那就跳出循环。如果没有那就让First_difference函数返回周围有几个雷,让返回值加上48(First_difference返回的是char类型,让它加48对应字符数字)。让xing数组的该位置等于它即可。最后打印。

     怎么判定成功呢?其实只需要一个flag变量。在每次没选到雷时flag++,最后如果flag等于没雷的数量那就成功了。

//排查雷
void Minesweeping(char digital[lines][columns], char xing[lines][columns], int Line, int Column)
{
	int a = line * column - thunder;//循环次数(不是雷的数量)
	int flag = 0;
	int x = 0;
	int y = 0;
	while (a--)
	{
		printf("请选择你要排查的坐标:");
		scanf("%d %d", &x, &y);
		if (digital[x][y] == '!')//选中雷
		{
			printf("\n");
			printf("很遗憾你死了,雷分布如下。注:!是雷\n");
			Print(digital, line, column);
			break;
		}
		else//未选中雷
		{
			char r = First_and_then_difference(digital, x, y);
			xing[x][y] = r + 48;
			Print(xing, line, column);
			flag++;
		}
	}
	if (flag == line * column - thunder)
	{
		printf("恭喜你通过了!!!\n");
	}
}

     这是升级版的扫雷的地址扫雷(升级版)附全代码-优快云博客 。

整体代码

test.c

#include "game.h"//自己写的头文件只能用""

void test()
{
	//创建数组
	char xing[lines][columns] = { 0 };
	char digital[lines][columns] = { 0 };
	//初始化
	Initialize(digital, lines, columns, '"');//暗
	Initialize(xing, lines, columns, '*');//明
	//埋雷
	Bury(digital, line, column);
	//打印
	Print(xing, line, column);
	//排雷
	Minesweeping(digital, xing, line, column);
}

int main()
{
    srand((unsigned int)time(NULL));
    test();
    return 0;
}

game.h

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//行
#define line 9
//列
#define column 9

#define lines line + 2
#define columns column + 2

//雷
#define thunder 10

//初始化棋盘
void Initialize(char function[lines][columns], int Lines , int Columns, char n);		

//打印棋盘
void Print(char function[lines][columns], int Line, int Column);

//埋雷
void Bury(char function[lines][columns], int Line, int Column);

//周围雷数
char First_difference(char digital[lines][columns], int x, int y);

//排查雷
void Minesweeping(char digital[lines][columns], char xing[lines][columns], int Line, int Column);

game.c 

#include "game.h"

//初始化棋盘
void Initialize(char function[lines][columns], int Lines, int Columns, char n)
{
	for (int i = 0; i < Lines; i++)
	{
		for (int j = 0; j < Columns; j++)
		{
			function[i][j] = n;
		}
	}
	
}

//打印棋盘
void Print(char function[lines][columns], int Line, int Column)
{
	printf("--------扫雷-------\n");
	int b = 1;
	for (int k = 0; k <= Line; k++)
	{
		printf("%d ", k);
	}
	printf("\n");
	for (int i = 1; i <= Line ; i++)
	{
		printf("%d ", b);
		for (int j = 1; j <= Column ; j++)
		{
			printf("%c ", function[i][j]);
		}
		b++;
		printf("\n");
	}
}

//埋雷
void Bury(char function[lines][columns], int Line, int Column)
{
	int num = thunder;
	while (num)
	{
		int x = rand() % line + 1;
		int y = rand() % column + 1;
		if (function[x][y] == '"')
		{
			function[x][y] = '!';
			num--;
		}
	}
}

//周围雷数
char First_difference(char digital[lines][columns], int x, int y)
{
	return (digital[x - 1][y - 1] + digital[x - 1][y] + 
			digital[x - 1][y + 1] + digital[x][y - 1] + 
			digital[x][y + 1] + digital[x + 1][y - 1] + 
			digital[x + 1][y] + digital[x + 1][y + 1] - 34 * 8) * -1;
}

//排查雷
void Minesweeping(char digital[lines][columns], char xing[lines][columns], int Line, int Column)
{
	int a = line * column - thunder;
	int flag = 0;
	int x = 0;
	int y = 0;
	while (a--)
	{
		printf("请选择你要排查的坐标:");
		scanf("%d %d", &x, &y);
		if (digital[x][y] == '!')
		{
			printf("\n");
			printf("很遗憾你死了,雷分布如下。注:!是雷\n");
			Print(digital, line, column);
			break;
		}
		else
		{
			char r = First_difference(digital, x, y);
			xing[x][y] = r + 48;
			Print(xing, line, column);
			flag++;
		}
	}
	if (flag == line * column - thunder)
	{
		printf("恭喜你通过了!!!\n");
		printf("\n");
	}
		
}

实现随机数

       C语言提供了rand函数,这个是用来生成随机数的。头文件为stdlib.h。给大家简单操作一下。

f40dacba3b3644969cc35dbd57b3a527.jpg

     通过以上我们不难发现第一次和第二次结果一样。事实上rand是伪随机数。伪随机数不是真正的随机数,是通过某种算法生成的。真正的随机数是无法预测的。而rand函数是对一个叫"种子"的基准值进行运算生成的随机值。因为种子默认为1,所以想生成不同随机数,就要让种子改变。

     C语言为我们提供了srand函数。用来初始化随机数的生成器。程序中在调用rand 函数之前先调用srand 函数,通过srand 函数的参数seed来设置rand函数生成随机数的时候的种子,只要种子在变化,每次生成的随机数序列也就变化起来了。

     那也就是说给srand的种子是如果是随机的,rand就能生成随机数;在生成随机数的时候又需要一个随机数,这就矛盾了。

     在程序中我们一般是使用程序运行的时间作为种子的,因为时间时刻在发生变化的。在C语言中有一个函数叫time,就可以获得这个时间。time会返回当前的日历时间。其实也就是返回1970年1月1日0时0分0秒到现在程序运行之间的差值。time函数的参数timer如果是非NULL的指针的话,函数也会将这个返回的差值放在timer指向的内存中带回去。

     如果 timer是NULL,就只返回这个时间的差值。time函数返回的这个时间差也被叫做:时间戳。 time函数的时候需要包含头文件:time.h如果只是让time返回时间戳的话可以这样写time(NULL);

    以上写的可能不够具体,如果存在什么问题的话,可以私信我。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值