c++扫雷教程
时间: 2023-07-24 22:04:52 浏览: 60
下面是一个基于控制台的简单扫雷游戏的 C++ 实现。这个游戏是一个经典的单人游戏,目标是在避免踩雷的情况下清理所有的方块。
```c++
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
using namespace std;
// 游戏难度常量
const int EASY = 10;
const int MEDIUM = 20;
const int HARD = 30;
// 方块类型常量
const char COVERED = '-';
const char UNCOVERED = ' ';
const char FLAGGED = 'F';
// 方块结构体
struct Square {
bool isMine;
int nearbyMines;
char display;
};
// 游戏类
class Minesweeper {
public:
Minesweeper(int difficulty);
void play();
private:
void printBoard();
bool isWin();
bool isLose(int row, int col);
void uncover(int row, int col);
void flag(int row, int col);
int numMines;
vector<vector<Square>> board;
};
// 构造函数
Minesweeper::Minesweeper(int difficulty) {
// 初始化随机数生成器
srand(time(nullptr));
// 根据难度设置雷数
switch (difficulty) {
case EASY:
numMines = 10;
break;
case MEDIUM:
numMines = 40;
break;
case HARD:
numMines = 99;
break;
}
// 初始化棋盘
for (int i = 0; i < difficulty; i++) {
vector<Square> row(difficulty);
for (int j = 0; j < difficulty; j++) {
row[j].isMine = false;
row[j].nearbyMines = 0;
row[j].display = COVERED;
}
board.push_back(row);
}
// 随机分布雷
int count = 0;
while (count < numMines) {
int row = rand() % difficulty;
int col = rand() % difficulty;
if (!board[row][col].isMine) {
board[row][col].isMine = true;
count++;
}
}
// 计算每个方块周围雷的数量
for (int i = 0; i < difficulty; i++) {
for (int j = 0; j < difficulty; j++) {
if (!board[i][j].isMine) {
int count = 0;
for (int k = -1; k <= 1; k++) {
for (int l = -1; l <= 1; l++) {
if (i+k >= 0 && i+k < difficulty && j+l >= 0 && j+l < difficulty) {
if (board[i+k][j+l].isMine) {
count++;
}
}
}
}
board[i][j].nearbyMines = count;
}
}
}
}
// 打印棋盘
void Minesweeper::printBoard() {
cout << " ";
for (int i = 0; i < board.size(); i++) {
cout << i << " ";
}
cout << endl;
for (int i = 0; i < board.size(); i++) {
cout << i << " ";
for (int j = 0; j < board.size(); j++) {
cout << board[i][j].display << " ";
}
cout << endl;
}
}
// 判断是否胜利
bool Minesweeper::isWin() {
int count = 0;
for (int i = 0; i < board.size(); i++) {
for (int j = 0; j < board.size(); j++) {
if (board[i][j].isMine) {
if (board[i][j].display == FLAGGED) {
count++;
}
} else {
if (board[i][j].display == UNCOVERED) {
count++;
}
}
}
}
return count == board.size() * board.size() - numMines;
}
// 判断是否踩雷
bool Minesweeper::isLose(int row, int col) {
return board[row][col].isMine;
}
// 揭开方块
void Minesweeper::uncover(int row, int col) {
if (row < 0 || row >= board.size() || col < 0 || col >= board.size()) {
return;
}
if (board[row][col].display != COVERED) {
return;
}
board[row][col].display = UNCOVERED;
if (board[row][col].isMine) {
return;
}
if (board[row][col].nearbyMines == 0) {
uncover(row-1, col-1);
uncover(row-1, col);
uncover(row-1, col+1);
uncover(row, col-1);
uncover(row, col+1);
uncover(row+1, col-1);
uncover(row+1, col);
uncover(row+1, col+1);
}
}
// 标记方块
void Minesweeper::flag(int row, int col) {
if (board[row][col].display == COVERED) {
board[row][col].display = FLAGGED;
} else if (board[row][col].display == FLAGGED) {
board[row][col].display = COVERED;
}
}
// 游戏主函数
void Minesweeper::play() {
bool gameover = false;
while (!gameover) {
printBoard();
cout << endl;
cout << "Enter row and column (e.g. 2 3) or 'f' to flag: ";
char c;
cin >> c;
if (c == 'f') {
int row, col;
cout << "Enter row and column (e.g. 2 3): ";
cin >> row >> col;
flag(row, col);
} else {
int row = c - '0';
int col;
cin >> col;
uncover(row, col);
if (isLose(row, col)) {
printBoard();
cout << "You lose!" << endl;
gameover = true;
} else if (isWin()) {
printBoard();
cout << "You win!" << endl;
gameover = true;
}
}
}
}
// 主函数
int main() {
int difficulty;
cout << "Select difficulty (10 for easy, 20 for medium, 30 for hard): ";
cin >> difficulty;
Minesweeper game(difficulty);
game.play();
return 0;
}
```
在这个实现中,我们首先定义了一个 `Square` 结构体,表示一个方块。其中 `isMine` 表示是否有雷,`nearbyMines` 表示周围雷的数量,`display` 表示方块的显示状态。
然后我们定义了一个 `Minesweeper` 类,表示扫雷游戏。在构造函数中,我们根据难度设置雷数,并随机分布雷。然后计算每个方块周围雷的数量。在主函数中,我们让用户选择游戏难度,并开始游戏。
在游戏过程中,我们通过 `printBoard` 函数打印棋盘,让用户输入行和列号或者 'f' 标记方块。如果用户选择揭开方块,则我们通过 `uncover` 函数递归地揭开周围没有雷的方块,直到遇到有雷的方块或者边界。如果用户选择标记方块,则我们通过 `flag` 函数将方块标记为旗帜或覆盖状态。当用户揭开有雷的方块时,游戏失败,当用户揭开所有没有雷的方块时,游戏胜利。