c++ 扫雷代码分享

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

扫雷这个游戏很多人都玩过,我是写这个项目之前没玩过,所以还专门去查了下扫雷的一些游戏规则,今天就分享一下我的代码把,用的是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++萌新,不足和错误还希望各位多多指出

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值