標籤:
某天閑逛時看見一副動圖:
真的是非常貪吃,各種拐彎各種吃,感覺十分有趣。
用Perl來實現自動吃滿,蓄謀已久,之前的字元貪吃蛇、深度優先演算法、A*演算法,都是為此篇做鋪墊。
那麼,怎樣讓蛇不吃到自己呢?
1、讓蛇按照我們設計好的路線行進,在一個N*M(N、M均為偶數,奇數不討論)的遊戲空間,設計好路線如下:
當花兒謝了,果子熟透,花牌 (春夏秋冬)一個輪迴後,蛇終於吃滿了。。。
2、假設蛇總是追著自己的尾巴跑,那麼永遠不會死;然而,這沒什麼鳥用,我們需要的是一條“貪吃”的蛇。
3、在2上稍稍改進,吃完食物後再追著尾巴,嗯,已經很接近了。但是問題來了:怎麼吃到食物?吃到食物後被圍死怎麼辦?
其實我的想法就是解決3中的問題:
1、使用A*演算法計算到食物的最短路徑
2、類比吃到食物後的情境,能否回到蛇尾;能--吃食物,不能--繼續追著尾巴,重複1、2
3、如果無法回到尾巴,保持當前移動方向(認命吧,要掛的節奏)
偽碼如下:
# while( 存活 && 未吃滿){# 計算蛇頭到食物的路徑# if( 有蛇頭到食物的路徑 ){# 類比吃到食物後的情境# 計算是否有路徑到達蛇尾# if( 有路徑 ){ # 執行蛇頭到食物的路徑# }# else{ # 沒有到蛇尾的路徑# next# }# }# 找出當前可行方向追逐蛇尾# }# if(吃滿){# 顯示:祝賀# }# else{# 顯示:wtf ?# }
類比吃到食物後的情境:使用A*計算路徑,並建立一條“影子蛇”用來類比吃到食物後的狀態
計算是否有路徑到達蛇尾:和“追逐蛇尾”方法類似,也可使用A*
找出當前可行方向追逐蛇尾:
由於移動時尾巴會變動,未嘗試A*,使用指定方向深度優先搜尋演算法
偽碼如下:
sub trace_tail{ @moves=grep{可行}; foreach(@moves){ next if(下一步越界 || 吃到自己) unshift @feasible,$_ if(遠離食物) 其他方向 push @feasible } foreach(@feasible){ next_move=cur_move+$_ 指定方向優先探索 next_move的反向上一步設為不可通過 每走一步,從蛇尾開始設未經過;每原路返回一次,當前位置的蛇身設不可通過 if(有路徑)return 1 } 執行完畢無路徑,return cur_move}
運行如下:
實際上還是會被困死,雖然追逐尾巴時避開食物優先,但唯一路徑可能會出現食物,不吃也得吃了。
代碼較亂,準備加好注釋後貼上來。
Perl看完這個,再不敢說自己會玩貪吃蛇