提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
扫雷这个游戏很多人都玩过,我是写这个项目之前没玩过,所以还专门去查了下扫雷的一些游戏规则,今天就分享一下我的代码把,用的是vs,头文件和main 老规矩放最下面了/font>
提示:以下是本篇文章正文内容,下面案例可供参考
一、初始化地图
void initMap()
{
// 初始化标记数组
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
flagMap[i][j] = 0;
}
}
// 初始化地图数据
setMine();
}
首先做一个9 9 的地图,遍历二维数组,全部赋值为0,数组flagMap这个数组用来表示格子有没有被翻开,0表示没翻开,1表示翻开了
二、setMine函数
void setMine()
{
// 布雷
int countOfMine = 10;//设置雷的数量为10
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)//遍历二维数组
{
if (countOfMine>0)//雷的数量还没到0
{
map[i][j] = 9;//直接赋值为9,也就是直接让它变成雷
countOfMine--;
}
else
{
map[i][j] = 0;
}//上面的意思就是直接让这个二维数组的前10个元素都为9,也就是都设置为雷
}
}
// 打乱顺序
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)//遍历整个数组
{
int x = rand() % 9;//
int y = rand() % 9;//设置两个随机数,作为数组下标
int temp = map[i][j];//从数组第一个数开始,和一个数组的随机位置的值进行交换
map[i][j] = map[x][y];
map[x][y] = temp;
}
}//打乱顺序实现了雷的位置的随机性
setMine函数在初始化地图最下面被调用了了,这是个布雷的函数,可以看到函数里面用的数组名为map,所以就像我上面说的一样,要用两个数组,一个数组表示格子有没有被翻开,另外一个数组表示格子的元素了,map[][]是第二者,在这里呢,设置了数字9为雷,0到8表示周围的雷的数量
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (map[i][j] != 9)
{
map[i][j] = getCountOfMineForPos(i, j);
}
}
}
}
这个部分用来计算每个点周围雷的数量,周围的范围就是以这个给点为中心的9宫格,getCountOfMineForPos函数在下面进行介绍
三、getCountOfMineForPos 函数
int getCountOfMineForPos(int x, int y)
{
int count = 0;//记录周围雷的数量
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)//9宫格范围从9宫格左上角到右下角,与中心点比较,x偏移范围是-1到1,y偏移范围也是-1到1
{
// 不能越界
if (x + i<0 || x + i>8 || y + j<0 || y + j >8)//中心点周围的9宫格位置有些元素不在地图内时
continue;//直接跳过
// 不能是自己
if (i == 0 && j == 0)//遍历九宫格嘛,中间的元素是自己,所以也直接跳过了
continue;
if (map[x + i][y + j] == 9)//当找到一个9时,说明找到一个炸弹
count++;//count自增
}
}
return count;//将count返回出去
}
getCountOfMineForPos函数用于获取指定位置雷的数量
三、渲染地图
void renderMap()
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (flagMap[i][j] == 0)//如果这个格子没有被翻开
cout << "■";
else if (flagMap[i][j] == 1)// 如果这个格子被翻开了
{
if (map[i][j] == 0)//元素是0,表示周围没有炸弹
cout << " ";
else if (map[i][j] == 9)//表示这个格子是炸弹
cout << "☆";
else
cout << map[i][j] << " ";//其余的情况也就是1到8,表示的是周围的炸弹数,那么直接输出这个数字就好了
}
}
cout << endl;
}
}
四、f函数
void f(int x, int y)
{
map[x][y] = getCountOfMineForPos(x, y);//调用了getCountOfMineForPos函数
if (map[x][y] == 0)//这个点周围没有一个雷
{
flagMap[x][y] = 1;//将格子翻开
for (int i = x - 1; i < x + 1; i++)
{
for (int j = y - 1; j < y + 1; j++)//同样,遍历9宫格的位置
{
if (x == i && y == j)//跳过自己的位置
continue;
if (i<0 || i >8 || j<0 || j>8)//出界的位置也跳过
continue;
else if (map[i][j] == 0)//当周围9宫格内的某个元素t也为0时,也就是t的9宫格内也没有雷
{
flagMap[i][j] = 1;//将这个格子翻开
f(i, j);//再执行t的f函数
}
else
{
continue;
}
}
}
}
}
f函数是一个递归函数,是用于格子的递归展开,就是一个点被翻开周围没有雷,那么对这个点周围的元素进行遍历,和它情况一样的都翻开
四、游戏更新
void GameUpdate()
{
int x, y;
cin >> x >> y;
// 1.判断是不是雷,是雷游戏结束
if (map[x][y] == 9)//翻到的是雷
{
// 显示所有的雷
boom();
//
cout << "Game Over~~~" << endl;//输出游戏结束
isOver = true;
}
else//翻到不是雷
{
flagMap[x][y] = 1;//将格子翻开
f(x, y);//调用f函数
}
}
上面用到的boom函数,就是当你翻到雷的时候,游戏失败了,显示出所有的雷
void boom()
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (map[i][j] == 9)
flagMap[i][j] = 1;
}
}
}
五、头文件和main函数
// 游戏初始化
void GameInit();
// 游戏渲染
void GameRender();
// 游戏更新
void GameUpdate();
// 设置雷
void setMine();
// 初始化地图
void initMap();
// 获取指定位置周围雷的数量
int getCountOfMineForPos(int x, int y);
// 渲染地图
void renderMap();
// 翻开所有的雷
void boom();//显示所有炸弹,游戏结束
void f(int x,int y);//方块的蔓延
void game();//进行游戏
int main()
{
srand(time(nullptr));
int input = 0;
do{
cout << "*************************" << endl;
cout << "****1.开始游戏 2.清屏 ***" << endl;
cout << "**** 3.退出游戏 ***" << endl;
cout << "*************************" << endl;
cin >> input;
switch (input)
{
case 1:
game();
return 0;
break;
case 2:
system("cls");
break;
case 3:cout << "退出游戏" << endl;
return 0;
break;
default:
cout << "请重新输入" << endl;
Sleep(1000);
system("cls");
break;
}
} while (input);
}
六、总结
天气太热了,就直接把代码的整体发一下把
#include <iostream>
using namespace std;
#include "czl.h"
#include <time.h>
#include<Windows.h>
//0~8表示周围雷的数量 9表示雷
//标记:1:翻开 0:未翻开
int map[9][9]; // 地图数据
int flagMap[9][9]; // 标记数组,标记当前点是否被翻开
bool isOver = false;
// 初始化地图
void initMap()
{
// 初始化标记数组
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
flagMap[i][j] = 0;
}
}
// 初始化地图数据
setMine();
}
// 设置雷
void setMine()
{
// 布雷
int countOfMine = 10;
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (countOfMine>0)
{
map[i][j] = 9;
countOfMine--;
}
else
{
map[i][j] = 0;
}
}
}
// 打乱顺序
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
int x = rand() % 9;
int y = rand() % 9;
int temp = map[i][j];
map[i][j] = map[x][y];
map[x][y] = temp;
}
}
// 计算每一个点周围雷的数量
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (map[i][j] != 9)
{
map[i][j] = getCountOfMineForPos(i, j);
}
}
}
}
// 获取指定位置周围雷的数量
int getCountOfMineForPos(int x, int y)
{
int count = 0;
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
// 不能越界
if (x + i<0 || x + i>8 || y + j<0 || y + j >8)
continue;
// 不能是自己
if (i == 0 && j == 0)
continue;
if (map[x + i][y + j] == 9)
count++;
}
}
return count;
}
// 渲染地图
void renderMap()
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (flagMap[i][j] == 0)// 未翻开
cout << "■";
else if (flagMap[i][j] == 1)// 翻开
{
if (map[i][j] == 0)
cout << " ";
else if (map[i][j] == 9)
cout << "☆";
else
cout << map[i][j] << " ";
}
}
cout << endl;
}
}
// 游戏初始化
void GameInit()
{
initMap();
}
void GameRender()
{
system("CLS");
renderMap();
}
// 游戏更新
void GameUpdate()
{
int x, y;
cin >> x >> y;
// 1.判断是不是雷,是雷游戏结束
if (map[x][y] == 9)
{
// 显示所有的雷
boom();
cout << "Game Over~~~" << endl;
isOver = true;
}
else
{
flagMap[x][y] = 1;
f(x, y);
}
}
void f(int x, int y)
{
map[x][y] = getCountOfMineForPos(x, y);
if (map[x][y] == 0)
{
flagMap[x][y] = 1;
for (int i = x - 1; i < x + 1; i++)
{
for (int j = y - 1; j < y + 1; j++)
{
if (x == i && y == j)
continue;
if (i<0 || i >8 || j<0 || j>8)
continue;
else if (map[i][j] == 0)
{
flagMap[i][j] = 1;
f(i, j);
}
else
{
continue;
}
}
}
}
}
void boom()
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (map[i][j] == 9)
flagMap[i][j] = 1;
}
}
}
void game()
{
GameInit();
GameRender();
while (!isOver)
{
GameUpdate();
GameRender();
}
system("pause");
}
int main()
{
srand(time(nullptr));
int input = 0;
do{
cout << "*************************" << endl;
cout << "****1.开始游戏 2.清屏 ***" << endl;
cout << "**** 3.退出游戏 ***" << endl;
cout << "*************************" << endl;
cin >> input;
switch (input)
{
case 1:
game();
return 0;
break;
case 2:
system("cls");
break;
case 3:cout << "退出游戏" << endl;
return 0;
break;
default:
cout << "请重新输入" << endl;
Sleep(1000);
system("cls");
break;
}
} while (input);
}
洗澡休息去了,这两天更新一下笔记,然后把自己写的魔塔游戏的项目也发一下,c++萌新,不足和错误还希望各位多多指出