C语言扫雷游戏

对扫雷游戏进行编程,我们将扫雷游戏分成三个文件来进行编程,这有利于我们养成良好的习惯。

一、扫雷游戏的框架

我们将扫雷游戏分为这三个文件来编程,它们分别是:

1.test.c文件:在这个文件中,我们主要实现整个游戏的逻辑,只编写一个主函数,便于观看。

2.game.c文件:在这个文件中,我们要实现这个游戏的具体功能,即编写各个函数来实现扫雷游戏对应的功能,这个部分是实现扫雷游戏最为重要的代码。

3.game.h文件:在这个文件中,主要包含了相关的头文件,后续编程中所需要用到的全局变量和所需函数的声明。

二、扫雷游戏的具体实现

1.菜单函数:每个游戏在开始时都会显示一个菜单来供你选择,你要通过输入一个数字来选择是否进行游戏。

do
	{
		menu();
		printf("请输入一个数字来选择:");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("游戏结束!\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
void menu()
{
	printf("**********\n");
	printf("**1.play**\n");
	printf("**0.exit**\n");
	printf("**********\n");
}//展示菜单

 我们用switch语句来实现菜单的选择功能,do while语句来控制循环,只有当输入的数字为0时,才跳出循环,游戏也就结束了,当选择1时,就会调用game函数,进行游戏的游玩,输入其他数字时会提醒你输入错误并重新输入。

2.game函数:这是游戏主要功能的实现。

void game()
{
	char mine[ROWS][COLS] = { 0 };//存放雷的数组
	char show[ROWS][COLS] = { 0 };//展示给玩家看的数组,排查出雷的信息
	initBoard(mine, ROWS, COLS, '0');
	initBoard(show, ROWS, COLS, '*');
	setMine(mine, ROW, COL);
	//Boardprint(mine, ROW, COL);
	Boardprint(show, ROW, COL);
	findMine(mine, show, ROW, COL);
}

在这里面有许多其他的函数,下面会给大家一一解释,先给大家解释二维数组mine和show,mine数组是用来存放雷的数组,show数组是展示给玩家看的数组,我们要做的扫雷游戏的棋盘是9×9的棋盘,但我们定义的二维数组是11×11的,这是因为后面我们要排查雷的个数,要对周围雷的个数进行排查,这种情况下可能会造成数组下标越界的情况。

像上图所示那样,当我要排查1所在的那个格子周围有多少个雷时,也要对下面三个格子进行排查,这个时候就会造成数组下标越界,所以,我们将数组定义成11×11的数组,这样在排查时就不会造成数组下标越界。

3.initBoard函数(初始化数组(棋盘)函数):

void initBoard(char a[ROWS][COLS], int b, int c, char d)//初始化数组(棋盘)
{
	int i, j;
	for (i = 0; i < b; i++)
	{
		for (j = 0; j < c; j++)
		{
			a[i][j] = d;
		}
	}
}

 将数组全部初始化为某个字符,取决于你传参传进来哪个字符。

4.setMine函数(设置雷函数):

当棋盘初始化完后,我们便要设置雷了。

void setMine(char a[ROWS][COLS], int b, int c)//布置雷
{
	int count = minecount;
	while (count)
	{
		int x = rand() % b + 1;//随机生成雷的行坐标
		int y = rand() % c + 1;//随机生成雷的列坐标
		if (a[x][y] == '0')//只有不是雷时才能设置雷
		{
			a[x][y] = '1';
			count--;
		}
	}
}

我们利用srand和rand函数随机在棋盘上布置雷,定义雷的个数minecount为10,每成功布置了一个雷,count就减减,布置完10个雷后就跳出循环。

5.Boardprint函数(棋盘打印函数)

在设置好雷后,我们便要打印show数组让玩家进行排雷游戏。

void Boardprint(char a[ROWS][COLS], int b, int c)//打印棋盘
{
	int i, j;
	for (i = 0; i <= c; i++)
	{
		printf("%d ", i);//打印列坐标
	}
	printf("\n");
	for (i = 1; i <= b; i++)
	{
		printf("%d ", i);//打印行坐标
		for (j = 1; j <= c; j++)
		{
			printf("%c ", a[i][j]);
		}
		printf("\n");
	}
}

将行列坐标打印出来便于玩家选择排查的坐标,也将棋盘打印出来。

6.findMine函数(排查函数)

我们需要选择一个坐标进行排查,排查后显示该坐标周围有几个雷,以及判断玩家是否赢得游戏的条件。

void findMine(char a[ROWS][COLS], char b[ROWS][COLS], int c, int d)//排查雷
{
	int x, y;
	int win = 0;
	while (win<c*d-minecount)
	{
		printf("请输入要排查的坐标:");
		scanf_s("%d %d", &x, &y);
		if (x >= 1 && x <= c && y >= 1 && y <= d)//判断坐标是否有效
		{
			if (a[x][y] == '1')
			{
				printf("很遗憾,你被炸死,游戏结束。\n");
				Boardprint(a, ROW, COL);
				break;
			}
			else
			{
				int count=getMinecount(a, x, y);
				b[x][y] = count + '0';
				Boardprint(b, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("输入错误,请重新输入:");
		}
	}
	if (win == c * d - minecount)
	{
		printf("恭喜你,排雷成功\n");
		Boardprint(a, ROW, COL);
	}
}

,先输入一个排查的坐标,判断坐标是否合法,然后显示周围雷的个数,当踩到雷时,游戏结束,将所有不是雷的坐标找出,游戏也胜利。

7.getMinecount函数(排查周围雷的个数函数)

int getMinecount(char a[ROWS][COLS], int b, int c)//排查周围雷的个数
{
	int count = a[b - 1][c] +
		a[b - 1][c - 1] +
		a[b][c - 1] +
		a[b + 1][c - 1] +
		a[b + 1][c] +
		a[b + 1][c + 1] +
		a[b][c + 1] +
		a[b - 1][c + 1] - 8 * '0';
	return count;
}

因为棋盘是由字符构成的,对周围八个格子累加再减去8ב0’即可得知有几个雷。

三、扫雷游戏完整代码:

test.c文件:

#include"game.h"



int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		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;
}

game.c文件:

#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, '*');
	setMine(mine, ROW, COL);
	//Boardprint(mine, ROW, COL);
	Boardprint(show, ROW, COL);
	findMine(mine, show, ROW, COL);
}



void initBoard(char a[ROWS][COLS], int b, int c, char d)//初始化数组(棋盘)
{
	int i, j;
	for (i = 0; i < b; i++)
	{
		for (j = 0; j < c; j++)
		{
			a[i][j] = d;
		}
	}
}


void Boardprint(char a[ROWS][COLS], int b, int c)//打印棋盘
{
	int i, j;
	for (i = 0; i <= c; i++)
	{
		printf("%d ", i);//打印列坐标
	}
	printf("\n");
	for (i = 1; i <= b; i++)
	{
		printf("%d ", i);//打印行坐标
		for (j = 1; j <= c; j++)
		{
			printf("%c ", a[i][j]);
		}
		printf("\n");
	}
}

void setMine(char a[ROWS][COLS], int b, int c)//布置雷
{
	int count = minecount;
	while (count)
	{
		int x = rand() % b + 1;//随机生成雷的行坐标
		int y = rand() % c + 1;//随机生成雷的列坐标
		if (a[x][y] == '0')//只有不是雷时才能设置雷
		{
			a[x][y] = '1';
			count--;
		}
	}
}

int getMinecount(char a[ROWS][COLS], int b, int c)//排查周围雷的个数
{
	int count = a[b - 1][c] +
		a[b - 1][c - 1] +
		a[b][c - 1] +
		a[b + 1][c - 1] +
		a[b + 1][c] +
		a[b + 1][c + 1] +
		a[b][c + 1] +
		a[b - 1][c + 1] - 8 * '0';
	return count;
}

void findMine(char a[ROWS][COLS], char b[ROWS][COLS], int c, int d)//排查雷
{
	int x, y;
	int win = 0;
	while (win<c*d-minecount)
	{
		printf("请输入要排查的坐标:");
		scanf_s("%d %d", &x, &y);
		if (x >= 1 && x <= c && y >= 1 && y <= d)//判断坐标是否有效
		{
			if (a[x][y] == '1')
			{
				printf("很遗憾,你被炸死,游戏结束。\n");
				Boardprint(a, ROW, COL);
				break;
			}
			else
			{
				int count=getMinecount(a, x, y);
				b[x][y] = count + '0';
				Boardprint(b, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("输入错误,请重新输入:");
		}
	}
	if (win == c * d - minecount)
	{
		printf("恭喜你,排雷成功\n");
		Boardprint(a, ROW, COL);
	}
}

game.h文件:

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define minecount 10

void initBoard(char a[ROWS][COLS], int b, int c, char d);//初始化数组(棋盘)

void Boardprint(char a[ROWS][COLS], int b, int c);//打印棋盘

void setMine(char a[ROWS][COLS], int b, int c);//设置雷

void findMine(char a[ROWS][COLS],char b[ROWS][COLS], int c, int d);//排查雷

int getMinecount(char a[ROWS][COLS], int b, int c);//查找周围有几个雷

四、游戏功能测试:

为了方便测试,我们先将雷的分布图打印出来。

可见,坐标2 6周围有两个雷,所以在棋盘上显示2,而2 7是雷,排查2 7后踩到雷游戏结束。

由于判断胜利的条件需要将剩余的不是雷的71个坐标全部找出,不方便证明,于是我将雷改为80个,将剩余1个不是雷的坐标找出来证明。

可见坐标6 7不是雷,将坐标6 7排查后,游戏成功。这就是排雷游戏的基本实现过程。

  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值