C++制作迷宫第一版

#include <iostream>

#include <vector>

#include <cstdlib>

#include <ctime>

#include <stack>

#include <queue>

#include <windows.h>

#include <conio.h>

using namespace std;

const char WALL = '█';

const char PATH = ' ';

const char PLAYER = 'P';

const char EXIT = 'E';

const char VISITED = '.';

const char SOLUTION = 'o';

class MazeGenerator {

private:

int width, height;

vector<vector<char>> maze;

// 检查边界

bool inBounds(int x, int y) {

return x >= 0 && x < width && y >= 0 && y < height;

}

// 获取邻居单元格

vector<pair<int, int>> getNeighbors(int x, int y) {

vector<pair<int, int>> neighbors;

int directions[4][2] = {{0, -2}, {2, 0}, {0, 2}, {-2, 0}};

for (auto dir : directions) {

int nx = x + dir[0];

int ny = y + dir[1];

if (inBounds(nx, ny) && maze[ny][nx] == WALL) {

neighbors.push_back({nx, ny});

}

}

return neighbors;

}

public:

MazeGenerator(int w, int h) : width(w), height(h) {

// 确保尺寸为奇数

if (width % 2 == 0) width++;

if (height % 2 == 0) height++;

maze.resize(height, vector<char>(width, WALL));

}

// 使用深度优先搜索生成迷宫

void generateDFS(int startX = 1, int startY = 1) {

srand(time(nullptr));

stack<pair<int, int>> cellStack;

maze[startY][startX] = PATH;

cellStack.push({startX, startY});

while (!cellStack.empty()) {

auto current = cellStack.top();

int x = current.first;

int y = current.second;

auto neighbors = getNeighbors(x, y);

if (!neighbors.empty()) {

// 随机选择一个邻居

int index = rand() % neighbors.size();

int nx = neighbors[index].first;

int ny = neighbors[index].second;

// 打通墙壁

int wallX = (x + nx) / 2;

int wallY = (y + ny) / 2;

maze[wallY][wallX] = PATH;

maze[ny][nx] = PATH;

cellStack.push({nx, ny});

} else {

cellStack.pop();

}

}

// 设置入口和出口

maze[1][0] = PATH; // 入口

maze[height - 2][width - 1] = PATH; // 出口

}

vector<vector<char>> getMaze() {

return maze;

}

void printMaze() {

for (const auto& row : maze) {

for (char cell : row) {

cout << cell;

}

cout << endl;

}

}

};

class AdvancedMazeGame {

private:

vector<vector<char>> maze;

int playerX, playerY;

int exitX, exitY;

int moves;

bool gameWon;

bool showSolution;

void gotoxy(int x, int y) {

COORD coord;

coord.X = x;

coord.Y = y;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

}

void setColor(int color) {

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);

}

// 寻找最短路径(BFS)

vector<pair<int, int>> findShortestPath() {

vector<pair<int, int>> path;

int rows = maze.size();

int cols = maze[0].size();

vector<vector<bool>> visited(rows, vector<bool>(cols, false));

vector<vector<pair<int, int>>> parent(rows, vector<pair<int, int>>(cols, {-1, -1}));

queue<pair<int, int>> q;

q.push({playerX, playerY});

visited[playerY][playerX] = true;

int dx[4] = {1, -1, 0, 0};

int dy[4] = {0, 0, 1, -1};

while (!q.empty()) {

auto current = q.front();

q.pop();

int x = current.first;

int y = current.second;

if (x == exitX && y == exitY) {

// 重构路径

while (x != playerX || y != playerY) {

path.push_back({x, y});

auto p = parent[y][x];

x = p.first;

y = p.second;

}

reverse(path.begin(), path.end());

return path;

}

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

int nx = x + dx[i];

int ny = y + dy[i];

if (nx >= 0 && nx < cols && ny >= 0 && ny < rows &&

maze[ny][nx] != WALL && !visited[ny][nx]) {

visited[ny][nx] = true;

parent[ny][nx] = {x, y};

q.push({nx, ny});

}

}

}

return path;

}

public:

AdvancedMazeGame(int width = 21, int height = 21) {

// 生成随机迷宫

MazeGenerator generator(width, height);

generator.generateDFS();

maze = generator.getMaze();

// 设置玩家位置(入口)

playerX = 0;

playerY = 1;

// 设置出口位置

exitX = width - 1;

exitY = height - 2;

moves = 0;

gameWon = false;

showSolution = false;

// 确保玩家和出口位置正确

maze[playerY][playerX] = PLAYER;

maze[exitY][exitX] = EXIT;

}

void drawMaze() {

system("cls");

cout << "=== 高级迷宫游戏 ===" << endl;

cout << "控制: WASD移动, H显示提示, Q退出" << endl;

cout << "移动次数: " << moves;

if (showSolution) {

cout << " (显示提示中)";

}

cout << endl << endl;

vector<pair<int, int>> solutionPath;

if (showSolution) {

solutionPath = findShortestPath();

}

for (int i = 0; i < maze.size(); i++) {

for (int j = 0; j < maze[i].size(); j++) {

bool isSolutionPath = false;

if (showSolution) {

for (const auto& point : solutionPath) {

if (point.first == j && point.second == i) {

isSolutionPath = true;

break;

}

}

}

if (i == playerY && j == playerX) {

setColor(10); // 玩家 - 亮绿色

cout << PLAYER;

} else if (i == exitY && j == exitX) {

setColor(12); // 出口 - 亮红色

cout << EXIT;

} else if (isSolutionPath) {

setColor(11); // 解决方案路径 - 亮青色

cout << SOLUTION;

} else if (maze[i][j] == WALL) {

setColor(8); // 墙 - 灰色

cout << WALL;

} else if (maze[i][j] == VISITED) {

setColor(7); // 已访问路径 - 白色

cout << VISITED;

} else {

setColor(15); // 未访问路径 - 亮白色

cout << PATH;

}

setColor(7);

}

cout << endl;

}

if (gameWon) {

setColor(10);

cout << "\n🎉 恭喜通关! 🎉" << endl;

cout << "移动次数: " << moves << endl;

int minMoves = findShortestPath().size();

cout << "最短路径需要 " << minMoves << " 步" << endl;

if (moves == minMoves) {

cout << "完美!你找到了最短路径!" << endl;

} else if (moves <= minMoves * 1.5) {

cout << "优秀的表现!" << endl;

}

setColor(7);

}

}

bool movePlayer(int dx, int dy) {

int newX = playerX + dx;

int newY = playerY + dy;

if (newX >= 0 && newX < maze[0].size() &&

newY >= 0 && newY < maze.size() &&

maze[newY][newX] != WALL) {

maze[playerY][playerX] = VISITED;

playerX = newX;

playerY = newY;

moves++;

if (playerX == exitX && playerY == exitY) {

gameWon = true;

}

return true;

}

return false;

}

void run() {

char input;

while (true) {

drawMaze();

if (gameWon) {

cout << "\n按任意键退出...";

_getch();

break;

}

input = _getch();

switch (tolower(input)) {

case 'w': movePlayer(0, -1); break;

case 's': movePlayer(0, 1); break;

case 'a': movePlayer(-1, 0); break;

case 'd': movePlayer(1, 0); break;

case 'h':

showSolution = !showSolution;

if (showSolution) moves += 10; // 使用提示扣分

break;

case 'q': return;

default: break;

}

}

}

};

int main() {

cout << "选择迷宫大小:" << endl;
cout << "1. 小 (15x15)" << endl;
cout << "2. 中 (21x21)" << endl;
cout << "3. 大 (31x31)" << endl;
cout << "选择: ";
int choice;
cin >> choice;
int size;
switch (choice) {
case 1: size = 15; break;
case 2: size = 21; break;
case 3: size = 31; break;
default: size = 21; break;
}
AdvancedMazeGame game(size, size);
game.run();
return 0;
}

相关推荐
雪域迷影2 小时前
Windows11中VS2026使用C++ 现代化json库nlohmann的3种方式
开发语言·c++·json
羑悻的小杀马特2 小时前
LRU Cache:高频访问数据的“智能保鲜舱”与经典淘汰艺术
c++·后端·lru cache·热点数据与冷数据
zephyr052 小时前
C++ STL string 用法详解与示例
开发语言·c++
郝学胜-神的一滴2 小时前
Linux线程的共享资源与非共享资源详解
linux·服务器·开发语言·c++·程序人生·设计模式
郝学胜-神的一滴2 小时前
Linux进程与线程的区别:从内存三级映射角度深入解析
linux·服务器·c++·程序人生
默凉2 小时前
c++使用http发送图像
开发语言·c++·http
不爱吃糖的程序媛2 小时前
OpenHarmony PC 第三方 C/C++ 库适配完整指南
c语言·c++·harmonyos
雪域迷影2 小时前
nlohmann::json库对象和json结构体转换的新方式
c++·json·nlohmann_json库
CreasyChan2 小时前
3D游戏数学基础指南
游戏·3d·unity·数学基础