扫雷简易版与进阶版


一.简单的思路分析

在9*9的矩阵中,随机布置10个(或自定义个)炸弹,由玩家输入坐标进行扫雷,如果该坐标没雷,并且该坐标八方皆没有雷,那么我们就对该坐标进行展开,并继续判断该坐标的八方是否有雷。若该坐标没雷,但八方有雷,我们就在棋盘上提示玩家该坐标附近有几颗雷。玩家可以对认为有雷的坐标进行标记,若标记满10个,则可以提示程序判断输赢,若标记的坐标都有雷,则胜利;若标记的坐标有不存在雷的,则失败;

二.代码实现

1.制作菜单

先制作一个菜单,供玩家进行游戏的选择
若玩家选择play则进入game()函数进行游戏

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

void Test()
{
   
	int input = 0;//选择
	do
	{
   
		menu();
		printf("请选择>\n");//提示玩家选择
		scanf("%d",&input);
		switch(input)
		{
   
		case 1:
			game();//实现扫雷游戏
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择有误,请重新选择\n");
			break;
		}		
	}while(input);

}

int main()
{
   
	Test();//三子棋游戏测试
	
	return 0;
}

2.初始化扫雷棋盘

我们需要创建两个二维数组来进行操作。一个(mine)用来存放雷,用0表示无雷,1表示雷,游戏过程中不展示给玩家;另一个(show)用来让玩家进行扫雷,初始时用*覆盖
创建两个数组时行和列都得是11,这方便我们后面在进行展开及判断周围雷的数目时的函数运算;

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
void BoardInit(char board[ROWS][COLS],int rows,int cols,char set)
//形参分别为二维数组,行,列,初始化需要设置的字符
{
   
	int i = 0;//行
	int j = 0;//列
	for(i=0;i<rows;i++)
	{
   
		for(j=0;j<cols;j++)
		{
   
			board[i][j] = set;
		}
	}
}

3.打印扫雷棋盘

我们创建的二维数组是11*11的,但是实际上我们需要展示给玩家的棋盘只有9 * 9;所以我们打印时需要省略掉最外围(上下左右各一行/列)的行和列

void BoardPrint(char board[ROWS][COLS],int row,int col)
{
   
	int i = 0;
	int j = 0;
	printf("----------扫雷游戏-----------\n");
	for(i=0;i<=row;i++)
	{
   
		printf("%d ",i);//提示玩家坐标列数
	}
	printf("\n");
	for(i=1;i<=row;i++)
	{
   
		printf("%d ",i);//提示玩家坐标行数
		for(j=1;j<=col;j++)
		{
   
			printf("%c ",board[i][j]);
		}
		printf("\n");//每隔一行就换行
	}
	printf("----------扫雷游戏-----------\n");
}

4.设置雷

雷的位置是随机的,所以我们需要用到rand(),srand(),time()函数。
设置的雷存放在mine数组中
设置雷的数量

#define EAZY_COUT 10
void BoardSet(char mine[ROWS][COLS],int row,int col)//只需要将雷存放在玩家所能看到的9*9棋盘中便可
{
   
	int cout = EAZY_COUT;
	while(cout)
	{
   
		int x = rand() % row + 1;//炸弹坐标从 1 -> 9
		int y = rand() % col + 1;
		if(mine[x][y] == '0')//避免在相同坐标下设置雷
		{
   
		mine[x][y] = '1';//用1表示炸弹
		cout--;
		}
	}
}

5.玩家排雷 && 判断输赢

玩家输入排雷坐标,若该坐标有雷,则游戏结束;若该坐标无雷,则判断该坐标八方的雷的个数并将其输入到棋盘上提醒玩家;
如果没有被炸死,那么在排完一次雷后,我们就对是否胜利进行判断,如果排满除了有炸弹的坐标外,就算胜利

void BoardFind(char mine[ROWS][COLS],char show[ROWS][COLS])//排雷过程
{
   
	int x = 0;
	int y = 0;
	int cout = 0;//已排查过的坐标个数
	int win_ret = 0;//用来接收是否胜利的返回值
	while(1)
	{
   
		printf("请输入要排雷的坐标\n");
		scanf("%d %d",&x,&y);
		if(x >= 1 && x <= 9 && y >= 1 && y <= 9)
		{
   
			if(mine[x][y] == '1')
			{
   
				printf("很遗憾你被炸死了\n");
				break;
			}
			else
			{
   
				int ret = ShowThunder(mine,x,y) + '0';//将数字转变为对应的字符
				show[x][y] = ret;
				system("cls");//每扫一次雷进行一次清屏
				cout++;//每次排雷让排查的坐标个数加1
				win_ret = is_win(cout,ROW,COL);
			}
		}
		else
		{
   
			printf("输入坐标无效,请重新输入\n");
		}

		if(win_ret)
		{
   
			printf("恭喜你,扫雷成功\n");
			break;
		}
	}
}

int ShowThunder(char mine[ROWS][COLS],int x,int y)//检测八方的雷的个数
{
   
	int i = 0;
	int j = 0;
	int sum = 0;
	for(i=-1;i<=1;i++)
	{
   
		for(j=-1;j<=1;j++)
		{
   
			if(j == 0 && i == 0)
			{
   
				continue;
			}
			else
			{
   
				sum += mine[x+i][y+j];//将除原本坐标外的八个方向的字符对应的ASCII码加起来
			}
		}
	}
	return sum - 8 * '0';//'1' - '0' == 1,若有8个雷则返回8;返回存在的雷的个数
}

int is_win(int cout,int row,int col)
{
   
	int ret = row * col;
	if(cout == ret - EAZY_COUT)
	{
   
		return 1;
	}
	return 0;
}

6.初阶完整代码

test.c

#define _CRT_SECURE_NO_WARNINGS 
#include"game.h"


void game()
{
   
	char mine[ROWS][COLS] = {
    0 };//用来存放雷的 --> 0表示无雷,雷用1表示
	char show[ROWS][COLS] = {
    0 };//显示给玩家看的

	BoardInit(mine, ROWS, COLS, '0');//全部初始化为0,表示无雷
	BoardInit(show, ROWS, COLS, '*');
	system("cls");
	BoardPrint(show, ROW, COL);
	BoardSet(mine,<
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值