21xrx.com
2024-09-20 00:47:50 Friday
登录
文章检索 我的文章 写文章
C++代码设计:扫雷小游戏
2023-07-05 08:02:44 深夜i     --     --
C++ 代码设计 扫雷小游戏

扫雷是一款经典的小游戏,它要求玩家扫描地图中的方块,找出其中的地雷。在这个过程中,玩家需要运用自己的思考能力和逻辑推理能力,同时也可以享受到游戏所带来的乐趣和快感。在这篇文章中,我们将介绍如何使用C++编写一个简单的扫雷小游戏。

首先,我们需要设计一个地图类来表示游戏地图。这个类需要存储地图的大小、地雷的位置和每个方块的状态(是否已被扫描)。为了方便计算周围地雷数量,我们还需要在每个方块上记录它周围8个方块的位置。示例代码如下:


class Map {

public:

  Map(int width, int height, int bombNum); // 构造函数

  void print(); // 输出地图

  void showMap(); // 输出全部方块状态

  int check(int x, int y); // 检查是否点中地雷,返回周围8个地雷数量

  void flag(int x, int y); // 在指定位置标记地雷

  void open(int x, int y); // 打开指定位置的方块

private:

  int w, h, b;

  bool isOpened[MAXSIZE][MAXSIZE]; // 表示该位置是否已经被打开

  bool isBomb[MAXSIZE][MAXSIZE]; // 表示该位置是否是地雷

  bool isFlagged[MAXSIZE][MAXSIZE]; // 表示该位置是否被标记为地雷

  int nearbyBombNum[MAXSIZE][MAXSIZE][8]; // 每个位置周围地雷数量

};

接下来,我们需要在主函数中初始化地图,并搭建游戏循环。在游戏循环中,每次玩家输入一个坐标,我们就检查该位置是否是地雷。如果是地雷,则游戏结束;如果不是地雷,则打开该方块,并显示周围地雷数量。如果该方块周围没有地雷,则递归打开周围的方块,直到没有未被打开的方块为止。示例代码如下:


int main() {

  Map map(WIDTH, HEIGHT, BOMB_NUM);

  while (true) {

    map.print();

    int x, y;

    cout << "Please input row and column: ";

    cin >> x >> y;

    x--, y--;

    if (map.check(x, y) == -1) {

      cout << "Boom!" << endl;

      map.showMap();

      break;

    } else {

      map.open(x, y);

      if (map.check(x, y) == 0) {

        map.openNearby(x, y);

      }

      if (map.checkAll()) {

        map.showMap();

        cout << "Win!" << endl;

        break;

      }

    }

  }

  return 0;

}

最后,我们需要实现Map类中的各个函数。在构造函数中,我们首先确定地雷的位置,并计算每个方块周围8个方块的位置。接着,我们遍历每个方块,计算它周围的地雷数量。在检查函数中,我们只需要判断该位置是否是地雷,如果是地雷则返回-1,否则返回周围地雷数量。在标记函数中,我们只需要将该位置标记为地雷。在打开函数中,我们首先检查该位置是否已被打开,如果是,则直接返回;否则,如果该位置是地雷,则游戏结束;否则,我们将该位置打开,显示其周围地雷数量,并递归打开周围的方块。示例代码如下:


Map::Map(int width, int height, int bombNum) {

  memset(isOpened, false, sizeof(isOpened));

  memset(isBomb, false, sizeof(isBomb));

  memset(isFlagged, false, sizeof(isFlagged));

  memset(nearbyBombNum, 0, sizeof(nearbyBombNum));

  w = width;

  h = height;

  b = bombNum;

  int cnt = 0;

  while (cnt < bombNum) {

    int x = rand() % height, y = rand() % width;

    if (isBomb[x][y]) continue;

    isBomb[x][y] = true;

    cnt++;

  }

  for (int x = 0; x < height; x++) {

    for (int y = 0; y < width; y++) {

      for (int i = 0; i < 8; i++) {

        int nx = x + DX[i], ny = y + DY[i];

        if (nx < 0 || nx >= height || ny < 0 || ny >= width) continue;

        nearbyBombNum[x][y][i] = isBomb[nx][ny];

      }

    }

  }

  for (int x = 0; x < height; x++) {

    for (int y = 0; y < width; y++) {

      for (int i = 0; i < 8; i++) {

        nearbyBombNum[x][y][i + 8] = 0;

        int nx = x + DX[i], ny = y + DY[i];

        if (nx < 0 || nx >= height || ny < 0 || ny >= width) continue;

        for (int j = 0; j < 8; j++) {

          int mx = nx + DX[j], my = ny + DY[j];

          if (mx < 0 || mx >= height || my < 0 || my >= width) continue;

          nearbyBombNum[x][y][i + 8] += isBomb[mx][my];

        }

      }

    }

  }

}

void Map::print() {

  cout << "---";

  for (int j = 0; j < w; j++) {

    cout << j + 1 << "--";

  }

  cout << endl;

  for (int i = 0; i < h; i++) {

    cout << i + 1 << "|";

    for (int j = 0; j < w; j++) {

      if (isFlagged[i][j])

        cout << "F|";

      |

        cout << " |";

       else if (!isOpened[i][j])

        cout << "*|";

       |

        cout << nearbyBombNum[i][j][8] << "|";

       else if (isBomb[i][j])

        cout << "*|";

      *|

        cout << nearbyBombNum[i][j][8] << "|";

       else {

        cout << nearbyBombNum[i][j][8] << "|";

      }

    }

    cout << endl;

  }

  cout << endl;

}

void Map::showMap() {

  cout << "---";

  for (int j = 0; j < w; j++) {

    cout << j + 1 << "--";

  }

  cout << endl;

  for (int i = 0; i < h; i++) {

    cout << i + 1 << "|";

    for (int j = 0; j < w; j++) {

      if (isBomb[i][j]) {

        cout << "*|";

      } else {

        cout << nearbyBombNum[i][j][8] << "|";

      }

    }

    cout << endl;

  }

  cout << endl;

}

int Map::check(int x, int y) {

  if (isBomb[x][y]) return -1;

  int res = 0;

  for (int i = 0; i < 8; i++) {

    int nx = x + DX[i], ny = y + DY[i];

    if (nx < 0 || nx >= h || ny < 0 || ny >= w) continue;

    res += isBomb[nx][ny];

  }

  return res;

}

void Map::flag(int x, int y) {

  isFlagged[x][y] = true;

}

void Map::open(int x, int y) {

  if (isOpened[x][y]) return;

  isOpened[x][y] = true;

  if (isBomb[x][y]) return;

  print();

  if (nearbyBombNum[x][y][8] == 0) {

    openNearby(x, y);

  }

}

void Map::openNearby(int x, int y) {

  for (int i = 0; i < 8; i++) {

    int nx = x + DX[i], ny = y + DY[i];

    if (nx < 0 || nx >= h || ny < 0 || ny >= w) continue;

    open(nx, ny);

  }

}

bool Map::checkAll() {

  for (int i = 0; i < h; i++) {

    for (int j = 0; j < w; j++) {

      if (!isOpened[i][j] && !isBomb[i][j])

        return false;

      

    }

  }

  return true;

}

这样,我们就完成了一个简单的扫雷小游戏。通过这个小游戏的设计,我们可以提高自己的C++编程能力,并锻炼我们的思考和逻辑能力。相信这个小游戏会带给您许多快乐和挑战!

  
  
下一篇: C++代码合集

评论区

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