?? 小白鼠鉆迷宮.c
字號:
這是個經(jīng)典的數(shù)學問題,說的是:在一個隨機的迷宮里,小白鼠如何能最快地從起點走到終點。
-# --------### # ## # # ###
----# # #-## # # # #### #### #
## ## #-# ## # # # #---# ## #
## # # # # -# ### ## #### ##
# # ----# # # ## # # # ## ### ##
-# --# ---### -* # ## # # ###
----# # #-## # # -----### #### #
## ## #-# ## # # # #---# ## #
## # # # # -# ### ## #### ##
# # ----# # # ## # # # ## ### ##
按上圖,老鼠用“*”來表示,要求從迷宮的左上腳選擇一條路徑,跑道右下腳的出口。也許用神經(jīng)網(wǎng)絡(luò)、用遺傳算法之類能找到一個最佳的做法,但我這個程序是基于對迷宮完全無知,而且沒有試驗的這個前提,所以我只能采用最機械的辦法:每條路都試探。具體是這樣的:向左看看,能否過去。只要左面不是墻,就走到出一步。若左面不能過去,看下面,再看右面...若三個方向都不能過去,只能回到上一步,重復干...
程序并不長,但它在四年前費了我一個星期的所有時間(包括上課 :-))。一直在我磁盤里放著,不拿出來分享,怪可惜的。你看看能不能找到更好的辦法?望交流。
注釋一:你能看見迷宮幾乎完全是隨機的,但為了保證一定有一條通道,我在起點和終點附近各放了九個可以通行的點。不算作弊吧。
注釋二:循環(huán)里面的延時對于PENTIUM幾乎一點作用都沒有。所以運行時你或者選用 STEP,或者把延時提高一點,才能看清小白鼠是如何邁向前途未卜的新一步,又是如何迷途知返,重新審視自己的步伐。
注釋三:這個程序的技巧很好,但完全沒有注釋,風格也不太好,但這正是幾年前我的標準的程序,所以現(xiàn)在我也不改,直接拿出來,僅供一娛。
注釋四:程序用TC才能編譯。VC,標準C中沒有“gotoxy”等函數(shù)。當然,這只影響界面顯示,不影響我們老鼠行走的算法。
您還可以直接下載已編譯好的程序maze.exe
--------------------------------------------------------------------------------
源程序如下:
#include < stdlib.h>
#include < time.h>
#include < stdio.h>
#include < conio.h>
main()
{int x,y,a[72][22];
char o;
int c,d,four,k=0,i,end,step;
randomize();
/* printf("Do you want it run or step?(0/1)");
scanf("%d",&step);*/
clrscr();
for(x=0;x < 72;x++){
for (y=0;y < 22;y++){
if ((y==0)||(x==0)||(x==71)||(y==21)) {
a[x][y]=11;
continue;}
if (random(3)==0) {
a[x][y]=11;
gotoxy(x,y);
printf("#");
}
else
a[x][y]=1;
}
}
for(y=1;y < 10;y++)
{ a[1][y]=1;
gotoxy(1,y);
printf(" ");
a[70][21-y]=1;
gotoxy(70,21-y);
printf(" ");
}
x=1;
y=1;
end=0;
gotoxy(1, 23);
printf("Step?(1/0) ");scanf("%d", &step);
//Above is to prepare the Maze. Now, our little mouse is comming.
while((x < 70)||(y < 20)) {
c=x;d=y;four=0;
do{
k++;
if ((a[x+1][y]==1)||((a[x+1][y]%7==0)&&(a[x][y]%2!=0)&&(four==1)))
{
a[x][y]=a[x][y]*2;
x=x+1;
break;
}
if ((a[x][y+1]==1)||((a[x][y+1]%5==0)&&(a[x][y]%3!=0)&&(four==1)))
{
a[x][y]=a[x][y]*3;
y=y+1;
break;
}
if ((a[x][y-1]==1)||((a[x][y-1]%3==0)&&(a[x][y]%5!=0)&&(four==1)))
{
a[x][y]=a[x][y]*5;
y=y-1;
break;}
if ((a[x-1][y]==1)||((a[x-1][y]%2==0)&&(a[x][y]%7!=0)&&(four==1)))
{a[x][y]=a[x][y]*7;
x=x-1;
break;
}
four++;
if (four == 2){
gotoxy(25, 23); printf("Cannot go out!");
end=1;
break;}
if (k>3000) {
gotoxy(30, 23); printf("Too long!");
end=1;
break;}
}while(1);
if (end==1) break;
/* gotoxy(x,y);printf("*");*/
gotoxy(c,d);printf("-");
gotoxy(16, 23); printf("step:%d ", k);
gotoxy(x,y); printf("*");
if (step==1) getch();
}/* no end point*/
if (end==1) printf("Error.");
else printf("ok!");
getch();
}/*end main()*/
看懂程序了嗎?當時我發(fā)現(xiàn)必須用一些東西來記錄老鼠的歷史,即要知道在該點是否已經(jīng)向右走過?是否向左走過?用了4天腦袋里跳出“素數(shù)”這樣一個悠久的名詞,于是一切就水到渠成了!
在Do-While中的第一個if的意思是:如果右邊的方格是如果從未走過的空地(值為1),走過去。但是,如果上下左右都沒有值為1的空地,就必須考慮退路了。這時four==1,查看一下我是否已經(jīng)走過這個地方 (a[x][y]%2!=0)?我是否從那里過來的(a[x+1][y]%7==0)?也就是說當four==4時我只走回頭路。
你的程序會采取這種策略嗎?
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -