【C++扫雷小游戏】

目录

  • 前言
    • 一.游戏规则
    • 二.游戏菜单
      • 1.创建菜单
      • 2.在主函数中使用菜单
    • 三.方式:面向对象的思想
      • 1.Mine(扫雷)类的创建
    • 四.核心内容及其实现
      • 1.棋盘的初始化
      • 2.打印棋盘
      • 3.在棋盘中埋雷
      • 4.统计周围雷的个数
      • 5.排查雷
    • 五.完整代码

前言

尝试挑战经典的扫雷游戏,用C++实现自己的版本
扫雷,这个经典的休闲益智游戏,曾陪伴许多人度过无数时光。玩家需要根据已翻开的方块上的数字,推断出隐藏在方格中的地雷位置,然后用标记或者揭开其他方块的方式逐渐清理出安全的区域。通过逻辑推理与快速反应,玩家能够体验到紧张刺激以及智慧的成就感。

一.游戏规则

设计游戏前先了解扫雷的基本规则,以围绕规则用C++实现:
一个扫雷盘面由许多方格(cell)组成,方格中随机分布着一定数量的雷(mine),一个格子中至多只有1雷。每个方格上都会显示数字来表示以此为中心的3*3的格子中有多少雷,胜利条件是打开所有非雷格(safe cell),失败条件是打开了一个雷格(踩雷)在这里插入图片描述

二.游戏菜单

1.创建菜单

先创建一个简单的游戏菜单

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

2.在主函数中使用菜单

(1)用switch case来找到选项
(2)用do while来实现一局又一局游戏的菜单弹出

int main()
{
	int input = 0;
	do
	{
		menu();
		cout << "请输入选项>";
		cin>>input;
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			cout << "退出游戏";
			break;
		default:
			cout << "输入错误,请重新输入";
			break;
		}
	} while (input);
	return 0;
}

三.方式:面向对象的思想

1.Mine(扫雷)类的创建

面向对象的设计提供了一种更加结构化的思维方式,使得代码更加清晰、可读和可维护。它能够提高代码的可重用性和可扩展性,同时也能够增强代码的灵活性和可靠性。

class Mine
{
public:
	//初始化棋盘
	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 board[ROWS][COLS], int row, int col)//排查雷
	void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//找周围有多少雷 
	int GetMineCount(char mine[ROWS][COLS], int x, int y)};

并创建一个扫雷对象mine1

Mine mine1;

四.核心内容及其实现

1.棋盘的初始化

以二维数组的形式展现棋盘
1.其中’0’元素为安全格
2.'1’元素为雷区

char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };

mine棋盘为被初始化且被埋雷的棋盘
show棋盘为用户每次操作棋盘时可看到的界面

包含的元素:雷的个数,棋盘大小

#define ROW 5//元素所在区域大小
#define COL 5
#define ROWS ROW + 2//棋盘大小偏大防止越界
#define COLS COL + 2
#define EASY_COUNT 5//雷的个数
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
	{
		int i = 0;
		int j = 0;
		for (i = 0; i < rows; i++)
		{
			for (j = 0; j < cols; j++)
			{
				board[i][j] = set;
			}
		}
	}

对于mine棋盘和show棋盘的初始化

mine1.InitBoard(mine, ROWS, COLS, '0');
mine1.InitBoard(show, ROWS, COLS, '*');

2.打印棋盘

代码实现

void DisplayBoard(char board[ROWS][COLS], int row, int col)
	{
		int i = 0;
		int j = 0;
		cout << "------------扫雷------------\n";
		for (i = 0; i <= row; i++)
		{
			cout << i<<" ";
		}
		cout << "\n";
		for (i = 1; i <= row; i++)
		{
			cout << i<<" ";
			for (j = 1; j <= col; j++)
			{
				cout << board[i][j]<<" ";
			}
			cout << "\n";
		}
		cout << "------------扫雷------------\n";
	}

【C++扫雷小游戏】_第1张图片

上图即为向用户展示的棋盘

3.在棋盘中埋雷

在棋盘中埋雷采用横纵坐标随机取值的方法
其中要调用rand()函数//其头文件为cstdlib
而对于x,y随机取值不能越界可使用如下方法

int x = rand() % row + 1;
int y = rand() % col + 1;

并且每次埋完一个雷就要减去一次总计雷的个数并再次进入循环

代码实现

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

4.统计周围雷的个数

由于用’1’表示的雷,用’0’表示的安全格,则可以直接 返回其周围元素的值之和再减去8个’0’即可

代码实现

int GetMineCount(char mine[ROWS][COLS], int x, int y)
	{
		return mine[x + 1][y] + mine[x - 1][y] +
			mine[x][y + 1] + mine[x][y - 1] +
			mine[x + 1][y + 1] + mine[x - 1][y + 1] +
			mine[x - 1][y - 1] + mine[x + 1][y - 1] - 8 * '0';
	}

5.排查雷

排查雷一共分三种情况
1.第一种是排查到show中的当前元素 不是*时,说明已经翻过此格子,需要重新排查
2.第二种是排查到mine中的当前元素是’1’时,那就是找到了炸弹,游戏结束
3.第三种就是排查到mine中的当前元素是’0’时,找到他周围有多少个雷,并在show中的此位置返回个数值。

要定义一个 count2来进行计数,如果count2的个数达到安全格的个数时,则说明游戏胜利
注意:在每次翻完格子或者在游戏结束时,都要添加打印函数来向用户展示实时情况

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
		{
	int x = 0;
	int y = 0;
	int count2 = 0;
	while (count2 < row * col - EASY_COUNT)
	{
		cout << "请输入横坐标>";
		cin>>x;
		cout << "请输入纵坐标>";
		cin >> y;
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (show[x][y] != '*')
			{
				cout << "输入坐标重复,请重新输入\n";
			}
			else if (mine[x][y] == '1')
			{
				cout << "笨猪你被炸死了\n";
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				//不是雷,就统计x,y坐标周围有几个雷
				int c = GetMineCount(mine, x, y);
				show[x][y] = c + '0';
				DisplayBoard(show, ROW, COL);
				count2++;
			}
		}
		else
		{
			cout<<"输入坐标错误,请重新输入\n";
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		cout << "排雷成功\n";
		DisplayBoard(mine, ROW, COL);
	}
}

五.完整代码

类中代码的实现

#include
#include
#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
#define EASY_COUNT 10
using namespace std;
class Mine
{
public:
	//初始化棋盘
	void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
	{
		int i = 0;
		int j = 0;
		for (i = 0; i < rows; i++)
		{
			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;
		cout << "------------扫雷------------\n";
		for (i = 0; i <= row; i++)
		{
			cout << i<<" ";
		}
		cout << "\n";
		for (i = 1; i <= row; i++)
		{
			cout << i<<" ";
			for (j = 1; j <= col; j++)
			{
				cout << board[i][j]<<" ";
			}
			cout << "\n";
		}
		cout << "------------扫雷------------\n";
	}
	//布置雷
	void SetMine(char board[ROWS][COLS], int row, int col)
		{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
		}
		count--;
	}
		}
	//排查雷
	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)
	{
		cout << "请输入横坐标>";
		cin>>x;
		cout << "请输入纵坐标>";
		cin >> y;
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (show[x][y] != '*')
			{
				cout << "输入坐标重复,请重新输入\n";
			}
			else if (mine[x][y] == '1')
			{
				cout << "笨猪你被炸死了\n";
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				//不是雷,就统计x,y坐标周围有几个雷
				int c = GetMineCount(mine, x, y);
				show[x][y] = c + '0';
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
			cout<<"输入坐标错误,请重新输入\n";
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		cout << "排雷成功\n";
		DisplayBoard(mine, ROW, COL);
	}
}
	//找周围有多少雷 
	int GetMineCount(char mine[ROWS][COLS], int x, int y)
	{
		return mine[x + 1][y] + mine[x - 1][y] +
			mine[x][y + 1] + mine[x][y - 1] +
			mine[x + 1][y + 1] + mine[x - 1][y + 1] +
			mine[x - 1][y - 1] + mine[x + 1][y - 1] - 8 * '0';
	}
};

把棋盘的实现步骤按顺序存放进新的函数game()中,便于 菜单的调用。
其中包含对象的创建,和对象函数的按序调用。

void game()
{
	Mine mine1;
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	mine1.InitBoard(mine, ROWS, COLS, '0');
	mine1.InitBoard(show, ROWS, COLS, '*');
	mine1.DisplayBoard(show, ROW, COL);
	mine1.SetMine(mine, ROW, COL);
	mine1.FindMine(mine, show, ROW, COL);
}

菜单及主函数的实现

int main()
{
	//srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		cout << "请输入选项>";
		cin>>input;
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			cout << "退出游戏";
			break;
		default:
			cout << "输入错误,请重新输入";
			break;
		}
	} while (input);
	return 0;
}

此扫雷小游戏是一个较简单的实现,读者可参考后根据自身写出符合需求的更高阶的制作。

你可能感兴趣的:(c++,网络,服务器)