-
關於本例子中用到的棧結構請參看:https://blog.csdn.net/d06110902002/article/details/106039828
-
迷宮分析:
迷宮通常是用一個二維數組來表示,通路以0表示,不通以1表示,出口位置以e表示,起點爲s表示(如下圖所示)。
1 | 1 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|
1 | 1 | 1 | 0 | 0 | 1 |
1 | 0 | 0 | 0 | e | 1 |
1 | 0 | 0 | s | 1 | 1 |
1 | 1 | 1 | 1 | 1 | 1 |
- 程序中使用1個棧與一個與迷宮數組規格一樣的數組,一個用來有存儲下一步待走的索引,以上圖爲例當前s在二維數組中的索引下標爲(3,3),下一步有可能走(3,2)與(2,3)那麼棧中就存放(3,2)與(2,3)(爲了存放方便可以聲明一個對象Cell內含x,y2個成員變量來表示在二維數組的索引)。
- 數組在尋找迷宮路徑的過程中使用,它的初始值只記住起點與終點位置,數組的行列應與迷宮原始數組保持一致。其他的點都是待尋找的點,尋找時都要探索當前點上、下、左、右四個方位直到出現下面三種情況之一則停止當前點的探索:
已經訪問過
已經到邊界了
當前點爲迷宮中的檣(不通點)
爲了記住嘗試過的路徑,需要將當前已經走過的點在數組對應的下標中的狀態改爲已經訪問過,這個狀態值非常重要一定要與連通點標記0和終點標記e區別開來(本例中標記爲’ . ')。置成這個標記主要目的是爲了防止重複尋找陷入無窮的遞歸當中。存放的點需滿足下面規則:
連通的點
終點
開始時這個數組的值如下:
1 | 1 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | e | 1 |
1 | 1 | 1 | s | 1 | 1 |
1 | 1 | 1 | 1 | 1 | 1 |
- 下面是本迷宮棧與數組每一步的存入情況
*核心 代碼如下:
-(void) pushUnVisited:(NSInteger)x y:(NSInteger)y{
Cell* cell = [[Cell alloc] init:x y:y];
NSString* tmp = [[self.storeArray objectAtIndex:x] objectAtIndex:y];
if ([tmp isEqualToString:@"0"] || [tmp isEqualToString:@"2"]) {
[self.mazeStack push:cell];
NSLog(@"78------:入棧x:%ld y:%ld",x,y);
}
}
-(void) queryPath{
NSInteger row = 0;
NSInteger col = 0;
while (!([self.curCell isEqual:self.exitCell])) {
row = self.curCell.x;
col = self.curCell.y;
NSLog(@"53--------經過的路徑結點座標 x:%ld y:%ld",row,col);
if(![self.curCell isEqual:self.enterCell]){
NSMutableArray* rowarray = [self.storeArray objectAtIndex:row];
//代表訪問過了
[rowarray replaceObjectAtIndex:col withObject:@"."];
}
[self pushUnVisited:row - 1 y:col];
[self pushUnVisited:row + 1 y:col];
[self pushUnVisited:row y:col - 1];
[self pushUnVisited:row y:col + 1];
if([self.mazeStack isEmpty]){
NSLog(@"83-------- 無出路 尋找失敗:node x:%ld y:%ld",row,col);
return;
}else{
self.curCell =(Cell*)[self.mazeStack pop];
NSLog(@"105-------出棧x:%ld y :%ld 棧大小:%ld",self.curCell.x,self.curCell.y,[self.mazeStack count]);
}
}
printf("90-------尋找成功 x:%ld y:%ld:\n",self.curCell.x,self.curCell.y);
NSMutableArray* rowarray = [self.storeArray objectAtIndex:self.curCell.x]; //將最後一個結點置爲走過,真實的路徑可以不需要此步
[rowarray replaceObjectAtIndex:self.curCell.y withObject:@"."];
[self printPath];
}
-(void) printPath{
for (int i = 0; i < 5; i ++) {
for (int j = 0 ; j < 6; j ++){
NSString* tmp = [[self.storeArray objectAtIndex:i] objectAtIndex:j];
printf(" %s ",[tmp UTF8String]);
}
printf("\n");
}
}
- 測試效果如下圖: