#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
using namespace std;
// 游戏配置(可自定义)
const int ROWS = 9; // 行数
const int COLS = 9; // 列数
const int MINE_COUNT = 10; // 地雷数量
// 地图状态枚举
enum CellState {
HIDDEN = -2, // 未揭开
FLAG = -3, // 标记为地雷
MINE = -1 // 地雷
};
// 全局变量
int gameMap[ROWS][COLS]; // 真实地图:-1=地雷,0-8=周围地雷数
int showMap[ROWS][COLS]; // 显示地图:-2=隐藏,-3=标记,0-8=显示数字
// 初始化游戏地图
void initMap() {
// 初始化两个地图
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
gameMap[i][j] = 0;
showMap[i][j] = HIDDEN;
}
}
// 随机生成地雷
srand(time(0));
int minePlaced = 0;
while (minePlaced < MINE_COUNT) {
int r = rand() % ROWS;
int c = rand() % COLS;
if (gameMap[r][c] != MINE) {
gameMap[r][c] = MINE;
minePlaced++;
}
}
// 计算每个位置周围的地雷数
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (gameMap[i][j] == MINE) continue;
int count = 0;
// 检查周围8个方向
for (int dr = -1; dr <= 1; dr++) {
for (int dc = -1; dc <= 1; dc++) {
if (dr == 0 && dc == 0) continue; // 跳过自己
int nr = i + dr;
int nc = j + dc;
// 检查边界
if (nr >= 0 && nr < ROWS && nc >= 0 && nc < COLS) {
if (gameMap[nr][nc] == MINE) {
count++;
}
}
}
}
gameMap[i][j] = count;
}
}
}
// 打印游戏界面
void printMap() {
system("cls"); // 清屏(Windows),Linux/Mac 用 "clear"
cout << "======= 扫雷游戏 =======" << endl;
cout << "操作说明:" << endl;
cout << "1. 揭开格子:输入 r c (行 列,从0开始)" << endl;
cout << "2. 标记/取消标记地雷:输入 f r c" << endl;
cout << "3. 退出游戏:输入 q" << endl;
cout << "========================" << endl;
// 打印列号
cout << " ";
for (int j = 0; j < COLS; j++) {
cout << setw(2) << j;
}
cout << endl;
// 打印行号和地图
for (int i = 0; i < ROWS; i++) {
cout << setw(2) << i << " ";
for (int j = 0; j < COLS; j++) {
switch (showMap[i][j]) {
case HIDDEN:
cout << "■ "; // 未揭开的格子
break;
case FLAG:
cout << "⚑ "; // 标记的地雷
break;
case 0:
cout << " "; // 空白(0个地雷)
break;
default:
cout << showMap[i][j] << " "; // 显示数字
break;
}
}
cout << endl;
}
}
// 递归展开空白区域
void expandArea(int r, int c) {
// 边界检查、已揭开、标记的格子不处理
if (r < 0 || r >= ROWS || c < 0 || c >= COLS ||
showMap[r][c] != HIDDEN || showMap[r][c] == FLAG) {
return;
}
// 显示当前格子
showMap[r][c] = gameMap[r][c];
// 如果是空白格(0),递归展开周围8个方向
if (gameMap[r][c] == 0) {
for (int dr = -1; dr <= 1; dr++) {
for (int dc = -1; dc <= 1; dc++) {
if (dr == 0 && dc == 0) continue;
expandArea(r + dr, c + dc);
}
}
}
}
// 检查游戏是否胜利
bool checkWin() {
int hiddenCount = 0;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
// 未揭开的格子数 == 地雷数 则胜利
if (showMap[i][j] == HIDDEN) {
hiddenCount++;
}
}
}
return hiddenCount == MINE_COUNT;
}
// 处理玩家输入
bool handleInput() {
char cmd;
cout << "\n请输入操作:";
cin >> cmd;
if (cmd == 'q' || cmd == 'Q') {
cout << "游戏退出!" << endl;
return false;
}
else if (cmd == 'f' || cmd == 'F') {
// 标记/取消标记地雷
int r, c;
cin >> r >> c;
if (r < 0 || r >= ROWS || c < 0 || c >= COLS) {
cout << "输入坐标超出范围!" << endl;
system("pause");
return true;
}
if (showMap[r][c] == HIDDEN) {
showMap[r][c] = FLAG; // 标记
}
else if (showMap[r][c] == FLAG) {
showMap[r][c] = HIDDEN; // 取消标记
}
else {
cout << "已揭开的格子不能标记!" << endl;
system("pause");
}
}
else if (isdigit(cmd)) {
// 揭开格子(输入格式:行 列)
int r = cmd - '0';
int c;
cin >> c;
if (r < 0 || r >= ROWS || c < 0 || c >= COLS) {
cout << "输入坐标超出范围!" << endl;
system("pause");
return true;
}
// 踩到地雷
if (gameMap[r][c] == MINE) {
// 显示所有地雷
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (gameMap[i][j] == MINE) {
showMap[i][j] = MINE;
}
}
}
printMap();
cout << "游戏结束!你踩到地雷了!" << endl;
return false;
}
// 揭开空白区域
if (showMap[r][c] == HIDDEN) {
expandArea(r, c);
}
// 检查胜利
if (checkWin()) {
printMap();
cout << "恭喜你!扫雷成功!" << endl;
return false;
}
}
else {
cout << "输入格式错误!请重新输入!" << endl;
system("pause");
}
return true;
}
// 主函数
int main() {
initMap();
bool isRunning = true;
while (isRunning) {
printMap();
isRunning = handleInput();
}
system("pause");
return 0;
}