代码中写有详细注释,供大家参考食用
这个功能就是为了让玩家提供退出和开始的可视化界面
#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;
}
我们在设计扫雷游戏要先分成两个二维数组,一个二维数组用来打印棋盘,就是让玩家看到的;另一个二维数组用来看雷的分布信息,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);
}
#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);
#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;
}