详解c语言,扫雷游戏,第一次死不了,可展开非雷区

用C语言实现扫雷游戏

话不多说先看效果;

代码:小小少年的GitHub

那么要实现这个游戏有下面几步:

分析

我们先列个表:1.要创建数组存放信息,一个是user显示给玩家,一个是mine存放雷。

                         2.初始化,打印雷盘;雷盘(mine)全初始化为‘0’,玩家全为‘*’

                         3.放雷:要往数组里随机放雷(字符‘1’),非雷则放(字符‘0’)。(到下面解释为什么

                         4.找雷:输入坐标,4.1  统计周围8个位置的雷的个数,并显示雷的个数

                                                         4.2  没有雷的话就展开非雷区

                                                         4.3  有雷的话就炸死了。

                                                         4.4  第一次不会被炸死。

1.创建数组            

void game() 
{
	char mine[ROWS][COLS] = {0};    //创建数组用来存雷
	char user[ROWS][COLS] = {0};    //用来存放雷的个数并显示给玩家
	init(mine, '0', ROWS, COLS);    //初始化雷盘
	init(user, '*', ROWS, COLS);    //初始化显示盘
	Display(user, ROW, COL);        //显示函数用来打印 数组(mine ,user)
	place_mine(mine,ROWS,COLS,MINE_NUM); //放置雷
	fine_mine(mine, user, ROWS, COLS);   //输入坐标找雷
}

2.初始化数组

void init(char arr[ROWS][COLS],char target,int rows,int cols) 
{
	memset(arr,target,rows*cols*sizeof(arr[0][0]));
}

 将数组arr全部初始化为target(是传入的字符)

 

3.放置雷

在数组mine中放置mine_num个雷

void place_mine(char mine[ROWS][COLS],int rows,int cols,int mine_num) 
{
	int n, m;
	while (mine_num) 
	{
		n = rand() % 9 + 1;
		m = rand() % 9 + 1;
		if (mine[n][m] != '1')
		{
			mine[n][m] = '1';
			mine_num--;
		}
	}
}

4.寻找雷

函数参数需要 mine[ROWS][COLS],user[ROWS][COLS],rows,cols,判断玩家输入的坐标(x,y),的位置是否有雷

如果是第一次输入有雷的话,就将雷移到没有 雷的位置,保证第一次不死。没有雷的话就展开非雷区

void fine_mine(char mine[ROWS][COLS],char user[ROWS][COLS],int rows,int cols)
{
	int x, y;
	int ret;
	while(1) 
	{
		int count = 1;
		printf("请输入座标:>");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= rows - 2 && y >= 1 && y <= cols - 2)
		{
			if (mine[x][y] == '1')
			{
				if (count == 1) 
				{
					mine[x][y] = '0';
					while (1)
					{
						int n; int m;
						n = rand() % 9 + 1;
						m = rand() % 9 + 1;
						if (mine[n][m] != '1')
						{
							mine[n][m] = '1';
							break;
						}
					}
					open_to_mine(mine, user, x, y);
				}
				else 
				{
					printf("很遗憾你被炸死乐!!!!!!!!!!!!\n");
					break;
				}
			}
			else
			{
				open_to_mine(mine,user, x, y);
			}
		}
		Display(user, ROW, COL);
	}
}

5.坐标周围雷的个数

注意:我们解释上面将雷为‘1’,非雷为‘0’,而不是其他:要统计(x,y)坐标周围的雷的个数,就可以像下面这样将周围的字符相加  减去  8*‘0’  既是雷的个数

int is_mine(char mine[ROWS][COLS], int x, int y)
{
	if(x>=1&&x<=ROW&&y>=1&&y<=COL)
	{   return  mine[x - 1][y] + mine[x - 1][y - 1] +
		mine[x][y - 1] + mine[x + 1][y - 1] +
		mine[x + 1][y] + mine[x + 1][y + 1] +
		mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0';
    }
}

6.展开非雷区

效果:

从上图中我们可以看出,如果没雷的话,就将这块非雷区,一直展开,直到格子周围有雷,并将雷数显示出来。再看下面分析:

 

 

红色为输入坐标,周围没雷,就以周围8个格子分别为中心(可假设为输入坐标)向外展开,就是分别计算8个格子他们周围的雷数,有雷就写上雷的个数(就是黄色的框)并停止向外展开,否则继续展开。

在这里我们使用递归的思想:1.停止条件:格子周围有雷

                                               2.不断展开,不断接近条件

代码:

int open_to_mine(char mine[ROWS][COLS], char user[ROWS][COLS],static int x,static int y)
{
	if (x >= 1 && x <= ROW&&y >= 1 && y <= COL&&user[x][y]=='*') {
		if (is_mine(mine, x, y)!=0)
		{
			user[x][y] = is_mine(mine,x, y) + '0';
		}
		else
		{
			user[x][y] = ' ';
			open_to_mine(mine, user, x - 1, y);
			open_to_mine(mine, user, x - 1, y-1);
			open_to_mine(mine, user, x , y-1);
			open_to_mine(mine, user, x +1, y-1);
			open_to_mine(mine, user, x +1, y);
			open_to_mine(mine, user, x +1, y+1);
			open_to_mine(mine, user, x , y+1);
			open_to_mine(mine, user, x - 1, y+1);
		}
	}
}

my_main.c我的主函数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "game.h"
void menu() 
{
	printf("*******************\n");
	printf("****1.开始游戏*****\n");
	printf("****0.结束游戏*****\n");
	printf("*******************\n");
}
void test() 
{
	int n;
	do 
	{
		menu();
		printf("请输入你的选择:>");
		scanf("%d", &n);
		switch (n)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏!");
			break;
		default:
			printf("输入有误!");
		}
	} while (n);
}
int main() 
{
	srand((unsigned)time(NULL));
	test();
	system("pause");
	return 0;

}

总结:

                    游戏的基本功能,到这算是实现了,但还没完,随着进一步的学习将会不断完善,大家可以一直关注,或者有问题可在下方评论。

------------------------------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值