C语言实现扫雷代码

一、game.c代码

1、面板初始化
#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

void Ib(char b[ROWS][COLS], int rows, int cols,char set);

void Ib(char b[ROWS][COLS], int rows, int cols,char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			b[i][j] = set;//分为两种,空心面板传入‘0’,实心面板传入‘*’
		}
	}
}

那么就该这样调用函数时:

Ib(b, ROWS, COLS,'0');//初始化空心面板
Ib(s, ROWS, COLS,'*');//初始化实心面板
 2、布置雷代码
#define EASY 10

void Com(char b[ROWS][COLS], int row, int col)
{
	int count = EASY;
	while (count)
	{
		int x = rand() % row + 1; //0(+1)---8(+1)
		int y = rand() % col + 1;//设置随机产生的雷,布置在二维数组的1-9的范围内
		if (b[x][y] == '0')
		{
			b[x][y] = '1';
			count--;//当布置10个雷之后,跳出循环
		}
	}
}
3、展示面板代码
void Db(char b[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("***********扫雷游戏**********\n");
	for (j = 0; j <= col; j++)//列号
		printf(" %d ", j);
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf(" %d ", i);//行号
		for (j = 1; j <= col; j++)
			printf(" %c ", b[i][j]);
		printf("\n");
	}
}
4、计算雷的个数代码
int get_count(char b[ROWS][COLS], int x, int y)
{
	return (b[x - 1][y] +
		    b[x - 1][y - 1] +
		    b[x - 1][y + 1] +
		    b[x][y - 1] +
		    b[x][y + 1] +
		    b[x + 1][y - 1] +
		    b[x + 1][y] +
		    b[x + 1][y + 1] - 8 * '0'); //将排查点一圈其他八个点的值相加
}
5、递归扩散空白格代码
void spread(char b[ROWS][COLS], char s[ROWS][COLS], int x, int y)
{
	int count = get_count(b, x, y);//统计排查点周围有几个雷
	if (count == 0)//排查的点周围无雷
	{
		s[x][y] = ' '; //若周围无雷将'*'改为' '
		int i = 0;
		int j = 0;
		for (i = -1; i <= 1; i++)
		{
			for (j = -1; j <= 1; j++)
				//将扩散的范围控制在1-9的范围,在该范围内,以排查的点(周围无雷)为中心向外扩散
				if ((x + i > 0) && (y + j > 0) && (x + i < ROWS) && (y + j < COLS) && s[x + i][y + j] == '*') 
					spread(b, s, x + i, y + j);//递归此函数,一圈一圈排查
        }
	}
	else //直到扩散到周围有雷的点停止,并将停止的点周围有几颗雷显示出来
		s[x][y] = count + '0';//将字符转换为数字显示周围几颗雷
}
6.排查雷和标记雷的代码
void Search(char b[ROWS][COLS], char s[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;//排查或标记的坐标
	int flag = EASY;//统计标记的变量,一共只有10次标记机会
	int ret = 0;//用于判断是否成功标记到雷的变量,与10比较
	int input = 0;//选择模式
	//int error = 0;//标记错误点的个数,若ret不为10,则error = 10-ret
again:
	printf("请输入要选择的模式(tip:1.排查模式;2.标记模式 特殊坐标:20,20(输入可重新选择模式)):>");
	scanf_s("%d",&input);
	switch (input)
	{
	case 1:
		while (1)
		{
			printf("请输入要排查的坐标:>");
			scanf_s("%d%d", &x, &y);
			if (x >= 1 && x <= row && y >= 1 && y <= col)
			{
				if (s[x][y] != '*')
				{
					printf("该坐标被排查过了,不能重复排查\n");
				}
				if (b[x][y] == '1')
				{
					printf("很遗憾,你被炸死了\n");
					Db(b, ROW, COL);
					break;
				}
				else//如果不是雷,统计周围有几个雷,周围八个坐标
				{
					spread(b,s, x, y);
					Db(s, ROW, COL);
				}
			}
			else if (x == 20 && y == 20)
			{
				goto again;//跳转到选择模式那一步
			}
			else
			{
				printf("输入坐标非法,重新输入");
			}
		}
		break;
	case 2:
		while (1)
		{
			printf("请输入要标记的坐标:>");
			scanf_s("%d%d", &x, &y);
			if (x >= 1 && x <= row && y >= 1 && y <= col && s[x][y] == '*')
			{
				ret += get_value(b, x, y);
				s[x][y] = '?';//标记后显示符号?
				flag--;//标记次数-1
				Db(s, ROW, COL);
				//printf("%d\n", ret);
				if(flag > 0)//只有在未完全标记成功显示,若flag = 0,则表示标记成功,不需在提示该语句
				{
					printf("标记次数剩余:%d\n", flag);
				}
			}
			else if (x >= 1 && x <= row && y >= 1 && y <= col && s[x][y] == '?')//当标记错误后,可取消标记,并返回标记的次数
			{
				s[x][y] = '*';
				if(b[x][y] == '1')
				{
					ret = ret - 1;
				}
				flag += 1;
				Db(s, ROW, COL);
				//printf("%d\n", ret);
				printf("标记次数剩余:%d\n", flag);
			}
			else if (x >= 1 && x <= row && y >= 1 && y <= col && s[x][y] != '?' && s[x][y] != '*')
			{
				printf("该坐标不可被标记,请重新输入标记坐标\n");//标记在' '或者数字上,显然是错误的
			}
			if (flag == 0)//标记十次后进行判断
			{
				if (ret == 10)
				{
					printf("恭喜你排雷全部正确,游戏胜利!\n");
					break;
				}
				else
				{
					printf("所标记的点不全为雷,请重新检查\n");
				}
			}
			if (x == 20 && y == 20)
			{
				goto again;
			}
		}
		break;
	default:
		printf("输入有误,重新输入\n");
		break;
	}
}

其中还有一个小方法:

int get_value(char b[ROWS][COLS], int x, int y) 
//为统计标记过的点是否为雷,若标记十个点后,进行判断,为10则成功,否则有错误
{
	if (b[x][y] == '1')
		return 1; //标记对雷则+1
	else
		return 0;
}

 二、game.h代码

#ifndef __GAME_H__
#define __GAME_H__

//将每个文件所用到的头文件都放入该头文件中,其他文件引入game.h头文件即可
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

//不同难度雷的数量
#define EASY 10
#define MID 20
#define EXPERT 30
#define MASTER 50

void Ib(char b[ROWS][COLS], int rows, int cols,char set); //初始化面板函数原型
void Db(char b[ROWS][COLS], int row, int col); //展示面板函数原型
void Com(char b[ROWS][COLS], int row, int col); //布置雷函数原型
void Search(char b[ROWS][COLS], char s[ROWS][COLS], int row, int col); //排查、标记雷函数原型
#endif

三、主函数main代码

#include "game.h"

void menu()
{
	printf("***********************************\n");
	printf("************   1.play   ***********\n");
	printf("************   0.quit   ***********\n");
	printf("***********************************\n");
}
void game()
{
	char b[ROWS][COLS] = {0}; //存放布置好的雷的信息
	char s[ROWS][COLS] = {0};//存放排查出的雷的信息
	Ib(b, ROWS, COLS,'0');//初始化布置
	Ib(s, ROWS, COLS,'*');//初始化排查
	//设置雷
	Com(b, ROW, COL);//随机分配10个雷
	Db(s, ROW, COL);//展示排雷页面
	//Db(b, ROW, COL);//展示布雷页面  用户不可以看到这个页面
	//排查雷
	Search(b,s,ROW,COL);//进行排查和标记动作方法
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//以时间戳做随机数的来源
	do
	{
		printf("扫雷游戏\n");
		menu();//游戏菜单
		printf("请选择:>");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			game();/ /游戏具体实现流程函数
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值