國慶這幾天,在 python技術交流群裡,10月1日,我發現大家在討論玩hacker.org網上的一個機器人逃跑的小遊戲,開始幾關試玩了一下,就明白了玩的原理,手動玩到了26關。本來沒有打算用編程的方式來解決這個遊戲,因為我根本沒有想到和注意到這個網頁上的flash遊戲還可以編程來解答。後來聽群裡的高手解說了一下,他們還發了自己解決問題時的,我就也開始嘗試使用python來編程解決這個問題。
最初,想到的是用窮舉的辦法,因為沒有遊戲編程的經驗。但是這個窮舉肯定是不行的。後來就在網上搜尋 遊戲尋找路徑等關鍵字,讓我發現了A*(可以念A星)演算法,並找到了這些資料:
我看的資料主要是:js+ajax實現的A*遊戲路徑演算法整理第1/2頁 http://www.jb51.net/article/10130.htm
js+ajax實現的A*遊戲路徑演算法整理第2/2頁 http://www.jb51.net/article/10130_2.htm
python Astar A* A星 http://www.cnblogs.com/kdy71107216/archive/2011/08/06/2129139.html
用Astar(A*)演算法 實現的迷宮最短路。代碼比較規範 http://www.cnblogs.com/kdy71107216/archive/2010/08/06/1794447.html
-----
還有很多就是關於list tuple 的操作的基礎資料和例子。
用Astar(A*)演算法 實現的迷宮最短路。代碼比較規範 http://www.cnblogs.com/kdy71107216/archive/2010/08/06/1794447.html
這個是java版的A星演算法,會Java的可以看看。
我的程式是用python實現的,就是照著上面所的那個 js +ajax 版的改的。
整個過程應該分為3個階段:
1,網上查資料,看資料,消化資料,主要是理解A星演算法和把那個js程式改編成python版的。改的時候,主要是解決A星演算法中介紹的那個經典例子。
2。開始用編好的python程式,解決最開始的幾關遊戲,地圖不用大,用個6X6就行,通過用紙筆畫圖,和程式推演,用程式列印運行資訊不斷的調試和排錯,同時也加深對A星演算法的理解。直到解決幾個小地圖的問題並取得路徑。我最開始的路徑是個座標值列表,後來又想了個辦法把它轉化成類似RDRDRD字串形式逃跑指令。然後又查閱了一些怎麼用python下載和儲存網頁,分析網頁連結中的參數等資料,最後就開始驅動程式過關了。
3,程式啟動並執行過程中,需要調優,開始的時候意識不到,以為反正讓電腦忙,自己等結果就行了。後來才意識到速度很重要,不然要等到哪年哪月啊。
開始的時候,輕輕鬆鬆玩到260多關,200關之前還是很快的,但後來過關時間越來越長,後來過一關就要10多分鐘,我以為別人也都是差不多這個時間,就讓電腦在那裡運行了一個晚上直到天亮,結果程式早就運行出錯停在那裡了。具體的錯誤就是什麼網頁下載錯誤,無服務等。上午再一問機哥,他說我的太慢了,我就大改了一次,減少了很多迴圈過程。終於從295關開始只要1分多鐘,不過後來慢慢地圖大了 ,到460關的時候又跑到10多分鐘一關,然後又改動了程式,從460直到500關都是10幾秒鐘解決了。只有後面的500-513關又到了幾分鐘,十幾分鐘。
-----------------------------
python中運行效率的幾個瓶頸小函數。
以下的seq指的是list,tuple等序列。
1。seq.count()函數
實際運行中,count函數耗費了很多時間,尤其是seq比較大的時候。如果在迴圈中用了count函數,那麼你的迴圈將會耗費大量時間。
例如,去除列表中的重複元素的一個函數小片段:
#清除 重複的炸彈,減少迴圈
# 保持排序
noDupes = []
[noDupes.append(i) for i in seq if not noDupes.count(i)]
這一小段,在後面的400多關的時候,總的耗費時間可以達到250多秒,後來我不用count函數,整個程式啟動並執行時間立馬降下來了。
2 some in seq,這個in的判斷也會耗費很多時間,尤其是seq比較大的時候,具體原因我不知道。反正你可以使用for 迴圈,在seq中找到了 some後可以break來中斷for迴圈,這個 some in seq,這次在解決這個遊戲的時候, 我的seq中是一大串tuple(),就是座標用(x,y)來表示。結果花的時間很長。
-------------------
這次學習了的資料有:
1.A星演算法尋找路徑
2.list,tuple的一些操作例子
3.下載網頁的函數
4.簡單使用python的profile來查看哪些函數耗時間最多.這個對我調優起到了最大的協助
--------------------
目前對A星演算法的理解:
1.主要是計算每個節點的F值,F值=G+H
2.演算法中主要做的一件事就是維護2個列表,一個開啟列表openlist,裡面儲存的是還沒有測試的節點,一個關閉列表,裡面儲存的是已經測試過了的點.
3.最終路徑,可以通過終點反推到起點得到路徑.
4.起始條件可以歸到兩個重要參數,一個是地圖範圍,簡化點說就是一個矩形範圍(簡化後,起點和終點變成矩形的兩個角),一個是炸彈或者障礙物的列表,有了這兩個參數,其他的任何尋找路徑的問題都可以使用各種方法轉化為A星演算法來解決.
-------------
體會主要有:
1、化整為零的解決問題的方法、把不熟悉的問題轉化為熟悉的問題的方法。
2、遇到問題,不斷學習,觸類旁通,從小處著眼解決問題的的思考方法。
3、吸收他人想法,但立足於用自己的代碼解決問題,通過自己實踐,培養獨立解決問題的能力。
-----
2011-10-6
總的來說,這個遊戲,以後再回顧,應該是好些人令人難以忘懷的編程經曆。我發現群裡好幾個人都過了。高山仰止,景行行止,我忽然有了正在與高手同行的感覺, 在無邊無際的網路世界中, 這種感覺讓人覺得 你不是一個人在戰鬥,你不是孤獨的。 希望和大家共勉。