感覺做了兩個回溯之後都差不多....
#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());
}