扫雷小游戏

2023-12-16 15:49:44

代码中写有详细注释,供大家参考食用

菜单打印

这个功能就是为了让玩家提供退出和开始的可视化界面

#include <iostream>
using namespace std;

int Game_interface()
{
	cout << "***************************" << endl;
	cout << "*******  1.start  *******" << endl;
	cout << "*******  0.end    *******" << endl;
	cout << "***************************" << endl;
	cout << "Please select :" << endl;
	return 1;//返回值是1为了在while循环中在输出前都会打印菜单
}
void game()
{
	cout << "******* 扫雷游戏 *********" << endl;
	//中间后续会加入游戏内容
	cout << endl;//为了和后面输出菜单分开,不会看混
}

void Game_Entrance()
{
	int input = 0;
	while ((Game_interface())&&scanf("%d", &input) == 1)//菜单展开并且
	//输入input的值
	{
	//根据input的值来判断游戏的板块
		if (input == 0)
			break;
		else if (input == 1)
			game();
		else
		{
			cout << "If the input is abnormal, re-enter" << endl << endl;//同理,也是为了在这一次循环结束后可以和Game_interface()菜单函数分隔开
		}
	}
	
}
int main()
{
	Game_Entrance();//封装本游戏的函数,单纯看着简洁点,可以不封装把这个函数内容
	//放在main函数内部也可以
	return 0;
}

game.cpp

我们在设计扫雷游戏要先分成两个二维数组,一个二维数组用来打印棋盘,就是让玩家看到的;另一个二维数组用来看雷的分布信息,1代表雷, 0代表无雷
为了后续简洁模块,我后面会建立在建立main.cpp,game.h,game.cpp三个文件来分开进行不同功能,main.cpp主要用来测试,game.h和game.cpp用来实现游戏功能,我会标注他在哪一个文件中,大家注意一下

#include "game.h"

void Initialize_board(char board[ROW][COL], int rows, int cols, char Initialize_characters)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			board[i][j] = Initialize_characters;
		}
	}
}

void Display_board(char board[ROW][COL], int row, int col)
{
	//分割线,可以不打印,为了好看而已
	cout << "----------y-----------" << endl;
	cout << "|";//后面要在左侧画|,用来标注x轴,如果不加这里|,
	//x轴偏一点,导致不会对齐
	//打印列号
	for (int i = 0; i <= col; i++)
	{
		//打印0是为了对齐列
		cout << i << " ";
	}
	cout << endl;
	for (int i = 1; i <= row; i++)
	{
		if (i != row / 2)
			cout << "|";
		else
			cout << "x";
		cout << i << " ";
		for (int j = 1; j <= col; j++)
		{
			cout << board[i][j] << " ";
		}
		cout << endl;
	}
}

void LayMines(char Observation_board[ROW][COL], int col, int row, int num)
{
	int count = num;
	while (count)
	{
		//让雷的坐标在9*9的棋盘里
		//%row把rand限制在0~row-1中,+1就是限制在乐1~row
		int i = rand() % row + 1;
		int j = rand() % col + 1;

		//避免同一个位置出现多个雷而重合
		if (Observation_board[i][j] == '0')
		{
			Observation_board[i][j] = '1';
			count--;
		}
	}
}

static int Calculate_mines(char Observation_board[ROW][COL], int x, int y)
{
	int num = 0;
	for (int i = x-1; i <= x+1; i++)
	{
		for (int j = y - 1; j <= y + 1; j++)
		{
			//因为我们这里用的char类型,转换会变成ASCII码值需要减去'0'
			//恢复原来的大小
			//因为前面的逻辑已经判断该位置不是雷,所以这个位置是'0'
			//对num的大小没有影响
			num = Observation_board[i][j] - '0' + num;
		}
	}
	return num;
}


void Mine(char Observation_board[ROW][COL], char External_chessboard[ROW][COL], int col, int row)
{
	int x, y;//坐标
	int count = 0;
	while (Mines+count<Row*Col)
	{
		cout << "Please enter the coordinates you want to probe(Enter x first, then y) :" << endl;
		cin >> x >> y;
		//判断坐标是否合法
		if (x<1 || x>row || y<1 || y>col)
		{
			cout << "The coordinates are invalid" << endl;
		}
		else
		{ 
			//先判断是否碰到雷
			if (Observation_board[x][y] == '1')
			{
				cout << "Hit Mines!!!" << endl;
				Display_board(Observation_board, row, col);
				return;
			}
			//看周围雷的个数
			External_chessboard[x][y] = Calculate_mines(Observation_board, x, y) + '0';
			count++;
			Display_board(External_chessboard, row, col);
		}
	}
	cout << "The game succeeded" << endl;
	Display_board(Observation_board, row, col);
}

game.h

#pragma once
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <time.h>

#define Col 9//列
#define Row 9//行
//下方棋盘+2是为了对后面棋盘边界情况计算雷的个数方便
//不必总是去分情况去计算雷的个数
#define COL Col+2//列
#define ROW Row+2//行

#define Mines 10

void Initialize_board(char board[ROW][COL], int rows, int cols, char Initialize_characters);

//打印的9行9列,注意区分宏
void Display_board(char board[ROW][COL], int row, int col);

void LayMines(char board[ROW][COL], int col, int row, int num);
 
void Mine(char Observation_board[ROW][COL], char External_chessboard[ROW][COL], int col, int row);

main.cpp

#include <iostream>
using namespace std;
#include "game.h"

int Game_interface()
{
	cout << "***************************" << endl;
	cout << "*******  1.start  *******" << endl;
	cout << "*******  0.end    *******" << endl;
	cout << "***************************"  << endl;
	cout << "Please select :" << endl;
	return 1;//返回值是1为了在while循环中在输出前都会打印菜单
} 

void game()
{ 
	srand((unsigned int)time(NULL));
	cout << "******* 扫雷游戏 *********" << endl;

	//外置棋盘,用来测试数据
	char External_chessboard[ROW][COL];
	//内置观测棋盘,用来包含雷的信息,以便后面检测数据是否正确
	char Observation_board[ROW][COL];
	//初始化两个棋盘,外置棋盘用*来初始化,内置观测棋盘用0来初始化
	Initialize_board(Observation_board, ROW, COL, '0');
	Initialize_board(External_chessboard, ROW, COL, '*');

	//在棋盘中加入雷
	LayMines(Observation_board, Col, Row, Mines);

	//打印棋盘
	Display_board(Observation_board, Row, Col);
	Display_board(External_chessboard, Row, Col);
	Mine(Observation_board, External_chessboard, Col, Row);
	cout << endl;//为了和后面输出菜单分开,不会看混
}

void Game_Entrance()
{
	int input = 0;
	while ((Game_interface()) && scanf("%d", &input) == 1)//菜单展开并且
		//输入input的值
	{
		//根据input的值来判断游戏的板块
		if (input == 0)
			break; 
		else if (input == 1)
			game();
		else
		{
			cout << "If the input is abnormal, re-enter" << endl << endl;//同理,也是为了在这一次循环结束后可以和Game_interface()菜单函数分隔开
		}
	}
}

int main()
{
	Game_Entrance();//封装本游戏的函数,单纯看着简洁点,可以不封装把这个函数内容
	//放在main函数内部也可以
	return 0;
}

文章来源:https://blog.csdn.net/tulingtuling/article/details/134904299
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。