扫雷小游戏

前言:经过前面的学习,我们可以写一些比较简单点的程序了,比如扫雷

首先我们要先设计扫雷游戏的结构:

1、游戏的界面

(1)用户界面

(2)用户选择

2、游戏逻辑的实现

(1)存储雷的信息

(2)布置雷

(3)显示游戏界面

(4)排查雷

3、游戏结束

总体来说就这三个步骤

一、游戏的界面:

也就是游戏菜单

如下图:

供用户选择的界面

代码如下:

void menu()//显示菜单
{
	printf("**************************\n");
	printf("*****     1. play    *****\n");
	printf("*****     0. exit    *****\n");
	printf("**************************\n");
}

然后就是用户选择:

void test()//
{
	int input = 0;
	do
	{
		menu();
		printf("请输入:");
		scanf("%d", &input);

		switch (input)
		{
		case 0:
			printf("退出游戏\n");
			break;
		case 1:
			game();//如果用户选择的是1就开始游戏,调用game函数
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
}

这个函数的作用就是让用户选择是开始游戏还是退出游戏。

二、游戏的内容:

我们要想实现这个扫雷游戏,就要先了解他的结构

就拿网页版的扫雷游戏来说:

他是一个9*9的一个结构 ,但是扫雷游戏的规则是:

以输入坐标为中心,输入坐标显示的是周围黄色方框的雷的个数和,所以当我们输入最边上坐标时,他就会越界访问,所以我们要避免越界访问就需要扩大数组。

2.1 数组的创建

那么我们就需要一个11*11的数组,里面的9*9数组用于存储需要排查雷的信息,外面的那一层

是为了防止越界访问。当然外面的那层是不放任何数据的,只用初始化就行了。

#define ROW 9

#define COL 9

#define ROWS ROW + 2

#define COLS COL + 2

这里我是先宏定义了ROW和COL为9,后面方便修改

下面是数组创建的代码:

char mine[ROWS][COLS] = { 0 };//创建扫雷信息的数组
char show[ROWS][COLS] = { 0 };//创建显示需要排查雷的数组

我们这里创建了两个数组,一个是用于存放雷的信息,一个是用于显示给用户看

2.2 数组的初始化

我们需要先初始化上面的两个数组,便于存放雷的信息

void Board(char arr[ROWS][COLS], int rows, int cols,char set)//初始化棋盘的函数
{
	for (int i = 0;i < rows;i++)
	{
		for (int j = 0;j < cols;j++)
		{
			arr[i][j] = set;
		}
	}
}

我们这里只创建了一个初始化函数,当我们需要调用的时候把实参改一下就行了,不然容易代码冗余。

2.3 雷的布置

当然我们初始化好数组之后就该布置雷了

void Setmine(char mine[ROWS][COLS],int row,int col)//布置雷的函数
{
	int l = lei;//在此之前我是先宏定义了#define lei 10的所以这里直接给l赋lei的值
	while(l)
	{
		int x = rand() % row + 1;//使用随机数生成随机坐标
		int y = rand() % col + 1;//同上一样的道理
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			l--;//布置好了一个雷之后就,需要布置雷的个数就减一
		}
		
	}
}

我们定义字符‘1’为雷,直到布置完10个雷为止

当然我们使用了rand()函数就需要srand

所以要在test函数里面加上srand函数例如:

void test()
{
	int input = 0;
	 srand((unsigned int)time(NULL));//随机数种子
	do
	{
		menu();
		printf("请输入:");
		scanf("%d", &input);

		switch (input)
		{
		case 0:
			printf("退出游戏\n");
			break;
		case 1:
			game();
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
}

还需要引用头文件#include<stdlib.h>

2.4 显示棋盘

我们需要把需要排查雷的界面显示给用户看

void Display(char show[ROWS][COLS],int row,int col)//棋盘显示函数
{
	printf(" ------扫雷游戏------\n");//为了看起来美观而加上的装饰
	printf("|");
	for (int i = 0;i <= row;i++)
	{
		printf("%d ", i);
	}
	printf("\b|");//装饰
	printf("\n");
	for (int i = 1;i <= row;i++)
	{
		printf("|");//装饰
		printf("%d",i);
		for (int j = 1;j <= col;j++)
		{
			printf("%2c",show[i][j]);//显示需要排查雷的信息
		}
		printf("|");//装饰
		printf("\n");
	}
	printf(" --------------------\n");//装饰

显示结果如下:

当然装饰不唯一,也可以任意发挥。

2.5 排查雷

这也是游戏逻辑的最后一步了,排查雷

void Find(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)游戏逻辑实现的函数
{
	int x = 0, y = 0;
	while(1)//死循环
	{
		printf("请输入你要排查的坐标:");
		scanf("%d %d", &x, &y);
		if ((x == 0 || x > 9) || (y == 0 || y > 9))//如果输入的坐标不符合就会提示
		{
			printf("输入的坐标错误,请重新输入:");
		}
		else
		{
			if (show[x][y] == '*')//如果show[x][y]没有被排查就会执行以下程序
			{
				if (mine[x][y] == '1')//如果是雷,就炸死,退出游戏
				{
					printf("很遗憾,你被炸死了。\n");
					Display(mine, ROW, COL);//调用显示棋盘信息的函数,显示给用户看那些地方有雷
					break;//退出游戏
				}
				else//如果不是雷就会显示周围雷的个数
				{
					system("cls");//这里用了一个清屏函数,在玩游戏的时候能够更直观
					int c = Getmine(mine, x, y);//这是一个统计周围雷的个数的函数
					show[x][y] = c + '0';
					Display(show, ROW, COL);
				}
			}
			else//如果show[x][y]不等于‘*’,就说明这个坐标被排查过了
			{
				printf("该坐标被排查过了\n");
			}
		}
	}
	
}

 这里我们还需要一个统计雷的函数

 int Getmine(char mine[ROWS][COLS], int x, int y)//获取该坐标周围雷的数量
{
	int a = 0;
	for (int i = x - 1;i <= x + 1;i++)//就是一个二维数组的遍历
	{
		for (int j = y - 1;j <= y + 1;j++)
		{
			if(mine[i][j] =='1')//如果mine[i][j]是‘1’的话,就+1
			{
				a++;
			}
		}
	}
	return a;//返回a的值
}

 代码实现:

三、游戏结束

当然我们如果把所有的非雷的坐标排除了之后就会游戏结束

所以我们只需要在Find()函数中稍作修改就可以了

void Find(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)游戏逻辑实现的函数
{
	int x = 0, y = 0;
	int b = 0;//当我们没有排查的时候,排查量为0
	while(b<row*col-lei)//当排查量=需要排查-雷的个数时就退出循环
	{
		printf("请输入你要排查的坐标:");
		scanf("%d %d", &x, &y);
		if ((x == 0 || x > 9) || (y == 0 || y > 9))
		{
			printf("输入的坐标错误,请重新输入:");
		}
		else
		{
			if (show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf("很遗憾,你被炸死了。\n");
					Display(mine, ROW, COL);
					break;
				}
				else
				{
					system("cls");
					int c = Getmine(mine, x, y);
					show[x][y] = c + '0';
					Display(show, ROW, COL);
					b++;//每排查一个坐标,排查量就加1
				}
			}
			else
			{
				printf("该坐标被排查过了\n");
			}
		}
	}
	if (b == row*col- lei)//当排查量=需要排查-雷的个数时游戏结束,玩家胜利
	{
		printf("you win!!!\n");
	}
	
}

整个游戏代码如下

这里我分成三个文件来实现的

这是头文件saolei.h的代码

#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<windows.h>
#define ROW 9

#define COL 9

#define ROWS ROW + 2

#define COLS COL + 2
#define lei 10
#define gezi ROW * COL
void menu();
void Board(char arr[ROWS][COLS], int rows, int cols,char set);
void Display(char arr[ROWS][COLS],int row,int col);
void Setmine(char arr[ROWS][COLS],int row,int col);
void Find(char arr1[ROWS][COLS],char arr2[ROWS][COLS],int row,int col);

saolei.c

//游戏逻辑的实现


#include"saolei.h"
 
 
void Board(char arr[ROWS][COLS], int rows, int cols,char set)//初始化棋盘的函数
{
	for (int i = 0;i < rows;i++)
	{
		for (int j = 0;j < cols;j++)
		{
			arr[i][j] = set;
		}
	}
}

void Display(char arr[ROWS][COLS],int row,int col)//棋盘显示函数
{
	printf(" ------扫雷游戏------\n");
	printf("|");
	for (int i = 0;i <= row;i++)
	{
		printf("%d ", i);
	}
	printf("\b|");
	printf("\n");
	for (int i = 1;i <= row;i++)
	{
		printf("|");
		printf("%d",i);
		for (int j = 1;j <= col;j++)
		{
			printf("%2c",arr[i][j]);
		}
		printf("|");
		printf("\n");
	}
	printf(" --------------------\n");
}
void Setmine(char mine[ROWS][COLS],int row,int col)//布置雷的函数
{
	int l = lei;
	while(l)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			l--;
		}
		
	}
}
int Getmine(char mine[ROWS][COLS], int x, int y)//因为这个函数被static修饰成静态函数了,所以这个函数只能在此文件中调用,获取该坐标周围雷的数量
{
	int a = 0;
	for (int i = x - 1;i <= x + 1;i++)
	{
		for (int j = y - 1;j <= y + 1;j++)
		{
			if(mine[i][j] =='1')
			{
				a++;
			}
		}
	}
	return a;
}

void Find(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//游戏逻辑实现的函数
{
	int x = 0, y = 0;
	int b = 0;
	while(b<row*col-lei)
	{
		printf("请输入你要排查的坐标:");
		scanf("%d %d", &x, &y);
		if ((x == 0 || x > 9) || (y == 0 || y > 9))
		{
			printf("输入的坐标错误,请重新输入:");
		}
		else
		{
			if (show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf("很遗憾,你被炸死了。\n");
					Display(mine, ROW, COL);
					break;
				}
				else
				{
					system("cls");
					int c = Getmine(mine, x, y);
					show[x][y] = c + '0';
					Display(show, ROW, COL);
					b++;
				}
			}
			else
			{
				printf("该坐标被排查过了\n");
			}
		}
	}
	if (b == row*col- lei)
	{
		printf("you win!!!\n");
	}
	
}

 game .c

//游戏的测试


#include "saolei.h"
void game()
{
	char mine[ROWS][COLS] = { 0 };//创建扫雷信息的数组
	char show[ROWS][COLS] = { 0 };//创建显示信息的数组
	Board(mine, ROWS, COLS,'0');//初始化雷信息棋盘
	Board(show, ROWS, COLS, '*');//初始化显示信息棋盘
	//布置雷
	
	Setmine(mine,ROW,COL);//布置雷
	Display(show, ROW, COL);//显示棋盘
	Find(mine,show,ROW,COL);//查找雷
}
void menu()//显示菜单
{
	printf("**************************\n");
	printf("*****     1. play    *****\n");
	printf("*****     0. exit    *****\n");
	printf("**************************\n");
}
void test()//
{
	int input = 0;
	 srand((unsigned int)time(NULL));//随机数种子
	do
	{
		menu();
		printf("请输入:");
		scanf("%d", &input);

		switch (input)
		{
		case 0:
			printf("退出游戏\n");
			break;
		case 1:
			game();
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
}


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

总结:

总体来说这个扫雷小游戏分为几小步:

1、显示菜单界面

2、用户选择

3、创建数组方便存储信息

4、初始化数组

5、布置雷

6、显示需要排查雷的数组

7、开始游戏,输入需要排查的坐标(需要判断输入的坐标是否有效,是否重复)

8、判断该坐标是否是雷,如果不是,统计该坐标周围雷的个数,再显示。如果是,就结束游戏。

9、如果把所有非雷的坐标都排查完了,游戏结束,玩家胜利

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值