21xrx.com
2025-06-27 13:31:28 Friday
文章检索 我的文章 写文章
C++扫雷游戏的源代码
2023-07-04 19:09:30 深夜i     29     0
C++ 扫雷游戏 源代码 游戏开发 编程技术

C++扫雷游戏是一款经典的益智游戏,可以锻炼玩家的观察力和反应能力。今天我们来分享一下它的源代码,以便初学者学习和参考。以下是C++扫雷游戏的源代码:

#include<iostream>
#include<time.h>
#include<stdlib.h>
#include<conio.h>
using namespace std;
/*游戏状态*/
const int PLAYING = 0;
const int WIN = 1;
const int LOSE = 2;
/*标记状态*/
const int UNKNOW = -1;
const int MINE = -2;
const int FLAG = -3;
/*方向数组*/
const int dx[8] = 0;
const int dy[8] = -1;
/*扫雷游戏类*/
class Minesweeper
{
public:
  Minesweeper(int row, int col, int mine_num);//构造函数
  ~Minesweeper();//析构函数
  bool open(int x, int y);//打开一个方块
  void flag(int x, int y);//标记一个方块
  void draw();//绘制游戏界面
  int get_status();//获取游戏状态
private:
  int row_, col_;
  int mine_num_;
  int opened_count_;
  int **mine_map_;
  int **board_;
  int game_status_;
  void dfs(int x, int y);//扫雷算法的核心
  void create_mine();//随机生成地图上的地雷
  bool is_valid(int x, int y);//判断坐标是否合法
};
/*构造函数*/
Minesweeper::Minesweeper(int row, int col, int mine_num)
{
  //初始化私有成员变量
  row_ = row;
  col_ = col;
  mine_num_ = mine_num;
  opened_count_ = 0;
  game_status_ = PLAYING;
  //创建地图
  mine_map_ = new int*[row_];
  board_ = new int*[row_];
  for(int i = 0; i < row_; i++)
  {
    mine_map_[i] = new int[col_];
    board_[i] = new int[col_];
    for(int j = 0; j < col_; j++)
    {
      mine_map_[i][j] = UNKNOW;
      board_[i][j] = UNKNOW;
    }
  }
  //生成地雷
  create_mine();
}
/*析构函数*/
Minesweeper::~Minesweeper()
{
  //释放动态分配的内存
  for(int i = 0; i < row_; i++)
  {
    delete[]mine_map_[i];
    delete[]board_[i];
  }
  delete[]mine_map_;
  delete[]board_;
}
/*打开一个方块*/
bool Minesweeper::open(int x, int y)
{
  if(!is_valid(x, y))//判断坐标是否合法
    return false;
  if(board_[x][y] == FLAG)//判断当前方块是否被标记
    return false;
  if(mine_map_[x][y] == MINE)//判断是否踩到雷
  {
    game_status_ = LOSE;//游戏结束
    return true;
  }
  if(board_[x][y] != UNKNOW)//判断当前方块是否已经被打开
    return false;
  dfs(x, y);//调用扫雷算法
  return true;
}
/*标记一个方块*/
void Minesweeper::flag(int x, int y)
{
  if(!is_valid(x, y))//判断坐标是否合法
    return;
  if(board_[x][y] == UNKNOW)//判断当前方块是否已经被打开
    board_[x][y] = FLAG;//标记当前方块
  else
    board_[x][y] = UNKNOW;//取消标记当前方块
}
/*获取游戏状态*/
int Minesweeper::get_status()
{
  if(game_status_ == LOSE)//判断是否踩雷
    return LOSE;
  if(opened_count_ == row_ * col_ - mine_num_)//判断是否胜利
    return WIN;
  return PLAYING;
}
/*绘制游戏界面*/
void Minesweeper::draw()
{
  system("cls");//清空屏幕
  cout<<"扫雷游戏"<<endl;
  cout<<"状态: ";
  if(game_status_ == PLAYING)
    cout<<"进行中"<<endl;
  if(game_status_ == WIN)
    cout<<"你赢了"<<endl;
  if(game_status_ == LOSE)
    cout<<"你输了"<<endl;
  cout<<"还剩 "<<mine_num_<<" 个地雷"<<endl;
  //绘制地图
  for(int i = 0; i < row_; i++)
  {
    for(int j = 0; j < col_; j++)
    {
      if(board_[i][j] == UNKNOW)//未打开
        cout<<". ";
      else if(board_[i][j] == FLAG)//已经标记
        cout<<"F ";
      else if(mine_map_[i][j] == MINE)//是地雷
        cout<<"* ";
      else//周围有雷
        cout<<mine_map_[i][j]<<" ";
    }
    cout<<endl;
  }
}
/*扫雷算法的核心*/
void Minesweeper::dfs(int x, int y)
{
  if(!is_valid(x, y))//判断坐标是否合法
    return;
  if(board_[x][y] != UNKNOW)//判断是否已经被打开
    return;
  if(mine_map_[x][y] == MINE)//判断是否是地雷
    return;
  int count = 0;//周围有多少个地雷
  for(int i = 0; i < 8; i++)
  {
    int nx = x + dx[i];
    int ny = y + dy[i];
    if(is_valid(nx, ny) && mine_map_[nx][ny] == MINE)
      count++;
  }
  board_[x][y] = count;//打开当前方块
  opened_count_++;//已经打开的方块数加1
  if(count == 0)//如果周围没有地雷
  {
    for(int i = 0; i < 8; i++)
    {
      int nx = x + dx[i];
      int ny = y + dy[i];
      dfs(nx, ny);//继续搜索周围的方块
    }
  }
}
/*随机生成地图上的地雷*/
void Minesweeper::create_mine()
{
  srand(time(NULL));//用系统时间来初始化随机种子
  for(int i = 0; i < mine_num_; i++)
  {
    int x = rand() % row_;//随机生成横坐标
    int y = rand() % col_;//随机生成纵坐标
    if(mine_map_[x][y] == MINE)//如果已经是地雷了
    {
      i--;//继续生成
      continue;
    }
    mine_map_[x][y] = MINE;//将该方块设为地雷
    for(int j = 0; j < 8; j++)//更新周围方块的地雷数
    {
      int nx = x + dx[j];
      int ny = y + dy[j];
      if(is_valid(nx, ny) && mine_map_[nx][ny] != MINE)
        mine_map_[nx][ny]++;
    }
  }
}
/*判断坐标是否合法*/
bool Minesweeper::is_valid(int x, int y)
{
  if(x >= 0 && x < row_ && y >= 0 && y < col_)
    return true;
  return false;
}
/*主函数*/
int main()
{
  int row = 10;//地图的行数
  int col = 10;//地图的列数
  int mine_num = 10;//地雷的个数
  Minesweeper game(row, col, mine_num);//创建游戏对象
  game.draw();//绘制初始界面
  while(game.get_status() == PLAYING)//游戏进行中
  {
    //输入坐标和操作
    int x, y, op;
    cout<<"请输入坐标和操作(1表示打开,2表示标记): ";
    cin>>x>>y>>op;
    if(op == 1)//打开当前方块
      game.open(x, y);
    else if(op == 2)//标记当前方块
      game.flag(x, y);
    game.draw();//绘制当前界面
  }
  game.draw();//绘制最终界面
  return 0;
}

以上是C++扫雷游戏的源代码,大家可以根据自己的需要进行修改和优化。希望这篇文章对大家有所帮助。

  
  

评论区