21xrx.com
2024-12-22 20:05:06 Sunday
登录
文章检索 我的文章 写文章
C++扫雷游戏的源代码
2023-07-04 19:09:30 深夜i     --     --
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++扫雷游戏的源代码,大家可以根据自己的需要进行修改和优化。希望这篇文章对大家有所帮助。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复