扫雷游戏的基本实现

本文详细介绍了如何使用C++编写一个简单的9×9扫雷游戏,包括菜单设计、用户输入判断、随机布雷、雷的计数以及游戏流程控制,展示了从基础逻辑到具体实现的关键步骤。
摘要由CSDN通过智能技术生成

学习写代码是为了完成某些事情,无论是循环还是判断语句都是为了去实现某些功能,接下来,我将详细的描述如何去写出一个9×9,包含10个雷的扫雷游戏。

这个游戏的规则是这样的,当我们进入这个游戏,我们输入一个坐标,电脑会判断这个坐标是否为雷,如果是雷,那么游戏结束,如果不是雷,那么游戏继续且显示出当前坐标附近八个坐标有几个雷。当场上只剩下雷的坐标,那么游戏胜利。

首先,为了让玩家自由选择是否开始游戏,我们可以先写出一个函数,让代码刚开始先打印出一个菜单,这个菜单会告诉玩家1是开始游戏,0是结束游戏。

void menu()
{
	printf("*****************************\n");
	printf("******    PLAY:1    *********\n");
	printf("******    EXIT:0    *********\n");
	printf("*****************************\n");
}

接着,我们便写出主函数。我们先初始化一个int input = 0;我们要无限的玩这个游戏,所以我们需要使用到while语句,而且我们至少需要进行一次循环,来让判断的input作用于switch语句,所以我们使用do while循环。

我们需要写出一个判断语句来让电脑知道玩家开不开始游戏,1代表游戏开始而0代表游戏结束,我们便自然而然的想到了switch语句,当玩家选择1时候,我们游戏开始,当玩家选择0的时候,游戏结束,当玩家输入其他数字的时候,我们可以打印一句话,提醒玩家重新选择。

int main()
{

	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("----扫雷游戏即将开始!-------\n");
			game();
			break;
		case 0:
			printf("Game Over!\n");
			break;
		default:
			printf("You print the wrong digit!\n");
			break;
		}
	} while (input);
	
	return 0;
}

当主函数写完以后,我们便需要开始考虑这个游戏的核心,也就是game函数部分了。

首先,为了实现功能,我们先定义雷的数量为10,初始化两个二维数组,一个数组arr1用来存放雷,一个arr2数组用来显示,而这个棋盘的大小,我们可以用Hang来表示行,用Lie来表示列,Hang和Lie我们会多次使用,且日后为了扩展扫雷游戏,所以我们把他放在头文件里面。于是,理论上我们的Hang和Lie就是9。但是,我们这样这样子定义,在后面判断坐标附近有几个雷的时候,四边的雷会检测超过当前内存的地区,导致报错。为了解决这个问题,我们可以给四条边多向外扩展一排,于是便可以这样写

#define Hang 9
#define Lie 9
#define HangPlus Hang + 2
#define LiePlus Lie + 2
#define BOME 10

而初始化数组我们需要放在game函数里头写。

	char arr1[HangPlus][LiePlus];
	char arr2[HangPlus][LiePlus];

当数组初始化以后,我们便需要在数组里面放东西了。为了方便,我们用1代表雷,用0代表不是雷,注意,在这里面,1和0都不是数字,他们是字符。我们在arr1里面放满0,在arr2里面放满*,我们不需要在最外侧的0和10列,0和10行放0或*,所以,我们只需要这样写

在game函数里面这样 

	Initboard(arr1, '0', HangPlus, LiePlus);
	Initboard(arr2, '*', HangPlus, LiePlus);

在game文件里面我们这么写

void Initboard(char board[HangPlus][LiePlus], char set,int hang ,int lie)//不能与关键字重名
{
	int i = 0;
	for (int i = 0; i < hang; i++)
	{
		for (int j = 0; j < lie; j++)
		{
			board[i][j] = set;
		}
	}

set让我们可以自由选择放进去什么字符,操作起来更自由。

在实现数组完全初始化以后,我们便可以开始选择先放雷或者先显示一次arr2棋盘的样子,我们这便选择先写Bome函数

Bome函数要实现的是在9×9的棋盘里面随机放10个雷,所以我们还是得使用前面学到的scrand()和时间戳知识来实现随机数,scrand()函数就放在主函数里面。

我们定义一个count文件等于BOME,定义x与y来确定雷的坐标,x与y皆需要通过随机数选出,x = rand()%Hang + 1;y也是同样意思,这样我们就可以得到随机的x,y值了。为了重复布雷,我们再写一个if判断语句来避免这种情况出现。

void Bome(char board[HangPlus][LiePlus], int hang, int lie)
{
	int count = BOME;
	while(count)
	{
		int x = rand() % hang + 1;
		int y = rand() % lie + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}

在布完雷以后,我们便开始打印出arr2棋盘,为了实现视觉上的美观,我们将棋盘打印成第一行与第一列都是0~9,让玩家更好的进行坐标锁定。接着就是很正常的利用for循环打印二维数组啦

void Display(char board[HangPlus][LiePlus], int hang, int lie)
{

	for (int i = 0; i <= hang; i++)
	{
		printf("%d ", i);
	}

	printf("\n");

	for (int i = 1; i <= lie; i++)
	{
		printf("%d ", i);
		for (int j = 1; j <= hang; j++)
		{
			printf("%c ",board[i][j]);
			
		}
		printf("\n");
	}
}

在我们的目标中,当我们选择一个坐标以后,我们便会得到这个坐标附近有几个雷,这个功能我们也可以通过一个函数实现,由于我们数组里面的0和1都是字符,所以我们需要针对的是他们的ASCII值进行计算的这个函数需要一个int的返回值,于是我们可以这样子写

int GetBome(char board[HangPlus][LiePlus], int x, int y)
{
	return(board[x][y - 1] + board[x][y + 1] + board[x + 1][y] + board[x + 1][y - 1] + board[x][y + 1] + board[x - 1][y] + board[x - 1][y + 1] + board[x - 1][y - 1] - 7 * '0');
}

到最后,就是我们最重要的找雷函数了,这个函数在前面函数已经写好的情况下并不算很难,只需要注意控制坐标的范围以及胜利的条件就行

void FindBome(char arr1[HangPlus][LiePlus], char arr2[HangPlus][LiePlus],int hang, int lie)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < (hang * lie - BOME))
	{
		printf("请输入要排查的坐标:");
		scanf("%d,%d", &x, &y);
		if (x >= 1 && x <= hang && y >= 1 && y <= lie)
		{
			if (arr1[x][y] == '1')
			{
				printf("你死了\n");
				Display(arr1, Hang, Lie);
				break;
			}
			else
			{
			
				arr2[x][y] = GetBome(arr1, x, y);
				Display(arr2, Hang, Lie);
				win++;
			}
		}
		else
		{
			printf("你输入了一个错误坐标!\n");
		}

	}
	if (win == hang * lie - BOME)
	{
		printf("你赢了\n");
		Display(arr1, Hang, Lie);
	}
}

于是经过这一串的代码,我们便写好了这个游戏。

game头文件

#pragma once

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

#define Hang 9
#define Lie 9
#define HangPlus Hang + 2
#define LiePlus Lie + 2
#define BOME 10

void Initboard(char board[HangPlus][LiePlus], char set, int hang, int lie);

void Bome(char board[HangPlus][LiePlus], int hang, int lie);

void Display(char board[HangPlus][LiePlus], int hang, int lie);

void FindBome(char arr1[HangPlus][LiePlus], char arr2[Hang][Lie], int hang, int lie);

game游戏文件

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void Initboard(char board[HangPlus][LiePlus], char set,int hang ,int lie)//不能与关键字重名
{
	int i = 0;
	for (int i = 0; i < hang; i++)
	{
		for (int j = 0; j < lie; j++)
		{
			board[i][j] = set;
		}
	}
}

void Bome(char board[HangPlus][LiePlus], int hang, int lie)
{
	int count = BOME;
	while(count)
	{
		int x = rand() % hang + 1;
		int y = rand() % lie + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}
void Display(char board[HangPlus][LiePlus], int hang, int lie)
{

	for (int i = 0; i <= hang; i++)
	{
		printf("%d ", i);
	}

	printf("\n");

	for (int i = 1; i <= lie; i++)
	{
		printf("%d ", i);
		for (int j = 1; j <= hang; j++)
		{
			printf("%c ",board[i][j]);
			
		}
		printf("\n");
	}
}

int GetBome(char board[HangPlus][LiePlus], int x, int y)
{
	return(board[x][y - 1] + board[x][y + 1] + board[x + 1][y] + board[x + 1][y - 1] + board[x + 1][y + 1] + board[x - 1][y] + board[x - 1][y + 1] + board[x - 1][y - 1] - 7 * '0');
}

void FindBome(char arr1[HangPlus][LiePlus], char arr2[HangPlus][LiePlus],int hang, int lie)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < (hang * lie - BOME))
	{
		printf("请输入要排查的坐标:");
		scanf("%d,%d", &x, &y);
		if (x >= 1 && x <= hang && y >= 1 && y <= lie)
		{
			if (arr1[x][y] == '1')
			{
				printf("你死了\n");
				Display(arr1, Hang, Lie);
				break;
			}
			else
			{
			
				arr2[x][y] = GetBome(arr1, x, y);
				Display(arr2, Hang, Lie);
				win++;
			}
		}
		else
		{
			printf("你输入了一个错误坐标!\n");
		}

	}
	if (win == hang * lie - BOME)
	{
		printf("你赢了\n");
		Display(arr1, Hang, Lie);
	}
}

主函数文件

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()
{
	printf("*****************************\n");
	printf("******    PLAY:1    *********\n");
	printf("******    EXIT:0    *********\n");
	printf("*****************************\n");
}

void game()
{
	char arr1[HangPlus][LiePlus];
	char arr2[HangPlus][LiePlus];

	Initboard(arr1, '0', HangPlus, LiePlus);
	Initboard(arr2, '*', HangPlus, LiePlus);

	Display(arr2, Hang, Lie);
	Bome(arr1,Hang,Lie);
	FindBome(arr1, arr2, Hang,Lie);
}

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

	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("----扫雷游戏即将开始!-------\n");
			game();
			break;
		case 0:
			printf("Game Over!\n");
			break;
		default:
			printf("You print the wrong digit!\n");
			break;
		}
	} while (input);
	
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值