小時候,都喜歡玩迷宮,現在的電腦上還可以玩3D類迷宮。
那么每次開始游戲時,迷宮里密密麻麻的道路是怎么生成的呢?
在代碼里面,我們把它們想象成一堆像素小格子,當兩個格子連在一起,就像一堵墻,那一圈格子就是一間小房間,房間有門,對應的門就沒有墻壁。所以生成迷宮地圖,就是一個挖墻造門的過程。
思路:
1.首先假設迷宮場地是充滿墻壁沒有道路的。我們的工作其實就是把迷宮“挖”出來。不妨把開始時的迷宮看成一些小的“房間”,每個“房間”四面都被墻壁包圍。畫迷宮的過程實際就是從一個房間隨機走到另一個房間,走的過程中把墻壁“挖掉”。定義一個類,這個類的每個對象代表迷宮里的一個格子,里面存放了這塊墻壁或房間是否被挖過,以及它是否是一個“房間”。選好一個房間作為起點(我選的左上角),然后開始隨機挖。
2.到達一個房間時判斷四周房間的情況。按照四個方向判斷。如果其中一個方向的隔壁房間挖過了,就不要把這個方向記錄下來。如果四周都不能挖了,就一路退回之前能挖的地方。再次隨機一個新方向,繼續挖。(有點類似走迷宮的過程)
程序中記錄道路用了C++STL里的棧。
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <stack>
#include <vector>
#define M 25 //迷宮的規模
using namespace std;class Grid{
public:bool cell, dig;
};
//迷宮格子類型,記錄了是否被挖過
Grid maze[M][M];
stack<int> row_s, col_s;
//用來存放路徑的棧
void Init(){for(int i=0; i<M; i++){for(int j=0; j<M; j++){maze[i][j].dig=false;if(i%2!=0 && j%2!=0)maze[i][j].cell=true;}}row_s.push(1); col_s.push(1);srand(time(0));
}
//初始化迷宮格子
int DirRand(){vector <int> dirlist; //用來記錄可選擇的方向int result=0;int row=row_s.top(), col=col_s.top();//0 up, 1 down, 2 left, 3 rightif(row-2>0 && !maze[row-2][col].dig) dirlist.push_back(0);if(row+2<M-1 && !maze[row+2][col].dig) dirlist.push_back(1);if(col-2>0 && !maze[row][col-2].dig) dirlist.push_back(2);if(col+2<M-1 && !maze[row][col+2].dig) dirlist.push_back(3);if(dirlist.size()==0) result=-1;else result=dirlist[rand()%((int)dirlist.size())];return result;
}
//判斷周圍情況,沒有可挖的格子時返回-1
void GenMaze(){while(!row_s.empty() && !col_s.empty()){int dir=DirRand();int row=row_s.top(), col=col_s.top();if(dir!=-1){ //前進if(dir==0){maze[row-2][col].dig=maze[row-1][col].dig=true;row_s.push(row-2); col_s.push(col);}else if(dir==1){maze[row+2][col].dig=maze[row+1][col].dig=true;row_s.push(row+2); col_s.push(col);}else if(dir==2){maze[row][col-2].dig=maze[row][col-1].dig=true;row_s.push(row); col_s.push(col-2);}else if(dir==3){maze[row][col+2].dig=maze[row][col+1].dig=true;row_s.push(row); col_s.push(col+2);}}else{row_s.pop(); col_s.pop(); //后退}}
}void OutMaze(){ //輸出迷宮for(int i=0; i<M; i++){for(int j=0; j<M; j++){if(maze[i][j].cell || maze[i][j].dig)cout<<" ";else cout<<"##"; //為了保證對齊,墻壁和道路寬都是2個字符}cout<<endl;}
}int main(){Init();GenMaze();OutMaze();return 0;
}