c语言小游戏——扫雷实现详解!

首先创建一个mian函数

int main()
{
	test();
	return 0;
}

我们在main函数尽量写少量的代码,我们在main函数中创建test()函数,其他功能在test()函数内实现。

void test()
{

	do
	{

	} while ();
}

我们运行代码首先要打印一个菜单,所以我们用do while循环来实现,在我们的do while循环中首先打印一个简易菜单,保证我们一运行就可以显示。

void test()
{

	do
	{
		menu();
	
	} while (input);
}

我们创建一个menu函数来打印菜单,当然简易菜单也是很容易实现,我们创建后只需要在里边打印输出就可以了;

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

打印菜单之后我们要提示一下,开始游戏或者结束游戏,这时候我们就要创建一个变量存放用户录入的值,这时我们创建一个switch开关,如果用户选择1那么就开始游戏,选择0,那么就退出游戏,当然,如果用户输入的既不是1也不是0;我们也要给用户一个提示,提示输入错误,请重新输入;

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);
}

当用户选择1:的时候,我们就创建一个game函数来实现游戏;

void game()
{

}

我们将在game函数中来实现我们游戏,既然是扫雷游戏,那么我们就需要打印一个棋盘,打印棋盘的话,我们要先创建一个二维数组,但是我们如果用数字创建,就会写死,那么不方便我们之后更改,所以我们创建一个头文件的文件夹,我们将需要的数字宏定义,,那么我们之后再更改棋盘大小或者别的更改将会非常的方便;下边是创建头文件的方法:

 在我们创建好头文件之后,我们就可以打开.h的头文件在里边创建我们所需要的头文件以及声明

#define ROW 9
#define COL 9

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

 我们既然是创建棋盘,那我们要创建的一个二维数组,我们今天要做的是一个9x9的棋盘,我们就在头文件中定义行和列都为9,这时候就出现一个问题了,因为扫雷判断条件是当前位置周围8个格子那么如果我们当前选择的格子在棋盘的边缘,那么我们9x9的棋盘是不够的,这时我们应该让棋盘的行和列都多出一行,那么我们边缘的位置也是可以判断的,当我们定义好之后,我们就回到最开始的.c文件中,我们要开始实现代码,我们首先要创建两个数组,那么数组要创建什么类型的呢,我们不妨先定义一下,如果我们所查找的一个坐标是雷的话,我们就在棋盘上放置‘1’,如果不是雷的话我们就放置‘0’;既然是字符,那么我们就应该创建一个char类型的数组

void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
}

创建好数组之后,我们就要去初始化我们的棋盘,初始化棋盘的话,首先我们要想,一个棋盘的话,我们之前约定的如果是雷的话我们放‘1’,相信大家也玩过扫雷游戏,当我们玩扫雷时,我们点击一个位置的时候,如果不是雷的话,会显示数字,这个数字代表周围有几个雷,那么入过我们点击的这个位置,周围8个位置的雷恰好是1个,是不是就和我们所约定的雷放‘1’冲突了,既然这样,那我们就创建两个棋盘,一个棋盘用来存放雷,一个棋盘我们用来排雷,打印的时候只打印我们需要扫雷的棋盘,不打印放雷的棋盘,那么要实现初始化棋盘,我们首先要在我们创建的.h头文件中声明一下,

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

实现的话,我们可以再创建一个.c文件,这个.c文件用来实现我们的代码,.c文件的创建方法可以参考.h文件的方法,在第三步的时候选择c++文件,注意这个文件的后缀名要改为.c,当我们在.h文件中定义之后,我们就可以拿到.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++)   //我们先遍历行,从下标为0开始,这时候的rows是11 从0开始小于11进 
                                  //入循环
	{
		int j = 0;
		for (j = 0; j < cols; j++) //这个就是列 
		{
			board[i][j] = set; //我们棋盘上的i行j列初始化为set
		}
	}                      //set的话就是一个是放雷的棋盘传过来的是‘0’
}                         //另一个就是我们要排雷时所打印出来给我们看的,首先扫雷要保密,我选择用 
                            //的‘*’

当我们在.c文件中实现的时候,我们是要引用我们所创建的头文件,就是我们的.h文件,#include“   ”引号中填鞋创建.h文件的名就可以,我们来实现的时候,就是将数组参数传到头文件中声明,在头文件中声明之后我们就可以拿到.c文件中来实现了,(表达起来真的好难呀呀呀呀呀!!!!)

当我们初始化之后,就要打印出来看一下了 打印的话和初始化棋盘一样,只是我们打印的话要打印的是9x9的不是11x11的,所以在我们传参数的时候要传ROW,COL,这两个是9 9,我们之前之所以传的是ROWS,COLS,是因为我们要先把11x11的棋盘完全初始化,我们所需要的只是9x9这么大的棋盘,如下:

DisplayBoard(show, ROW, COL);  //test函数中
FindMine(mine, show, ROW, COL);
void DisplayBoard(char board[ROWS][COLS], int row, int col);

//这是.h文件中定义;
void DisplayBoard(char board[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 ", board[i][j]);
		}
		printf("\n");
	}
	printf("---------扫雷----------\n");
}

//这是在创建的.c文件中所实现的

那么接下来我们就要开始布置雷;布置雷我们要生成随机数,这时我们就要用到time函数,我们如果要使用time函数首先要引用头文件,我们这个头文件可以放在我们的.h文件中,

#include <time.h> //.h文件

那么我们开始布置雷,首先在test函数值创建函数

SetMine(mine, ROW, COL); //test函数

接着我们在.h文件中声明

void SetMine(char mine[ROWS][COLS], int row, int col);//.h文件

接着在.c文件中实现

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		//1. 生成随机下标
		int x = rand() % row + 1;//这时候就要用到time函数了
		int y = rand() % col + 1;
		//2. 布置雷
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

那么随机数具体要怎么生成呢,rand函数首先要使用的话是需要调用srand函数的,我们srand函数只需要声明一次,我们直接在test()函数中定义一下

srand((unsigned int)time(NULL));

当我们定义之后,我们使用的时候会自动生成0到32767之间的数,我们不需要这么大的数,所以我们%上row,row是9,那么就会生成0到8的数字,我们+1就会生成0到9之间的数字,当我们布置好雷之后我们就可以开始排雷,

	FindMine(mine, show, ROW, COL); //test
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

//.h
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');
}//假设我们排查的坐标为x,y,那么我们就把要周围8个坐标全部排查一遍,如果有雷我们要显示数字,可我们 
  //现在现在查到的是字符数,所以我们要减去8个字符0;也是就8*48;剩余的数字就是我们周围雷的数
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))
	{
		printf("请输入要排查的坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)//如果x和y是在行和列1到9之间
		{
			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';
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标非法,重新输入\n");
		}
	}
	if (win == (row * col - EASY_COUNT))//所有的坐标位减去10个雷
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

我们到此已经可以开始玩了,有些不知道该如何表达,有问题可以留言哦,我会尽力为大家解决我,感谢鉴赏,下边上全代码

teste文件

#include "game.h"

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

void game()
{
	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;
}

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_COUNT 10


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); //排雷

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;
		}
	}
}

void DisplayBoard(char board[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 ", board[i][j]);
		}
		printf("\n");
	}
	printf("---------扫雷----------\n");
}

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

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))
	{
		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';
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标非法,重新输入\n");
		}
	}
	if (win == (row * col - EASY_COUNT))
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值