c语言小游戏——扫雷的实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

一、前言

二、代码详解

1.test.c——测试游戏的逻辑

2.game.c——游戏代码的实现

3.game.h——游戏代码的声明 ( 函数声明,符号定义 )


前言

提示:这里可以添加本文要记录的大概内容:

大家好,今天带来的是一个简单的c语言小程序——扫雷,扫雷游戏相对简单易于新手实现。在这边文章里我将详细讲解程序的实现,本文代码采用多文件方式。欢迎大家关注和评论。


提示:以下是本篇文章正文内容,下面案例可供参考

一、扫雷是什么?

《扫雷》是益智小游戏。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非地雷的格子,同时避免踩到地雷,踩到一个地雷全盘皆输。玩家需要在雷区中,将所有地雷一一排查出来。

注意: 本文实现的是 9×9 的扫雷游戏,在雷区放置 10 个地雷 。

二、代码详解

部分定义说明:

ROW 代表常量 9,COL 代表常量 9,ROWS 代表 ROW + 2,即常量 11,COLS 代表 COL + 2,即常量 11。

这样定义的原因:当我们在说明其中一个位置周围有几个雷时如果为9*9表格会发生数组下标溢出如下如果我们选择了坐标:(2,1)的位置当我们遍历周围8个格子有没有雷时左边会出现溢出所以在部分函数中使用11*11.

0 1 2 3 4 5 6 7 8 9
1
2
3
4
5
6
7
8
9

 

1.tset.c文件

#include "game.h"

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

void game()
{
	//1. 需要存放布置好的雷的信息,存放排查出的雷的信息,我们需要2个二维数组
	//2. 排查坐标的时候,为了防止坐标越界,我们给数组的行增加2行,列增加了2列
	char mine[ROWS][COLS] = {0};//布置好的雷的信息
	char show[ROWS][COLS] = {0};//排查出的雷的信息
	//初始化棋盘
	InitBoard(mine, ROWS,COLS, '0');
	InitBoard(show, ROWS,COLS, '*');

	//打印棋盘
	DisplayBoard(show, ROW, COL);

	//布置雷
	SetMine(mine, ROW, COL);
	//DisplayBoard(mine, ROW, COL);    
	//排查雷
	FindMine(mine, show, ROW, COL);
}

void test()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请选择:>");
		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.game.c文件

#include "game.h"

void InitBoard(char board[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++)
		{
			board[i][j] = set;        //分别将mine和show棋盘初始化,我们在这里规定0为空1
		}                             //为炸弹。使用set可以简化代码。*为show棋盘没有扫的位置
	}
}

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;                           //该函数作用是打印出show棋盘
	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 ", board[i][j]);
		}
		printf("\n");
	}
	printf("---------扫雷----------\n");
}

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;                 //随机安排雷
	while (count)
	{
		//1. 生成随机下标
		int x = rand() % row + 1;          //使x范围在1——9之间
		int y = rand() % col + 1;          //同上
		//2. 布置雷
		if (mine[x][y] == '0')             //判断条件可以防止雷的坐标重复
		{
			mine[x][y] = '1';
			count--;                     //count为10在game.h有定义,安排10个雷
		}
	}
}

int get_mine_count(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 row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < (row * col - EASY_COUNT))     //括号中说明最多重复9*9-10次如果条件不成立说
	{                                         //雷已经扫完
		printf("请输入要排查的坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)  //防止坐标溢出
		{
			if (show[x][y] != '*')       
			{
				printf("该坐标被排查过了\n");      
				continue;
			}
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				int n = get_mine_count(mine, x, y);
				show[x][y] = n+'0';               //显示附件8个格子一共有几个雷给玩家提示 
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标非法,重新输入\n");
		}
	}
	if (win == (row * col - EASY_COUNT))     //扫够70次游戏结束
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

注释:

我们随便选一个位置(x,y)它周围8个格子的坐标可得如图

0 1 2 3 4 5 6 7 8 9
1
2
3 x-1,y-1

x-1,y

x-1,y-1
4 x,y-1 x,y x,y+1
5 x-1,y+1 x+1,y x+1,y+1
6
7
8
9

如果周围8个位置字符相加减去字符‘0’得到的数就是周围有几个雷,字符0和字符1的askii值相差1.

3.game.h文件

#include 
#include 
#include 

#define ROW 9
#define COL 9

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

#define EASY_COUNT 79

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);

//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);

//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

总结



 

你可能感兴趣的:(c语言)