2.C语言扫雷游戏(下)

C语言扫雷游戏(下)

整个工程的框架出来之后,这篇文章来对实现整个流程进行实现。

游戏的整体逻辑

一、游戏正式开始前的准备工作:打印一个菜单——menu函数,并且让玩家顺利进入游戏

1.展示一个游戏最初始的界面
菜单函数代码
菜单界面

2.用switch语句来服务用户的选择再合适不过

主函数的具体代码实现
到此为止,我们就可以安心去设计game()函数的内容了

二、执行游戏的步骤

1.先初始化两个棋盘,包括mine棋盘(用于布置雷)和show棋盘(用于展示给玩家看)

2.把show棋盘打印在屏幕上供玩家进行操作

3.在mine数组里面布置雷

4.玩家扫雷

由此不难看出游戏执行需要四个关键的函数
(1)初始化棋盘的函数:

`void InitializeBoard(char board[ROWS][COLS], int rows, int cols, char set) 

(2)打印棋盘的函数:

void DisplayBoard(char arr[ROWS][COLS],int row,int col)

(3)布置雷的函数:

void SetMine(char arr[ROWS][COLS],int row,int col)

(4)玩家进行扫雷操作的函数:

void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS])

下面对这四个函数进行逐一分析设计

三、game()内部设计,实现整个游戏的功能

1.初始化棋盘

(1)逻辑:用两重for循环遍历二维数组mine的所有元素,全部初始化为‘0’;同理遍历show数组的是所有元素,全部初始化为‘*’。
(2)具体代码实现

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

2.布置雷

(1)逻辑:我们的目的是在ROW行,COL列的数组当中布置雷。那么rand()%ROW+1就可以产生1~ROW的数字,rand()%COL+1就可以产生1-COL的数字,这两个数字一组合就是一个随机的坐标值,判断一下是不是‘0’,如果是的话就可以初始化为1,雷就布置下去了。
(2)此外,还有必要设置雷的个数,每布置一个雷这个数字就减1,直到布置完为止,这里采用count来接收雷的个数。
(3)在头文件中可以定义雷的个数如:#define EASY_COUNT 10//布置雷的时候计数用的,此处表示雷的个数是10(可任意修改)
(4)具体代码实现

//布置雷:生成十个随机的坐标,布置十个雷
void SetMine(char arr[ROWS][COLS],int row,int col)
{
	int count = EASY_COUNT;
	int x = ROW;
	int y = COL;
	while (count)
	{
		int x = rand() % ROW + 1;
		int y = rand() % COL + 1;
		if (arr[x][y] = '0')
		{
			arr[x][y] = '1';//布置一个雷
			count--;
		}
	}
}

3.打印棋盘

(1)逻辑:与初始化棋盘的函数相似,用两重循环遍历整个数组即可,注意换行符的处理,美观起见可以先打印行号和列号。
(2)具体代码实现

//打印棋盘
void DisplayBoard(char arr[ROWS][COLS],int row,int col)
{
	int i = 0;
	int j = 0;
	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 ", arr[i][j]);
		}
		printf("\n");
	}
}

4.玩家扫雷

(1)逻辑:玩家输入的坐标有三种可能性:踩雷(mine里面的数字1);没踩雷(mine里面的数字0);坐标错误(不符合ROW行,COL列),分别对这三种情况进行处理即可。先对玩家输入坐标的合法性进行判断,合理则进入第1,2种情况,不合理则进入第3种情况
(2)踩雷/没踩雷:判断mine[x][y]是否等于‘1’,如果是的话就踩雷,不是的话就没踩雷
(3)坐标错误:让玩家重新输入
(4)具体代码实现

//辅助排查雷函数FindMind,统计周围雷的个数
int GetMineCount(char mine[ROWS][COLS],int x,int y)
{
	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');
}
//排查雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS])
{
	int x = 0;
	int y = 0;
	int win = 0;//记录玩家排查掉的无雷格子个数
	while (win < ROW * COL - EASY_COUNT)//ROW*COL-EASY_COUNT是无雷格子的个数
	{
		printf("请输入要排查的坐标(行,列)(只用输入两个数字,中间用空格隔开):");
		scanf("%d %d", &x, &y);
		if ((x >= 1 && x <= ROW) && (y >= 1 && y <= COL))//判断坐标的有效性
		{
			if (mine[x][y] == '1')//踩雷
			{
				printf("很遗憾,你被炸死了\n");
				printf("请看雷都在哪里?0表示没有雷,1表示有雷\n");
				DisplayBoard(mine, ROW, COL);//让玩家看一下雷都在哪里
				break;
			}
			else//没踩雷,统计雷的个数
			{
				int count = GetMineCount(mine, x, y);//统计该点周围8个格子当中雷的个数
				show[x][y] = count + '0';//把int数字转为字符:int= char+'0'
				system("cls");//清理屏幕
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标输入错误,请重新输入");
		}
	}
	if (win == ROW * COL - EASY_COUNT)
	{
		printf("恭喜你!排雷成功\n");
		DisplayBoard(mine, ROW, COL);//让玩家看一下雷都在哪里
	}
}

game.h

//此文件写游戏需要的数据类型和函数声明等
#define ROW 9//真正有雷数组的行
#define COL 9//真正有雷数组的列
#define ROWS 11//整个大棋盘的行
#define COLS 11//整个大棋盘的列
#define EASY_COUNT 10//布置雷的时候计数用的,此处表示雷的个数是10(可任意修改)

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu();//菜单
void InitializeBoard(char arr[ROWS][COLS], int rows,int cols, char set);//初始化棋盘
void DisplayBoard(char arr[ROWS][COLS], int rows, int cols);//打印棋盘
void SetMine(char arr[ROW][COL], int row, int col);//布置雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS]);//排查雷


test.c

//此文件写游戏的测试逻辑
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h";
void menu()//菜单
{
	printf("**********************\n");
	printf("********1.play********\n");
	printf("********0.exit********\n");
	printf("**********************\n");
}

void game()//完成扫雷游戏
{
	char mine[ROWS][COLS];//存放布置好的雷
	char show[ROWS][COLS];//展示排查出雷的信息

	InitializeBoard(mine, ROWS, COLS,'0');//mine数组全部初始化为‘0’
	InitializeBoard(show, ROWS, COLS, '*');//show数组全部初始化为‘*’
	
	SetMine(mine, ROW, COL);//布置雷
	
	DisplayBoard(show, ROW, COL);//打印棋盘

	FindMine(mine,show,ROWS,COLS);//排查雷
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("-------扫雷游戏-------\n");
			game();//运行扫雷游戏
			break;
		case 0:
			printf("游戏结束\n");
			break;
		default:
			printf("选择值错误,请重新选择:\n");
		}
	} while (input);
	return 0;
}

game.c

//此文件写游戏中函数的实现
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h";

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

//打印棋盘
void DisplayBoard(char arr[ROWS][COLS],int row,int col)
{
	int i = 0;
	int j = 0;
	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 ", arr[i][j]);
		}
		printf("\n");
	}
}

//布置雷:生成十个随机的坐标,布置十个雷
void SetMine(char arr[ROWS][COLS],int row,int col)
{
	int count = EASY_COUNT;
	int x = ROW;
	int y = COL;
	while (count)
	{
		int x = rand() % ROW + 1;
		int y = rand() % COL + 1;
		if (arr[x][y] = '0')
		{
			arr[x][y] = '1';//布置一个雷
			count--;
		}
	}
}

//辅助排查雷函数FindMind,统计周围雷的个数
int GetMineCount(char mine[ROWS][COLS],int x,int y)
{
	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');
}
//排查雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS])
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < ROW * COL - EASY_COUNT)
	{
		printf("请输入要排查的坐标(行,列)(只用输入两个数字,中间用空格隔开):");
		scanf("%d %d", &x, &y);
		if ((x >= 1 && x <= ROW) && (y >= 1 && y <= COL))//判断坐标的有效性
		{
			if (mine[x][y] == '1')//踩雷
			{
				printf("很遗憾,你被炸死了\n");
				printf("请看雷都在哪里?0表示没有雷,1表示有雷\n");
				DisplayBoard(mine, ROW, COL);//让玩家看一下雷都在哪里
				break;
			}
			else//没踩雷,统计雷的个数
			{
				int count = GetMineCount(mine, x, y);
				show[x][y] = count + '0';//把int数字转为字符:int= char+'0'
				system("cls");
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标输入错误,请重新输入");
		}
	}
	if (win == ROW * COL - EASY_COUNT)
	{
		printf("恭喜你!排雷成功\n");
		DisplayBoard(mine, ROW, COL);//让玩家看一下雷都在哪里
	}
}

  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值