迷宮地形我們可以通過讀文件的形式,通過已知入口逐個遍歷座標尋找通路。
文件如圖:
每個座標的位置用結構體來記錄:
struct Pos //位置座標 { int _row; int _col; };
定義行列範圍
#define M 10 //行 #define N 10 //列
初始化迷宮數組:
將通過讀文件的方式獲取的字符轉成整型數據,保存在M行N列的數組中。
void InitMaze(int* maze) { struct WavHeadhWAV; FILE* fout = fopen("MazeMap.txt", "r"); // .txt文件要放在當前目錄下 if (fout == NULL) // 這裏一定要檢查讀文件是否成功 { cout << "can't find MazeMap.txt !" << endl<<endl; return; } for (int i = 0; i < M; i++) { for (int j = 0; j < N;) { char ch = fgetc(fout); if (ch=='1'||ch=='0') { maze[i*N + j] = ch - '0'; j++; } } } fclose(fout); }
回溯查找通路:
利用棧來存儲通路,通過上下左右四個方向依次遍歷,如果該位置滿足條件,就將它入棧,並將該位置的數據置爲2;如果四個方向都不滿足條件就執行出棧操作,回溯查找滿足條件的位置(這時候如果棧爲空了,說明查找通路失敗),繼續循環遍歷,直到找到出口爲止。
這裏建立一個最小棧,如果找到出路,就將該棧賦給最小棧,並將出口置爲1,繼續回溯查找通路,如果又一次找到通路,就將該棧的長度與最小棧進行比較,如果該棧長度比最小棧還要小,就將它再一次賦給最小棧(保證最小棧是最短的通路),繼續回溯,直到整個棧爲空,回到了入口,程序結束。
bool SearchMazePath(int *maze, Pos entry, stack<Pos>& paths) // 利用棧回溯查找通路,並實現迷宮的最優解 { assert(maze); stack<Pos>min; paths.push(entry); while (!paths.empty()) { Pos cur = paths.top(); maze[cur._row*N+cur._col] = 2; if (cur._row==M-1) { if (paths.size()< min.size() || min.size() == 0) { min = paths; } paths.pop(); maze[min.top()._row*N + min.top()._col] = 1; } Pos next = cur; next._col--; //左 if (CheckIsAccess(maze, next)) { paths.push(next); maze[next._row*N + next._col] = 2; continue; } next = cur; next._col++; //右 if (CheckIsAccess(maze, next)) { paths.push(next); maze[next._row*N + next._col] = 2; continue; } next = cur; next._row--; //上 if (CheckIsAccess(maze, next)) { paths.push(next); maze[next._row*N + next._col] = 2; continue; } next = cur; next._row++; //下 if (CheckIsAccess(maze, next)) { paths.push(next); maze[next._row*N + next._col] = 2; continue; } paths.pop(); } if (paths.empty()&&!min.empty()) { maze[min.top()._row*N + min.top()._col] = 2; return true; } return false; }
檢查該位置是否合法:(座標在行列範圍之內)
bool CheckIsAccess(int* maze, const Pos& next) // 檢查該位置是否合法 { assert(maze); if ((next._row >= 0 && next._row <= N) && (next._col >= 0 && next._col < M) && maze[next._row*N + next._col] == 0) { return true; } return false; }
打印迷宮:
void PrintMaze(int *maze) // 打印迷宮 { assert(maze); for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { cout << maze[i*N + j] <<" " ; } cout << endl; } cout << endl; }