【LB】迷宮尋路——棧與迭代的應用

        迷宮求解問題之所以老師跳過了,其實是因爲要留給我們做課程設計的。前天看到迷宮那裏時覺得這個迷宮問題還挺有意思的,就自己做了一個。與網上某些已經做出來的迷宮算法不同,我的算法採用的是迭代求解,並且有動態的圖形顯示,而不是單一的給出路徑。這樣就使這個程序有意思多了,大家其實可以將迷宮進行修改,通過動態的圖來體會棧的作用。這個算法另外一個優點是可以進行修改使之變成貪喫蛇遊戲(正準備搞呢)。

        下面就是具體的實現代碼,按照序號我會將每一步解釋清楚:

#include<stdio.h>
#include<windows.h>


typedef struct{
int base;
int top;
int route[100];                       
}routes;                                                                                                                          //①

routes b;                                                                                                                        //②

int a[]={               2,2,2,2,2,2,2,2,2,2,
          		2,0,0,2,0,0,0,2,0,2,
			2,0,0,2,0,0,0,2,0,2,
			2,0,0,0,0,2,2,0,0,2,
			2,0,2,2,2,0,0,0,0,2,
			2,0,0,0,2,0,0,0,0,2,
			2,0,2,0,0,0,2,0,0,2,
			2,0,2,2,0,2,2,2,2,2,
			2,0,0,0,0,0,0,0,0,2,
			2,2,2,2,2,2,2,2,2,2};                                                                   //③


void push(int s){
int x;
if(b.top>=99) {printf("錯誤!");}
else {
b.top++;
x=b.top;
b.route[x]=s;
}
}                                                                                                                                   //④

void pop(){
if(b.base==b.top) {printf("無路徑!");system("pause");}
else b.top--;
}                                                                                                                                   //⑤


void print()
{int x;
for(x=0;x<100;x++){
if(a[x]==2) printf("田");                                       //牆
if(a[x]==4) printf(" /");                                        //確定不能走的地方
if(a[x]==3) printf(" *");                                       //當前位置
if(a[x]==0) printf("  ");                                       //可以走的位置
if(a[x]==1) printf("  ");                                       //已經走過的地方
if(x%10==9) printf("\n");}                                 //一行只輸出九個地圖格
}


main(){
        int x=11; 
b.top=0;
b.base=0;                                                                                                           //⑥
a[11]=3;
push(x);
                                                                                                                           //⑦
while(b.route[b.top]!=88){                                                                                  //⑨
system("cls");print();                                                                                  //⑩
if(a[b.route[b.top]+1]!=1&&
   a[b.route[b.top]+1]!=2&&
   a[b.route[b.top]+1]!=4&&
   (b.route[b.top]+1)/10==b.route[b.top]/10)                                                               //11
{a[b.route[b.top]]=1;push(b.route[b.top]+1);a[b.route[b.top]]=3;}                               //12


else if(a[b.route[b.top]+10]!=1&&
   a[b.route[b.top]+10]!=2&&
   a[b.route[b.top]+10]!=4&&
   (b.route[b.top]+10)<100)                                                                                         //13
{a[b.route[b.top]]=1;push(b.route[b.top]+10);a[b.route[b.top]]=3;}


else if(a[b.route[b.top]-1]!=1&&
   a[b.route[b.top]-1]!=2&&
   a[b.route[b.top]-1]!=4&&
   (b.route[b.top]-1)/10==b.route[b.top]/10)                                                                 //14        
{a[b.route[b.top]]=1;push(b.route[b.top]-1);a[b.route[b.top]]=3;}


else if(a[b.route[b.top]-10]!=1&&
   a[b.route[b.top]-10]!=2&&
   a[b.route[b.top]-10]!=4&&
   (b.route[b.top]-10)>=0)                                                                                             //15
{a[b.route[b.top]]=1;push(b.route[b.top]-10);a[b.route[b.top]]=3;}

else {a[b.route[b.top]]=4;pop();a[b.route[b.top]]=3;}                                                    //16
Sleep(200);                                                                                                                 //17
}
}

逐句解釋:
① 這幾行定義了一個棧的結構體,棧底用base指示,棧頂用top指示,route來存儲數據。
② b爲棧的結構體全局變量(當然你可以不使用全局變量,不過全局變量不用傳參,所以在這個程序中採用全局變量使其更簡單)
③定義a爲一個整形數組,用來存儲地圖信息 ,2表示牆,0表示空位置(路),也是採用的全局變量。
④入棧函數,學過棧的應該都懂吧,不多說。
⑤出棧函數,在這裏說明一下,因爲這裏的出棧操作不需要返回棧頂的值,所以只需要top--就行。
⑥ 對棧進行初始化,棧的初始化沒有單獨寫一個函數,直接在主函數裏面操作的。
⑦將迷宮的起點位置壓入棧。因爲地圖爲一位數組,起始位置在這個一位數組中的位置爲11. a[11]=3是使第起點位置初始爲當前位置。
⑧……………………8號呢?好吧,我標漏了……………………………………………… 
⑨因爲地圖的第88號位置爲出口,所以判斷的條件是當沒有走到第88號位的時候就繼續迭代尋路。
⑩system("cls");的作用是清屏,print();是調用畫地圖函數來顯示當前狀態,這樣每尋一次路就清屏重畫一次,連貫起來就成動態顯示了。
⑪首先判斷向東的方向是否可走。讀取棧頂的數據,即當前的位置,加1就是右邊的位置,如果其值是2爲牆不可走,其值是1爲已經走過的地方不能走,其值是4爲確定不能走的地方(當這個位置被出棧操作時即爲確定不能走的地方,否則只會在這裏死轉悠),
b.route[b.top]+1)/10==b.route[b.top]/10這是用來判斷是否走到右邊界(當十位上的數相同時,這個等號是成立的,當等號不成立時,即爲已經走到邊界)。
⑫ 當判斷條件爲真,即右邊位置可以走時,當前位置就爲已經走過的位置,然後將右邊的位置壓入棧,再將右邊的位置換爲當前位置。下面一個判斷條件爲真時執行的操作與這基本相同,就不重複說了,打字累……
⑬第二個判斷條件是下面的位置是否可走,因爲這是一個10x10的迷宮,所以當前位置加10即爲下一個位置,前面幾個判斷條件與第一個差不多,最後一個判斷條件 
(b.route[b.top]+10)<100是判斷下一個位置是否越過下界。
⑭判斷左邊的位置是否可走,發沒發現與第一個判斷條件基本一模一樣,只是+1變成-1了。不多說。
判斷上邊的位置是否可走,只說下最後一個判斷條件(b.route[b.top]-10)>=0,當上邊位置不可走時,即爲上邊位置已經小於0 了。
⑯ 如果上面四個條件都不成立,就說明當前位置爲確定不可走的位置,將其值變爲4,然後退棧,這時當前位置爲之前的一個位置了,然後使這個位置變爲當前位置。
⑰暫停200ms,不然走得太快你根本什麼都看不到就已經走完了。



結語:
1、這個程序採用的是一維數組存儲地圖,其實用二維數組更好,有興趣熟悉一下棧的運用的可以試一下用二維數組來處理。這個程序還有些bug,在特定情況下會出一些問題,比如路封死的時候半天不顯示無路徑。發現bug麻煩告知。



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