设计异形迷宫,不同于传统的方形迷宫,异形迷宫 中每个迷宫单元是由相同的多边形组成,如图,是 一个六边形迷宫,每一个单元格与其它单元格最多 有六个通道可以连接。 1)自动生成并走出迷宫。 2)迷宫单元的边数由用户输入确定。c++语言
时间: 2024-05-09 16:15:00 浏览: 154
以下是一个简单的基于深度优先搜索算法的异形迷宫生成和求解程序,迷宫单元的边数由用户输入确定:
```c++
#include <iostream>
#include <stack>
#include <vector>
#include <random>
using namespace std;
// 定义迷宫单元格类
class Cell {
public:
int row, col; // 行和列
vector<Cell*> neighbors; // 邻居列表
bool visited; // 是否已访问
// 构造函数
Cell(int row, int col) {
this->row = row;
this->col = col;
visited = false;
}
// 添加邻居
void addNeighbor(Cell* neighbor) {
neighbors.push_back(neighbor);
}
// 获取未访问的邻居列表
vector<Cell*> getUnvisitedNeighbors() {
vector<Cell*> unvisitedNeighbors;
for (int i = 0; i < neighbors.size(); i++) {
if (!neighbors[i]->visited) {
unvisitedNeighbors.push_back(neighbors[i]);
}
}
return unvisitedNeighbors;
}
};
// 定义迷宫类
class Maze {
public:
int rows, cols; // 行和列
int numSides; // 每个单元格的边数
vector<vector<Cell>> cells; // 单元格矩阵
// 构造函数
Maze(int rows, int cols, int numSides) {
this->rows = rows;
this->cols = cols;
this->numSides = numSides;
// 初始化单元格矩阵
cells.resize(rows);
for (int i = 0; i < rows; i++) {
cells[i].resize(cols);
for (int j = 0; j < cols; j++) {
cells[i][j] = Cell(i, j);
}
}
// 建立邻居关系
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
for (int k = 0; k < numSides; k++) {
int neighborRow, neighborCol;
switch (numSides) {
case 3: // 三角形
if (k == 0) {
neighborRow = i - 1;
neighborCol = j;
} else if (k == 1) {
neighborRow = i;
neighborCol = j - 1;
} else {
neighborRow = i + 1;
neighborCol = j;
}
break;
case 4: // 正方形
if (k == 0) {
neighborRow = i - 1;
neighborCol = j;
} else if (k == 1) {
neighborRow = i;
neighborCol = j - 1;
} else if (k == 2) {
neighborRow = i + 1;
neighborCol = j;
} else {
neighborRow = i;
neighborCol = j + 1;
}
break;
case 6: // 六边形
if (k == 0) {
neighborRow = i - 1;
neighborCol = j;
} else if (k == 1) {
neighborRow = i - 1;
neighborCol = j + 1;
} else if (k == 2) {
neighborRow = i;
neighborCol = j + 1;
} else if (k == 3) {
neighborRow = i + 1;
neighborCol = j;
} else if (k == 4) {
neighborRow = i + 1;
neighborCol = j - 1;
} else {
neighborRow = i;
neighborCol = j - 1;
}
break;
}
if (neighborRow >= 0 && neighborRow < rows && neighborCol >= 0 && neighborCol < cols) {
cells[i][j].addNeighbor(&cells[neighborRow][neighborCol]);
}
}
}
}
}
// 随机生成迷宫
void generate() {
stack<Cell*> cellStack;
Cell* currentCell = &cells[0][0];
currentCell->visited = true;
while (true) {
vector<Cell*> unvisitedNeighbors = currentCell->getUnvisitedNeighbors();
if (!unvisitedNeighbors.empty()) {
// 随机选择一个未访问的邻居
int randIndex = rand() % unvisitedNeighbors.size();
Cell* neighborCell = unvisitedNeighbors[randIndex];
// 打通当前单元格和邻居单元格之间的墙
int wallIndex = 0;
for (int i = 0; i < currentCell->neighbors.size(); i++) {
if (currentCell->neighbors[i] == neighborCell) {
wallIndex = i;
break;
}
}
currentCell->neighbors[wallIndex] = nullptr;
int neighborWallIndex = (wallIndex + numSides / 2) % numSides;
neighborCell->neighbors[neighborWallIndex] = nullptr;
// 将邻居单元格入栈,并标记为已访问
cellStack.push(neighborCell);
neighborCell->visited = true;
// 更新当前单元格
currentCell = neighborCell;
} else if (!cellStack.empty()) {
// 回溯到上一个单元格
currentCell = cellStack.top();
cellStack.pop();
} else {
// 生成完成
break;
}
}
}
// 输出迷宫
void print() {
// 打印第一行墙
for (int j = 0; j < cols; j++) {
cout << "+";
if (cells[0][j].neighbors[0] != nullptr) {
cout << "-";
} else {
cout << " ";
}
}
cout << "+" << endl;
// 打印每个单元格的第一行和第二行
for (int i = 0; i < rows; i++) {
// 第一行
for (int j = 0; j < cols; j++) {
if (cells[i][j].neighbors[5] != nullptr) {
cout << "|";
} else {
cout << " ";
}
if (cells[i][j].neighbors[4] != nullptr) {
cout << "\\";
} else {
cout << " ";
}
if (cells[i][j].neighbors[0] != nullptr) {
cout << "-";
} else {
cout << " ";
}
}
if (cells[i][cols - 1].neighbors[1] != nullptr) {
cout << "|";
} else {
cout << " ";
}
cout << endl;
// 第二行
for (int j = 0; j < cols; j++) {
if (cells[i][j].neighbors[3] != nullptr) {
cout << "\\";
} else {
cout << " ";
}
if (cells[i][j].neighbors[2] != nullptr) {
cout << "|";
} else {
cout << " ";
}
if (cells[i][j].neighbors[1] != nullptr) {
cout << "\\";
} else {
cout << " ";
}
}
cout << "\\" << endl;
}
// 打印最后一行墙
for (int j = 0; j < cols; j++) {
cout << "+";
if (cells[rows - 1][j].neighbors[3] != nullptr) {
cout << "-";
} else {
cout << " ";
}
}
cout << "+" << endl;
}
// 求解迷宫
void solve() {
stack<Cell*> cellStack;
cells[0][0].visited = true;
cellStack.push(&cells[0][0]);
while (!cellStack.empty()) {
Cell* currentCell = cellStack.top();
if (currentCell == &cells[rows - 1][cols - 1]) {
// 到达终点,求解完成
break;
}
vector<Cell*> unvisitedNeighbors = currentCell->getUnvisitedNeighbors();
if (!unvisitedNeighbors.empty()) {
// 随机选择一个未访问的邻居
int randIndex = rand() % unvisitedNeighbors.size();
Cell* neighborCell = unvisitedNeighbors[randIndex];
// 打通当前单元格和邻居单元格之间的墙
int wallIndex = 0;
for (int i = 0; i < currentCell->neighbors.size(); i++) {
if (currentCell->neighbors[i] == neighborCell) {
wallIndex = i;
break;
}
}
currentCell->neighbors[wallIndex] = nullptr;
int neighborWallIndex = (wallIndex + numSides / 2) % numSides;
neighborCell->neighbors[neighborWallIndex] = nullptr;
// 将邻居单元格入栈,并标记为已访问
cellStack.push(neighborCell);
neighborCell->visited = true;
} else {
// 回溯到上一个单元格
cellStack.pop();
}
}
}
};
int main() {
int rows, cols, numSides;
cout << "请输入迷宫单元的边数(3/4/6):";
cin >> numSides;
cout << "请输入迷宫的行数和列数:";
cin >> rows >> cols;
Maze maze(rows, cols, numSides);
maze.generate();
cout << "随机生成的迷宫如下:" << endl;
maze.print();
maze.solve();
cout << "迷宫的解如下:" << endl;
maze.print();
return 0;
}
```
程序先定义了一个 `Cell` 类表示迷宫的单元格,包含了行列坐标、邻居列表和是否已访问等信息。然后定义了一个 `Maze` 类表示迷宫,包含了行列大小、单元格边数和单元格矩阵等信息,以及生成和求解迷宫的方法。生成迷宫采用了深度优先搜索算法,求解迷宫采用了类似的方法,都是使用栈来实现回溯。
程序中还有一些细节处理,比如打印迷宫时需要根据单元格的邻居情况来打印墙的位置,这些都是根据迷宫单元的边数来做的。此外,为了让生成的迷宫更加随机,程序还使用了随机数生成器来随机选择邻居单元格。
阅读全文