扫雷--包含空白格展开的详细内容

目录

1.分析与思路
2.头文件说明
3.主函数
4.分支函数的各个功能
5.全部代码

1. 分析与思路:

                                                          通过Windows的小游戏扫雷   通过玩这个小游戏,我们不难发现这是一个由二维数组组成的棋盘和一些功能函数组成,所以我们就要先从棋盘做起,再写多个功能函数,
  那么第一步就是棋盘的构造,通过观察可得到是两个二维数组,第一个二维数组是棋盘第一层空白格,第二个二维数组就是第二层的雷与安全格 ,第二步就是各种功能函数,优先到后的顺序便是布置雷,输入坐标查找雷,以及不是雷的格子周围雷的数量(为了接近原型,这里在展开空白格这里加一个递归函数),为了方便后续的观看,分多文件的形式来编写代码

2.头文件说明:

#include<stdio.h>
//这个是c语言中输入输出函数的头文件

#include<stdlib.h>
//这个头文件是生成随机数中的rand的头文件,以及srand随机生成的种子的头文件
//srand生成的种子并不是真正意义上的随机,所以要用time(NULL)来做到随机

#include<time.h>
//调用函数time()生成时间戳,来实现srand生成种子的随机

#include<Windows.h>
//调用system()函数,来实现清屏
#define ROW 9  //定义棋盘宽9行
#define COL 9  //定义棋盘长9列
#define ROWS ROW+2 //定义二维数组的行
#define COLS COL+2 //定义二维数组的列

void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set);
//在头文件中,声明创建的棋盘函数
void Display(char arr[ROWS][COLS],int row,int col);
//在头文件中,声明显示棋盘的函数
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);
//在头文件中,声明查找地雷的函数
void SetMine(char arr[ROWS][COLS], int row, int col);
//在头文件中,声明布置地雷的函数
int Xianshi(char mine[ROWS][COLS], int x, int y);
//在头文件中,声明判断空白格周围雷的个数函数
void DiGui(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int row, int col);
//在头文件中,声明展开空白格的函数

这是创建game.h文件中的头文件,以及每一个头文件对应的意义与作用,当然想实现更多作用,可以调用更多的函数,后面又定义的全局变量数组的行列长度,后面主函数所用到的功能函数在头文件中声明了一次,以便后面调用的时候不用再声明。

3.主函数

  这个扫雷的主函数还是比较简单的,通俗易懂的,先看代码

#include"mine.h"

void menu()    //设置了一个最开始的菜单函数
{
	printf("********************\n");
	printf("****** 1. play *****\n");
	printf("****** 2. exit *****\n");
	printf("********************\n");
}              //打印所需要的开局选项和菜单

void game()    //扫雷最重要的游戏函数,同时包含了这个游戏的功能函数
{
	char mine[ROWS][ROWS];   //定义了第一个二维数组,是后台放雷的棋盘
	char show[COLS][COLS];   //定义第二个二维数组,是展示页面空白格
	InitBoard(mine, ROWS, COLS, '0');//初始化雷盘
	InitBoard(show, ROWS, COLS, '*');//初始化展示棋盘
	Display(show, ROW, COL);//显示棋盘
	SetMine(mine, ROW, COL);//布雷
	FindMine(mine, show, ROW, COL);//查找雷
}

	int main()
{
	srand((unsigned int)time(NULL));
//为布置雷生成随机位置,调用了time()函数利用空指针来实现srand生成随机雷的位置
	int a = 0;
	do
	{
		menu();    //调用菜单函数
		printf("输入你的选择:");
		scanf("%d", &a); //输入选择的选项
		switch (a)   //通过输入的选项来判断后续运行
		{
		case 1:
			game();  //调用游戏函数,正式进入游戏
				break;
		case 2:
			printf("退出游戏");
				break;
		default:
			printf("输入错误重新开始\n");
				break;
		 }
	} while (a != 2);//不是选择退出则一直循环
	return 0;
}

这是扫雷的主函数,各种功能函数已经被调用了,那么接下来就是各个功能性函数的介绍

这是打印的菜单:

4.功能性函数:

    1.创建棋盘,比较简单的循环嵌套来完成二维数组的创建

void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set)
{
	int i;
	for (i = 0; i < rows; i++)   
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = set;   
           //两个for循环定义棋盘,多在函数设一个参数set,可以方便后面改棋盘上字符
		}
	}
}

2.打印棋盘,并在棋盘的行列上标上对印的序号,代码还是比较通俗易懂

void Display(char arr[ROWS][COLS], int row, int col)
{
	int i;
	printf("*********扫雷*********\n");
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);  //在棋盘的行标上序号,方便输入坐标
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		int j = 0;
		printf("%d ", i);   //在棋盘的列标上序号,方便输入坐标
		for (j = 1; j <= col; j++)
		{
			printf("%c ", arr[i][j]);   //打印二维数组的棋盘
		}
		printf("\n");
	}
}

这是代码运行出来打印的棋盘显示

3.布置雷的函数,要用到rand,并且主函数调用time()来实现真正的随机

void SetMine(char arr[ROWS][COLS], int row, int col)//布置雷的函数
{
	int m = 10;      //定义m为雷,并初始化为十个
	while (m)        //当十个雷都布置完,结束循环
	{
		int x = rand() % row + 1;//通过rand生成随机数,来确定雷的横坐标
		int y = rand() % col + 1;//通过rand生成随机数,来确定雷的横坐标
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';       //判断这个位置是否布置过雷
			m--;             //成功布置一个m自减减
		}
	}
}

4.输入坐标查找雷的函数:

利用了函数的嵌套,在查找雷的函数中重新调用了Xianshi()和Digui函数

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int num = 71;
	while (num!=0)  //排除雷后的71个空格被排查完结束循环
	{
		printf("请输入要排雷的坐标");
		scanf("%d %d", &x, &y);    //输入坐标
		if (x >= 1 && x <= row && y >= 1 && y <= col)//如果输入的坐标在棋盘中
		{
			if (mine[x][y] == '1')    //如果输入的坐标为‘1’ 即是雷
			{
				printf("很抱歉你被炸死了\n");
				Display(mine, ROW, COL);   //显示雷的棋盘,也就是答案
				break;
			}
			else          //所查找的坐标不是雷的话
			{
				int n;
				
				 n = Xianshi(mine, x, y);  //调用一个计算周围有多少雷的函数
				show[x][y] = n + '0';  //所查找坐标周围有几个雷就显示数字几
				if (n== 0)
				{
					DiGui(mine, show, x, y, ROW, COL); //调用这个递归函数,来实现展开多空白
				}
				show[x][y] = n + '0';
				Display(show, ROW, COL);//显示棋盘
				num--;
				
			}
		}
		else
			printf("输入错误,重新输入:");

	}
	if (num == 0)  //如果把所有的空格都排查完则胜利
	{
		printf("恭喜你获胜\n");
		Display(mine, ROW, COL);
	}
	
}

5.完成一个计算所排查周围有多少雷的函数,并显示在该坐标

int Xianshi(char mine[ROWS][COLS],int x,int y)
{
	int count;
	 return count = mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x - 1][y] + mine[x + 1][y]+ mine[x][y + 1] + mine[x - 1][y + 1] + mine[x + 1][y + 1] + 8 * '0';
 //定义了一个整型count,把周围八个坐标里的数加起来,因为坐标里边是字符,减0的ASSIC码便变成了整型

}

5.完成一个递归函数,来实现展开大部分空白为零区域

void DiGui(char mine[ROWS][COLS],char show[ROWS][COLS],int x,int y,int row,int col)
{
	int count=Xianshi(mine,x,y);
      show[x][y]=count+'0';  //调用Xianshi()函数,判断所排查的坐标是否为零
 
		if (count!=0)   //不为零则跳出该函数
		{
          return;
		}
    int i;
    int xx[]={1,1,1,-1,-1,-1,0,0};
     int yy[]={1,0,-1,0,1,-1,1,-1};//周围的八个格子的横纵坐标
      for(i=0;i<8;i++)//循环八次来判断是否周围有非零的数
      {  
     int dx =x + xx[i];
    int dy = y+ yy[i];
      if(dx >= 1 && dx <= row && dy >= 1 && dy <= col && mine[dx][dy] == '0' && show[dx][dy]=='*')
      {
        DiGui(mine,show,dx,dy,ROW,COL);//如果满足为零则再次返回Digui函数,进行递归
      }
 
       }
}

5.全部代码

           mine.h文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set);
void Display(char arr[ROWS][COLS],int row,int col);
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);
void SetMine(char arr[ROWS][COLS], int row, int col);
int Xianshi(char mine[ROWS][COLS], int x, int y);
void DiGui(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int row, int col);

           main.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"mine.h"

void menu()
{
	printf("********************\n");
	printf("****** 1. play *****\n");
	printf("****** 2. exit *****\n");
	printf("********************\n");

}
void game()
{
	char mine[ROWS][ROWS];
	char show[COLS][COLS];
	InitBoard(mine, ROWS, COLS, '0');//初始化棋盘
	InitBoard(show, ROWS, COLS, '*');
	Display(show, ROW, COL);//显示棋盘
	SetMine(mine, ROW, COL);//布雷
	FindMine(mine, show, ROW, COL);//查找雷


}

	int main()
{
	srand((unsigned int)time(NULL));
	int a = 0;
	do
	{
		menu();
		printf("输入你的选择:");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			game();
				break;
		case 2:
			printf("退出游戏");
				break;
		default:
			printf("输入错误重新开始\n");
				break;
		}
		} while (a != 2);
	return 0;
}

            game.c函数

#define _CRT_SECURE_NO_WARNINGS 1
#include"mine.h"
void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set)
{
	int i;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = set;
		}
	}
}
void Display(char arr[ROWS][COLS], int row, int col)
{
	int i;
	printf("*********扫雷*********\n");
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		int j = 0;
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}
void SetMine(char arr[ROWS][COLS], int row, int col)
{
	int m = 10;
	while (m)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';
			m--;
		}
	}
}
int Xianshi(char mine[ROWS][COLS],int x,int y)
{
	int count;
	 return count = mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x - 1][y] + mine[x + 1][y]
		+ mine[x][y + 1] + mine[x - 1][y + 1] + mine[x + 1][y + 1] + 8 * '0';

}
void DiGui(char mine[ROWS][COLS],char show[ROWS][COLS],int x,int y,int row,int col)
{
	int count=Xianshi(mine,x,y);
      show[x][y]=count+'0';
 
		if (count!=0)
		{
          return;
		}
    int i;
    int xx[]={1,1,1,-1,-1,-1,0,0};
     int yy[]={1,0,-1,0,1,-1,1,-1};
      for(i=0;i<8;i++)
      {  
     int dx =x + xx[i];
    int dy = y+ yy[i];
      if(dx >= 1 && dx <= row && dy >= 1 && dy <= col && mine[dx][dy] == '0' && show[dx][dy]=='*')
      {
        DiGui(mine,show,dx,dy,ROW,COL);
      }
 
       }
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int num = 71;
	while (num!=0)
	{
		printf("请输入要排雷的坐标");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("很抱歉你被炸死了\n");
				Display(mine, ROW, COL);
				break;
			}
			else  
			{
				int n;
				
				 n = Xianshi(mine, x, y);
				show[x][y] = n + '0';
				if (n== 0)
				{
					DiGui(mine, show, x, y, ROW, COL);
				}
				show[x][y] = n + '0';
				Display(show, ROW, COL);//显示棋盘
				num--;
				
			}
		}
		else
			printf("输入错误,重新输入:");

	}
	if (num == 0)
	{
		printf("恭喜你获胜\n");
		Display(mine, ROW, COL);
	}
	
}
6.输出结果:结果比较繁琐,所以只截取了一部分结果,感兴趣的小i伙伴可以下去玩一下

感谢小伙伴们的浏览,喜欢的可以点赞三连哦!!!

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值