扫雷游戏
题目描述: 开发一个简单的扫雷游戏,支持以下功能:
- 初始化游戏板,随机放置地雷。
- 用户选择一个格子进行挖掘。
- 如果用户挖到地雷,游戏结束。
- 如果用户挖到空格子,显示相邻的空格子。
- 用户可以选择标记地雷。
- 显示游戏板的状态。
- 用户可以选择重新开始游戏或退出游戏。
要求:
- 使用二维数组来表示游戏板。
- 使用随机数生成函数来放置地雷。
- 提供友好的用户界面,使用菜单选择功能。
示例代码框架
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <iomanip>
using namespace std;const int BOARD_SIZE = 10;
const int NUM_MINES = 15;enum CellState {HIDDEN,VISIBLE,FLAGGED
};struct Cell {bool isMine;int mineCount;CellState state;
};class Minesweeper {
private:vector<vector<Cell>> board;int minesLeft;public:Minesweeper() : board(BOARD_SIZE, vector<Cell>(BOARD_SIZE, {false, 0, HIDDEN})), minesLeft(NUM_MINES) {initializeBoard();}void initializeBoard() {srand(time(0)); // 初始化随机数生成器int placedMines = 0;while (placedMines < NUM_MINES) {int x = rand() % BOARD_SIZE;int y = rand() % BOARD_SIZE;if (!board[x][y].isMine) {board[x][y].isMine = true;placedMines++;}}calculateMineCounts();}void calculateMineCounts() {for (int i = 0; i < BOARD_SIZE; ++i) {for (int j = 0; j < BOARD_SIZE; ++j) {if (!board[i][j].isMine) {board[i][j].mineCount = countAdjacentMines(i, j);}}}}int countAdjacentMines(int x, int y) {int count = 0;for (int dx = -1; dx <= 1; ++dx) {for (int dy = -1; dy <= 1; ++dy) {if (dx == 0 && dy == 0) continue;int nx = x + dx;int ny = y + dy;if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny].isMine) {count++;}}}return count;}void displayBoard(bool reveal = false) {cout << " ";for (int i = 0; i < BOARD_SIZE; ++i) {cout << setw(3) << i;}cout << endl;for (int i = 0; i < BOARD_SIZE; ++i) {cout << i << " ";for (int j = 0; j < BOARD_SIZE; ++j) {if (reveal || board[i][j].state == VISIBLE) {if (board[i][j].isMine) {cout << setw(3) << "*";} else if (board[i][j].mineCount > 0) {cout << setw(3) << board[i][j].mineCount;} else {cout << setw(3) << "-";}} else if (board[i][j].state == FLAGGED) {cout << setw(3) << "F";} else {cout << setw(3) << "#";}}cout << endl;}}bool makeMove(int x, int y) {if (board[x][y].state == VISIBLE) {cout << "该位置已经挖过。\n";return false;}if (board[x][y].isMine) {cout << "游戏结束!你挖到了地雷。\n";displayBoard(true);return true;}revealCells(x, y);return false;}void revealCells(int x, int y) {if (x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE || board[x][y].state == VISIBLE) {return;}board[x][y].state = VISIBLE;if (board[x][y].mineCount == 0) {for (int dx = -1; dx <= 1; ++dx) {for (int dy = -1; dy <= 1; ++dy) {if (dx == 0 && dy == 0) continue;revealCells(x + dx, y + dy);}}}}void flagCell(int x, int y) {if (board[x][y].state == VISIBLE) {cout << "该位置已经挖过,不能标记。\n";return;}if (board[x][y].state == FLAGGED) {board[x][y].state = HIDDEN;minesLeft++;} else {board[x][y].state = FLAGGED;minesLeft--;}}bool checkWin() {for (int i = 0; i < BOARD_SIZE; ++i) {for (int j = 0; j < BOARD_SIZE; ++j) {if (!board[i][j].isMine && board[i][j].state != VISIBLE) {return false;}}}return true;}
};void showMenu() {cout << "1. 挖掘格子\n";cout << "2. 标记地雷\n";cout << "3. 重新开始游戏\n";cout << "0. 退出游戏\n";
}int main() {Minesweeper game;int choice, x, y;do {game.displayBoard();showMenu();cout << "请选择操作: ";cin >> choice;switch (choice) {case 1:cout << "请输入要挖掘的格子坐标 (x y): ";cin >> x >> y;if (game.makeMove(x, y)) {cout << "游戏结束!\n";choice = 0;} else if (game.checkWin()) {cout << "恭喜你,你赢了!\n";choice = 0;}break;case 2:cout << "请输入要标记的格子坐标 (x y): ";cin >> x >> y;game.flagCell(x, y);break;case 3:game = Minesweeper();cout << "游戏重新开始。\n";break;case 0:cout << "退出游戏。\n";break;default:cout << "无效的选择,请重新输入。\n";}} while (choice != 0);return 0;
}
项目说明
-
初始化游戏板:
initializeBoard
方法随机放置地雷。calculateMineCounts
方法计算每个格子周围地雷的数量。
-
显示游戏板:
displayBoard
方法显示当前游戏板的状态,可以选择是否显示所有地雷。
-
用户操作:
makeMove
方法处理用户的挖掘操作。flagCell
方法处理用户的标记操作。revealCells
方法递归地显示相邻的空格子。
-
游戏逻辑:
checkWin
方法检查用户是否赢得了游戏。- 主循环根据用户选择调用相应的功能。