用C实现扫雷游戏(低配版)

利用循环与数组的知识,可以初步实现扫雷游戏的编写。

利用控制台的功能,可以用自己写出的代码玩扫雷游戏啦!!!

整个代码将由多个函数嵌套而成,因此我们在同一个项目中建设三个文件,来用于存放函数的头文件,函数运行和主函数。

先确定整体思路:

创建雷区——初始化雷区(随机生成雷)——打印雷区——进行扫雷——反馈结果并显示周围雷数——打印雷区——直到雷全部扫完,游戏结束。

首先,我们创建两个二维数组。(InitBoard,Print)

一个用来存放雷区状况,一个用来存放每一格周围有多少颗雷的情况,详情如下

左边为show数组,右边为mine数组。

用’*‘符号初始化mine数组,’*‘地区意为未扫雷地带。打印出雷区和每一格的横纵坐标。

void InitBoard(char arr[100][100],int row,int col,char set)//初始化数组
{
	int j;
	int i;
	for (i = 0; i <= row+1; i++)
	{
		for (j = 0; j <= col+1; j++)
		{
			arr[i][j] = set;
		}
	}
}
void print(char arr[100][100], int row,int col)
{
	int i,j,m;
	for (m = 0; m <= col; m++)
	{
		printf("%2d ", m);
	}
	printf("\n");
	for (i = 1; i <=row; i++)
	{
		printf("%2d  ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c  ", arr[i][j]);
		}
		printf("\n");
	}
}

ps.将雷区从mine[1][1]开始设置,是为了防止检查周围雷数时数组越界。比如想要初始化9*9的雷区,就需要初始化11*11的二维数组,如上方图1,2所示。

打印9*9以上的雷区时,会出现坐标与‘*’对不齐的情况,可以参照以上代码,用"%2d"进行向右对齐。

现在开始布雷(Creat)

num为想要布置的雷数,用’1‘字符来表示雷。

利用

srand((unsigned int)time(NULL));
int x = rand() % row + 1;
int y = rand() % col + 1;

生成随机坐标,将其放进循环之中,通过if语句判断该坐标是否有雷,有则进入下一次循环,无则布雷并且使count变量减一,count为需设雷数,当其为零时,循环结束,布雷完成。详情如下:

void creat(char arr[100][100], int row, int col,int num)
{
	srand((unsigned int)time(NULL));
	int count = num;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (arr[x][y] == '*')
		{
			arr[x][y] = '1';
				count--;
		}
	}
}

最后进入扫雷环节(Find)

ps.可以将mine和show一起打印出来,看着答案扫雷以检验项目是否正确。具体流程如下:

InitBoard(mine, row, col, '*');
InitBoard(show, row, col, '*');
creat(mine, row, col, num);
print(show, row, col);
print(mine, row, col);

但是最后记得把打印mine的部分给注释掉,不然你的扫雷游戏就会自动泄题啦。

玩家通过向控制台中输入坐标进行扫雷,程序判断mine数组中对应下标的字符是否为’1‘。

如果为’1‘,则输出“你被炸死啦”并返回0。

若为’*‘,则调用另一个函数,该函数会对该坐标周围一圈进行查看,最终返回以该坐标为中心的3*3方格中有几个’1‘,即周围雷数,并将其值num返回。Find函数会将num这一返回值赋予show数组中对应坐标并返回1。

若不为’1‘或’*‘,则说明玩家输入的数组越界,输出"格式错误,请重新填写“并返回2。

int Find(char arr[100][100],char ch[100][100], int row, int col)
{
	int x, y;
	scanf("%d,%d", &x, &y);

	if (arr[x][y] == '1')
	{
		printf("你被炸死了\n");
		return 0;
	}
	else if (arr[x][y] == '*')
	{
		ch[x][y] =Jud(arr,x,y)+'0';
		return 1;
	}
	else
		printf("格式错误,请重新填写:\n");
	return 2;
}

上述用于查找周围雷数的函数为Jud,向其中传入用户输入的坐标(x,y),他会对(x-1,y-1)(x-1,y)(x-1,y+1)(x,y-1)(x,y)(x,y+1)(x+1,y-1)(x+1,y)(x+1,y+1)这九个坐标进行检查,统计其中的雷数并将其返回。具体如下

int Jud(char arr[100][100], int x, int y)
{
	int i, m, n,num=0;
	for (i = y - 1; i <= y + 1; i++)
	{
		if (arr[x - 1][i] == '1')
		{
			num++;
		}
	}
	for (m = y-1; m <= y + 1; m++)
	{
		if (arr[x][m] == '1')
		{
			num++;
		}
	}
	for (n = y - 1; n <= y + 1; n++)
	{
		if (arr[x+1][n] == '1')
		{
			num++;
		}
	}
	return num;
}

利用以上的五个函数,我们就可以实现一个扫雷游戏的函数game。

只需要按照前面所说的“创建雷区——初始化雷区(随机生成雷)——打印雷区——进行扫雷——反馈结果并显示周围雷数——打印雷区——直到雷全部扫完,游戏结束”的顺序调用函数即可

由于扫雷需要多次操作和判断,我们将Find函数放进while循环之中,以其返回值来决定是否继续循环。

定义一个count来计算循环次数,当循环进行的次数等于非雷坐标数时,输出"恭喜你,扫雷成功!!!”并使循环结束(break)。

完整的game函数如下:

void game(int t)
{
	int count = 0;
	int i,j;
	char show[100][100] = { '0'};
	char mine[100][100] = { '0'};
	int row=0,col=0,num=0;
	if (t == 1)
	{
		row = 3;
		col = 3;
		num = 2;
	}
	else if (t == 2)
	{
		row = 9;
		col = 9;
		num = 10;
	}
	else if (t == 3)
	{
		row = 16;
		col = 16;
		num = 40;
	}
	InitBoard(mine, row, col, '*');
	InitBoard(show, row, col, '*');
	Creat(mine, row, col, num);
	Print(show, row, col);
	/*Print(mine, row, col);*/
	//print(show, row, col);
	printf("请输入扫雷坐标:");
	while (Find(mine,show, row, col))
	{
		
		Print(show, row, col);
		count++;
			if (count == row * col - num)
			{
				printf("恭喜你,扫雷成功!!!\n");
				break;
			}
			printf("请输入扫雷坐标:");
	}
}

如此,扫雷游戏的编写就已经接近尾声了,我们可以再做一些修缮,为其增添一点游戏的仪式感。

int menu()
{
	int t;
	Sleep(1000);
	printf("****************************************\n");
	Sleep(1000);
	printf("****************************************\n");
	Sleep(1000);
	printf("****************************************\n");
	Sleep(1000);
	printf("****************游戏开始****************\n");
	Sleep(1000);
	printf("****************************************\n");
	Sleep(1000);
	printf("****************************************\n");
	Sleep(1000);
	printf("****************************************\n");
	printf("请选择你想要的难度:\n");
	printf("1.简单:3*3,雷*2\n");
	printf("2.普通:9*9,雷*10\n");
	printf("3.困难:16*16,雷*40\n");
	scanf("%d", &t);
	return t;
}

加入菜单函数,利用闪烁打印游戏开始菜单(具体可以参照前面“猜数游戏”那篇文章),并让玩家自由选择不同的游戏难度,通过返回值的形式,与game函数嵌套在一起。

int main()
{
	int t;
	int w = 1;
	while (w)
	{
		game(menu());
		printf("输入'0'退出游戏,输入'1'继续游戏:\n");
		scanf("%d", &w);
	}
	return 0;
}

主函数中,将整个game和menu函数放入循环之中,通过循环末尾对变量w的改变,给玩家提供终止游戏和继续玩两个选项,互动性杠杠滴。

最后,三个文件的代码都放这了,希望大家耐心看,耐心理解,我们一同进步!

game.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void InitBoard(char arr[100][100], int row, int col,char set);//初始化数组
void Print(char arr[100][100], int row,int col);
void Creat(char arr[100][100], int row, int col,int num);
int Jud(char arr[100][100], int x, int y);
int Find(char arr[100][100], char ch[100][100], int row, int col);

game.c

#include"game.h"
void InitBoard(char arr[100][100],int row,int col,char set)//初始化数组
{
	int j;
	int i;
	for (i = 0; i <= row+1; i++)
	{
		for (j = 0; j <= col+1; j++)
		{
			arr[i][j] = set;
		}
	}
}
void Print(char arr[100][100], int row,int col)
{
	int i,j,m;
	for (m = 0; m <= col; m++)
	{
		printf("%2d ", m);
	}
	printf("\n");
	for (i = 1; i <=row; i++)
	{
		printf("%2d  ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c  ", arr[i][j]);
		}
		printf("\n");
	}
}
void Creat(char arr[100][100], int row, int col,int num)
{
	srand((unsigned int)time(NULL));
	int count = num;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (arr[x][y] == '*')
		{
			arr[x][y] = '1';
				count--;
		}
	}
}

int Jud(char arr[100][100], int x,int y)
{
	int i, m, n,num=0;
	for (i = y - 1; i <= y + 1; i++)
	{
		if (arr[x - 1][i] == '1')
		{
			num++;
		}
	}
	for (m = y-1; m <= y + 1; m++)
	{
		if (arr[x][m] == '1')
		{
			num++;
		}
	}
	for (n = y - 1; n <= y + 1; n++)
	{
		if (arr[x+1][n] == '1')
		{
			num++;
		}
	}
	return num;
}

int Find(char arr[100][100],char ch[100][100], int row, int col)
{
	int x, y;
	scanf("%d,%d", &x, &y);

	if (arr[x][y] == '1')
	{
		printf("你被炸死了\n");
		return 0;
	}
	else if (arr[x][y] == '*')
	{
		ch[x][y] =Jud(arr,x,y)+'0';
		return 1;
	}
	else
		printf("格式错误,请重新填写:\n");
	return 2;
}

test.c

#include"game.h"
void game(int t)
{
	int count = 0;
	int i,j;
	char show[100][100] = { '0'};
	char mine[100][100] = { '0'};
	int row=0,col=0,num=0;
	if (t == 1)
	{
		row = 3;
		col = 3;
		num = 2;
	}
	else if (t == 2)
	{
		row = 9;
		col = 9;
		num = 10;
	}
	else if (t == 3)
	{
		row = 16;
		col = 16;
		num = 40;
	}
	InitBoard(mine, row, col, '*');
	InitBoard(show, row, col, '*');
	Creat(mine, row, col, num);
	Print(show, row, col);
	/*Print(mine, row, col);*/
	//print(show, row, col);
	printf("请输入扫雷坐标:");
	while (Find(mine,show, row, col))
	{
		
		Print(show, row, col);
		count++;
			if (count == row * col - num)
			{
				printf("恭喜你,扫雷成功!!!\n");
				break;
			}
			printf("请输入扫雷坐标:");
	}
}
int menu()
{
	int t;
	Sleep(1000);
	printf("****************************************\n");
	Sleep(1000);
	printf("****************************************\n");
	Sleep(1000);
	printf("****************************************\n");
	Sleep(1000);
	printf("****************游戏开始****************\n");
	Sleep(1000);
	printf("****************************************\n");
	Sleep(1000);
	printf("****************************************\n");
	Sleep(1000);
	printf("****************************************\n");
	printf("请选择你想要的难度:\n");
	printf("1.简单:3*3,雷*2\n");
	printf("2.普通:9*9,雷*10\n");
	printf("3.困难:16*16,雷*40\n");
	scanf("%d", &t);
	return t;
}
int main()
{
	int t;
	int w = 1;
	while (w)
	{
		game(menu());
		printf("输入'0'退出游戏,输入'1'继续游戏:\n");
		scanf("%d", &w);
	}
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值