c++扫雷游戏

用c++写的扫雷

所需要的头文件:

#include <iostream>  
#include <vector>  
#include <cstdlib>  
#include <ctime>  
#include <windows.h>  
#include <limits>  

using namespace std;

 游戏各项参数:


// 默认的游戏参数  
int WIDTH = 10;   // 棋盘宽度  
int HEIGHT = 10;  // 棋盘高度  
int MINES = 10;   // 地雷数量  

enum Cell {  
	HIDDEN,  
	REVEALED,  
	MARKED  
};  

struct BoardCell {  
	int mineCount;  
	Cell state;  
	bool isMine;  
	
	BoardCell() : mineCount(0), state(HIDDEN), isMine(false) {}  
};

游戏类:


class Minesweeper {  
	public: 
	Minesweeper(int width, int height, int mines) : WIDTH(width), HEIGHT(height), MINES(mines) {  
		board.resize(HEIGHT, vector<BoardCell>(WIDTH));  
		placeMines();  
		calculateMineCounts();  
	}   
	
	void displayBoard(bool revealMines = false) {  
		cout << "     ";  
		for (int x = 0; x < WIDTH; x++) {  
			cout << x << "   ";  
		}  
		cout << endl;  
		
		for (int i = 0; i < HEIGHT; ++i) {  
			cout << ' ' << i << "   ";  
			for (int j = 0; j < WIDTH; ++j) {  
				printCell(board[i][j], revealMines);  
			}  
			cout << endl << endl;  
		}  
	}  
	
	void revealCell(int x, int y) {  
		if (isOutOfBounds(x, y) || board[y][x].state != HIDDEN) {  
			return;  
		}  
		
		board[y][x].state = REVEALED;  
		
		if (board[y][x].isMine) {  
			gameOver();  
			return;  
		}  
		
		if (board[y][x].mineCount == 0) {  
			// 递归揭示周围的单元格  
			for (int dy = -1; dy <= 1; ++dy) {  
				for (int dx = -1; dx <= 1; ++dx) {  
					revealCell(x + dx, y + dy);  
				}  
			}  
		}  
		
		checkVictory(); // 检查是否胜利  
	}  
	
	void markCell(int x, int y) {  
		if (isOutOfBounds(x, y) || board[y][x].state != HIDDEN) {  
			return;  
		}  
		board[y][x].state = MARKED;  
	}  
	
	void unmarkCell(int x, int y) {  
		if (isOutOfBounds(x, y) || board[y][x].state != MARKED) {  
			return;  
		}  
		board[y][x].state = HIDDEN;  
	}  
	private:  
	int WIDTH;  
	int HEIGHT;  
	int MINES;  
	vector<vector<BoardCell>> board;  
	
	
	void placeMines() {  
		int placedMines = 0;  
		while (placedMines < MINES) {  
			int x = rand() % WIDTH;  
			int y = rand() % HEIGHT;  
			if (!board[y][x].isMine) {  
				board[y][x].isMine = true;  
				placedMines++;  
			}  
		}  
	}  
	
	void calculateMineCounts() {  
		for (int y = 0; y < HEIGHT; ++y) {  
			for (int x = 0; x < WIDTH; ++x) {  
				if (board[y][x].isMine) {  
					continue;  
				}  
				int count = 0;  
				for (int dy = -1; dy <= 1; ++dy) {  
					for (int dx = -1; dx <= 1; ++dx) {  
						if (isOutOfBounds(x + dx, y + dy)) {  
							continue;  
						}  
						if (board[y + dy][x + dx].isMine) {  
							count++;  
						}  
					}  
				}  
				board[y][x].mineCount = count;  
			}  
		}  
	}  
	
	bool isOutOfBounds(int x, int y) {  
		return (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT);  
	}  
	
	void gameOver() {  
		system("cls");  
		cout << "Game Over! You hit a mine!" << endl;  
		displayBoard(true);  
		offerRestart();  
		system("cls");  
	}  
	
	void checkVictory() {  
		int revealedCells = 0;  
		int nonMineCells = WIDTH * HEIGHT - MINES;  
		
		for (int y = 0; y < HEIGHT; y++) {  
			for (int x = 0; x < WIDTH; x++) {  
				if (board[y][x].state == REVEALED) {  
					revealedCells++;  
				}  
			}  
		}  
		
		if (revealedCells == nonMineCells) {  
			system("cls");  
			cout << "Congratulations! You've revealed all cells without hitting a mine!" << endl;  
			displayBoard(true);  
			offerRestart();  
		}  
	}  
	
	void offerRestart() {  
		char response;  
		system("cls");  
		cout << "再来一次? (y/n): ";  
		cin >> response;  
		if (response == 'y' || response == 'Y') {  
			cout << "选择难度 (1 - 简单, 2 - 中等, 3 - 困难): ";  
			int difficulty;  
			
			cin >> difficulty;  
			setDifficulty(difficulty);  
			resetGame();  system("cls");  
		} else {  
			cout << "Thank you for playing!" << endl;  
			exit(0);  
		}  
	}  
	
	void resetGame() {  
		board.clear();  
		board.resize(HEIGHT, vector<BoardCell>(WIDTH));  
		placeMines();  
		calculateMineCounts();  
	}  
	
	void setDifficulty(int level) {  
		switch (level) {  
			case 1: // Easy  
			WIDTH = 8;  
			HEIGHT = 8;  
			MINES = 10;  
			break;  
			case 2: // Medium  
			WIDTH = 12;  
			HEIGHT = 12;  
			MINES = 30;  
			break;  
			case 3: // Hard  
			WIDTH = 16;  
			HEIGHT = 16;  
			MINES = 40;  
			break;  
			default:  
			WIDTH = 10;  
			HEIGHT = 10;  
			MINES = 10;  
			break;  
		}  
	}  
	
	void printCell(const BoardCell& cell, bool revealMines) {  
		HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);  
		if (cell.state == HIDDEN) {  
			SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);  
			cout << "+   ";  
		} else if (cell.state == REVEALED) {  
			if (cell.isMine) {  
				SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);  
				cout << "*   ";  // 地雷  
			} else {  
				if (cell.mineCount == 0) {  
					cout << "    ";  // 空白  
				} else {  
					cout << cell.mineCount << "   ";  // 显示周围地雷的数量  
				}  
			}  
		} else if (cell.state == MARKED) {  
			SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);  
			cout << "o   ";  // 标记  
		}  
		SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);  
	}  
}; 

主函数:


int main() {  
	system("cls");  
	cout << "扫雷游戏!" << endl;  
	
	// 选择难度  
	cout << "选择难度 (1 - 简单, 2 - 中等, 3 - 困难): "<<endl<<"请输入:";  
	int difficulty;  
	cin >> difficulty;  
	system("cls"); 
	int width, height, mines;  
	switch (difficulty) {  
		case 1: // Easy  
		width = 8; height = 8; mines = 10; break;  
		case 2: // Medium  
		width = 12; height = 12; mines = 30; break;  
		case 3: // Hard  
		width = 16; height = 16; mines = 40; break;  
		default:  
		width = 10; height = 10; mines = 10; break;  
	}  
	
	Minesweeper game(width, height, mines);  
	
	while (true) {  
		cout << "棋盘:" << endl << endl;  
		game.displayBoard();  
		cout << "输入 x y 去揭示格子,或 o x y 标注格子,q x y 去掉标注:";  
		
		string command;  
		cin >> command;  
		
		if (command == "o") {  
			int x, y;  
			cin >> x >> y;  
			game.markCell(x, y);  
		}
		else if (command == "q") {  
			int x, y;  
			cin >> x >> y;  
			game.unmarkCell(x, y);  
		}
		else {  
			try {  
				int x = stoi(command);  
				int y;  
				cin >> y;  
				game.revealCell(y, x);  
			} catch (const invalid_argument&) {  
				cout << "Invalid input, please enter valid coordinates." << endl;  
				cin.clear(); // Clear error flag  
				cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Clear input buffer  
			} catch (const out_of_range&) {  
				cout << "Input out of range, please enter valid coordinates." << endl;  
				cin.clear();  
				cin.ignore(numeric_limits<streamsize>::max(), '\n');  
			}  
		}  
		system("cls");  
	}  
	
	return 0;  
}  

 最终代码:

#include <iostream>  
#include <vector>  
#include <cstdlib>  
#include <ctime>  
#include <windows.h>  
#include <limits>  

using namespace std;  

// 默认的游戏参数  
int WIDTH = 10;   // 棋盘宽度  
int HEIGHT = 10;  // 棋盘高度  
int MINES = 10;   // 地雷数量  

enum Cell {  
	HIDDEN,  
	REVEALED,  
	MARKED  
};  

struct BoardCell {  
	int mineCount;  
	Cell state;  
	bool isMine;  
	
	BoardCell() : mineCount(0), state(HIDDEN), isMine(false) {}  
};  

class Minesweeper {  
	public: 
	Minesweeper(int width, int height, int mines) : WIDTH(width), HEIGHT(height), MINES(mines) {  
		board.resize(HEIGHT, vector<BoardCell>(WIDTH));  
		placeMines();  
		calculateMineCounts();  
	}   
	
	void displayBoard(bool revealMines = false) {  
		cout << "     ";  
		for (int x = 0; x < WIDTH; x++) {  
			cout << x << "   ";  
		}  
		cout << endl;  
		
		for (int i = 0; i < HEIGHT; ++i) {  
			cout << ' ' << i << "   ";  
			for (int j = 0; j < WIDTH; ++j) {  
				printCell(board[i][j], revealMines);  
			}  
			cout << endl << endl;  
		}  
	}  
	
	void revealCell(int x, int y) {  
		if (isOutOfBounds(x, y) || board[y][x].state != HIDDEN) {  
			return;  
		}  
		
		board[y][x].state = REVEALED;  
		
		if (board[y][x].isMine) {  
			gameOver();  
			return;  
		}  
		
		if (board[y][x].mineCount == 0) {  
			// 递归揭示周围的单元格  
			for (int dy = -1; dy <= 1; ++dy) {  
				for (int dx = -1; dx <= 1; ++dx) {  
					revealCell(x + dx, y + dy);  
				}  
			}  
		}  
		
		checkVictory(); // 检查是否胜利  
	}  
	
	void markCell(int x, int y) {  
		if (isOutOfBounds(x, y) || board[y][x].state != HIDDEN) {  
			return;  
		}  
		board[y][x].state = MARKED;  
	}  
	
	void unmarkCell(int x, int y) {  
		if (isOutOfBounds(x, y) || board[y][x].state != MARKED) {  
			return;  
		}  
		board[y][x].state = HIDDEN;  
	}  
	private:  
	int WIDTH;  
	int HEIGHT;  
	int MINES;  
	vector<vector<BoardCell>> board;  
	
	
	void placeMines() {  
		int placedMines = 0;  
		while (placedMines < MINES) {  
			int x = rand() % WIDTH;  
			int y = rand() % HEIGHT;  
			if (!board[y][x].isMine) {  
				board[y][x].isMine = true;  
				placedMines++;  
			}  
		}  
	}  
	
	void calculateMineCounts() {  
		for (int y = 0; y < HEIGHT; ++y) {  
			for (int x = 0; x < WIDTH; ++x) {  
				if (board[y][x].isMine) {  
					continue;  
				}  
				int count = 0;  
				for (int dy = -1; dy <= 1; ++dy) {  
					for (int dx = -1; dx <= 1; ++dx) {  
						if (isOutOfBounds(x + dx, y + dy)) {  
							continue;  
						}  
						if (board[y + dy][x + dx].isMine) {  
							count++;  
						}  
					}  
				}  
				board[y][x].mineCount = count;  
			}  
		}  
	}  
	
	bool isOutOfBounds(int x, int y) {  
		return (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT);  
	}  
	
	void gameOver() {  
		system("cls");  
		cout << "Game Over! You hit a mine!" << endl;  
		displayBoard(true);  
		offerRestart();  
		system("cls");  
	}  
	
	void checkVictory() {  
		int revealedCells = 0;  
		int nonMineCells = WIDTH * HEIGHT - MINES;  
		
		for (int y = 0; y < HEIGHT; y++) {  
			for (int x = 0; x < WIDTH; x++) {  
				if (board[y][x].state == REVEALED) {  
					revealedCells++;  
				}  
			}  
		}  
		
		if (revealedCells == nonMineCells) {  
			system("cls");  
			cout << "Congratulations! You've revealed all cells without hitting a mine!" << endl;  
			displayBoard(true);  
			offerRestart();  
		}  
	}  
	
	void offerRestart() {  
		char response;  
		system("cls");  
		cout << "再来一次? (y/n): ";  
		cin >> response;  
		if (response == 'y' || response == 'Y') {  
			cout << "选择难度 (1 - 简单, 2 - 中等, 3 - 困难): ";  
			int difficulty;  
			
			cin >> difficulty;  
			setDifficulty(difficulty);  
			resetGame();  system("cls");  
		} else {  
			cout << "Thank you for playing!" << endl;  
			exit(0);  
		}  
	}  
	
	void resetGame() {  
		board.clear();  
		board.resize(HEIGHT, vector<BoardCell>(WIDTH));  
		placeMines();  
		calculateMineCounts();  
	}  
	
	void setDifficulty(int level) {  
		switch (level) {  
			case 1: // Easy  
			WIDTH = 8;  
			HEIGHT = 8;  
			MINES = 10;  
			break;  
			case 2: // Medium  
			WIDTH = 12;  
			HEIGHT = 12;  
			MINES = 30;  
			break;  
			case 3: // Hard  
			WIDTH = 16;  
			HEIGHT = 16;  
			MINES = 40;  
			break;  
			default:  
			WIDTH = 10;  
			HEIGHT = 10;  
			MINES = 10;  
			break;  
		}  
	}  
	
	void printCell(const BoardCell& cell, bool revealMines) {  
		HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);  
		if (cell.state == HIDDEN) {  
			SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);  
			cout << "+   ";  
		} else if (cell.state == REVEALED) {  
			if (cell.isMine) {  
				SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);  
				cout << "*   ";  // 地雷  
			} else {  
				if (cell.mineCount == 0) {  
					cout << "    ";  // 空白  
				} else {  
					cout << cell.mineCount << "   ";  // 显示周围地雷的数量  
				}  
			}  
		} else if (cell.state == MARKED) {  
			SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);  
			cout << "o   ";  // 标记  
		}  
		SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);  
	}  
};  

int main() {  
	system("cls");  
	cout << "扫雷游戏!" << endl;  
	
	// 选择难度  
	cout << "选择难度 (1 - 简单, 2 - 中等, 3 - 困难): "<<endl<<"请输入:";  
	int difficulty;  
	cin >> difficulty;  
	system("cls"); 
	int width, height, mines;  
	switch (difficulty) {  
		case 1: // Easy  
		width = 8; height = 8; mines = 10; break;  
		case 2: // Medium  
		width = 12; height = 12; mines = 30; break;  
		case 3: // Hard  
		width = 16; height = 16; mines = 40; break;  
		default:  
		width = 10; height = 10; mines = 10; break;  
	}  
	
	Minesweeper game(width, height, mines);  
	
	while (true) {  
		cout << "棋盘:" << endl << endl;  
		game.displayBoard();  
		cout << "输入 x y 去揭示格子,或 o x y 标注格子,q x y 去掉标注:";  
		
		string command;  
		cin >> command;  
		
		if (command == "o") {  
			int x, y;  
			cin >> x >> y;  
			game.markCell(x, y);  
		}
		else if (command == "q") {  
			int x, y;  
			cin >> x >> y;  
			game.unmarkCell(x, y);  
		}
		else {  
			try {  
				int x = stoi(command);  
				int y;  
				cin >> y;  
				game.revealCell(y, x);  
			} catch (const invalid_argument&) {  
				cout << "Invalid input, please enter valid coordinates." << endl;  
				cin.clear(); // Clear error flag  
				cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Clear input buffer  
			} catch (const out_of_range&) {  
				cout << "Input out of range, please enter valid coordinates." << endl;  
				cin.clear();  
				cin.ignore(numeric_limits<streamsize>::max(), '\n');  
			}  
		}  
		system("cls");  
	}  
	
	return 0;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值