回溯--迷宮問題

感覺做了兩個回溯之後都差不多....

#include <iostream>
#include <stack>
using namespace std;


typedef enum{AVAILABEL, ROUTE, BACKTRACKED, WALL} Status; //前期準備 記錄當前迷宮的狀態,分別爲可用(未探索),已用,已經探測過沒有退路的,還有牆
typedef enum{ UNKNOWN, EAST, SOUTH, WEST, NORTH, NO_WAY} ESWN;
//enum方向,從unknown開始,到NORTH,遇到NO_WAY就要回溯並標記 BACKTRACKED

inline ESWN nextESWN ( ESWN eswn)
{
return ESWN(eswn + 1);
}

//這個內聯函數用來返回方向的
 
struct Cell{
int x, y;
Status status;
ESWN incoming, outgoing;
};
//迷宮宮格

#define LABY_MAX 24
Cell labe[LABY_MAX][LABY_MAX];


inline Cell* neighbor (Cell* cell)
{
switch (cell->outgoing){
case EAST : return cell + LABY_MAX;
case SOUTH : return cell + 1;
case WEST : return cell - LABY_MAX;
case NORTH : return cell - 1;
default:  exit(-1);
}
}
//去探測當前cell的下一個鄰居cell

inline Cell* advance (Cell* cell){
Cell *next;
switch (cell ->outgoing){
case EAST : 
next =  cell + LABY_MAX;
next ->incoming = WEST;
break;
case SOUTH : 
next =  cell + 1;
next ->incoming = NORTH;
break;
case WEST : 
next = cell - LABY_MAX;
next ->incoming = EAST;
break;
case NORTH : next = cell - 1;
next ->incoming = SOUTH;
break;
default:  exit(-1);
}
return next;
}
//跳轉到下一個鄰居,並給鄰居做上標記
bool laberinth(Cell Laby[LABY_MAX][LABY_MAX], Cell *sourth, Cell *tail)
{
if ((AVAILABEL != sourth->status) || (AVAILABEL != tail ->status))
{
return false;
}
//這是用來處理初始條件不符合的情況

stack <Cell*> path;
sourth->incoming = UNKNOWN;
sourth -> status = ROUTE;
path.push(sourth);
//初始設定,我覺得也應該將outgoing 設置成UNKNOWN的

do  //不斷循環,直到遍歷所有,或者有結果
{
Cell *c = path.top(); //當前位置,若和出口相等,退出
if (c == tail)
{
return true;
}
while(NO_WAY > (c -> outgoing = nextESWN(c->outgoing))) //不斷去探索路,直到找到沒去過的

//如果沒有,就回溯
if (AVAILABEL == neighbor(c)->status) break;
if (NO_WAY <= c->outgoing)
{
c->status = BACKTRACKED;
path.pop();
}
else //可以的話就push c的鄰居進去,並且標記
{
path.push(c = advance(c));
c->outgoing = UNKNOWN;
c->status = ROUTE;
}
} while (!path.empty());


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章