程式碼吃雞:Python-Robocode
最近看到一個很有“未來感”的新聞:
一輛 特斯拉 在拉斯維加斯出了車禍,撞“死”了一個……emmmm……機器人。不知道是意外還是炒作,又或者是這位機器人故意碰瓷,反正人們也無法從受害者口中瞭解“ 被特斯拉撞是怎樣一種體驗 ”了。
圖為受害者,情緒看起來很穩定
隨著“ 人工智慧 ”的應用場景越來越多,此類新聞以後可能也會越來越頻繁。但願這些機器人們能嚴格遵守 阿西莫夫三定律 :
- 機器人不得傷害人類個體,或者目睹人類個體將遭受危險而袖手不管
- 機器人必須服從人給予它的命令,當該命令與第一定律衝突時例外
- 機器人在不違反第一、第二定律的情況下要儘可能保護自己的生存
在早些年,人工智慧這個概念還沒有這麼火的時候,提到 AI 經常是指 遊戲中電腦角色的執行策略 。比如槍戰遊戲、即時戰略遊戲、MOBA 類遊戲中的電腦方,對於 尋路、攻擊、躲避 等行為的判斷和執行。早期的一些 AI 有點傻,真的可以稱得上“人工智障”。比如玩過星際爭霸的玩家一定知道“勾農民”的戰術:你只要攻擊一下電腦方的基地,它的所有農民就會放下手中工作來追著你。
然而正因為如此,產生了一種程式設計師之間特有的較量: 程式設計遊戲 。所有人 針對某一個遊戲規則編寫策略,看誰的策略表現得更好 ,能打敗其他人,最終取得勝利。像星際爭霸、CS之類的經典遊戲都有過類似的比賽。優秀的程式碼甚至可以挑戰人類,比如這兩年為人所熟知的 AlphaGo ,就是此類的極致。而 對於程式設計新手來說,程式設計遊戲也是練習程式碼的極好方式。
在眾多可程式設計的遊戲中,有個比較知名的專案: Robocode 。它是 IBM 在 2001 年釋出的 坦克機器人戰鬥模擬引擎 ,並在數年後開源。簡單來說,它就是一個“坦克大戰”的遊戲,你可以控制一輛坦克,和別人對戰。然而與一般遊戲所不同的是:你不是通過鍵盤滑鼠控制坦克,而是需要 自己寫一段程式碼,制定坦克的策略 ,在遊戲開始後自動對戰。
坦克由三部分組成:
- 車身
- 炮臺(決定開炮方向)
- 雷達(用以發現敵人)
在程式碼中,你可以通過介面獲取以下資料:
- 坦克當前座標
- 車身、炮臺、雷達的朝向角度
- 戰場長寬尺寸
- 事件響應,包括:探測到敵人、被子彈打中、碰撞到敵人、碰撞到牆壁等
以及控制坦克的:
- 前進、後退
- 車身旋轉
- 炮臺旋轉
- 雷達旋轉
- 開炮
一些基本規則:
- 每輛坦克具有一定的能量,初始值相同,當能量降到0時則被消滅
- 被敵人擊中會扣能量,但擊中敵人會增加能量
- 發射炮彈需要消耗能量,可以指定消耗能量的多少,對敵人造成的傷害也相應變化
- 碰撞到敵人和牆壁時都會扣能量
所以我們要做的就是: 儘可能避開子彈 、 儘可能避免撞牆和撞上別人 、 儘可能擊中敵人 (打不中不如不打)、活到最後。這和當下熱門的吃雞遊戲(絕地求生)的套路就是一致的嘛。
可是,Robocode 使用的語言是 Java ,這是 IBM 當年所大力推廣的。如果你想嘗試,但不懂 JAVA 就尷尬了。好在有人做了個 Python 移植版本: Python-Robocode 。
不過呢,這個專案有點年久失修了,用的還是 python2 + PyQt4 ,在很多比較新的系統上執行會有一些小 bug,比如選單欄點不出來、不能調引數之類。不要抱太高要求,還是可以玩玩的,我也就玩了一百多局而已。
具體方式:
- 下載專案程式碼
- 確保你電腦的環境已安裝 python2、PyQt4,你可以建立一個虛擬環境來做這事(參考: Crossin:為什麼你的python版本一團糟?因為少了這個操作 )
- 命令列執行
python main.py
啟動專案 - 點選選單欄上面的 Battle - New 新增坦克,你自己寫的坦克也是從這裡新增
- 之後如果不改變遊戲設定,直接點選 Start Last Battle 即可
- 坦克策略檔案在 Robots 資料夾下,你可以仿照已有例子增加一個
這裡我再給一個更簡單的策略示例:
from robot import Robot import random # 坦克類 class World(Robot): # 初始化 def init(self): self.lockRadar("gun") # 遊戲迴圈 def run(self): self.gunTurn(90) self.turn(random.randint(-45, 45)) self.move(random.randint(-100, 100)) # 發現敵人事件 def onTargetSpotted(self, botId, botName, botPos): self.fire(1) self.gunTurn(10)
這裡我定義了一個名叫 World 的坦克類,繼承框架提供的 Robot 類。在初始化裡,把雷達和炮臺角度繫結,這樣只要發現敵人就可以開炮了。run是主體策略部分,會一直迴圈執行,這裡我讓它同時做三件事:炮臺旋轉90度、車身旋轉隨機角度、車身前進/後退隨機距離。而當發現敵人後,就開炮,並將炮臺移動10度(避免死鎖)。
就這幾行程式碼,儲存到 hello.py裡,從選單欄新增到遊戲中,已經可以讓你的坦克上場 PK(當炮灰)了。接下來,你可以在此基礎上繼續擴充套件它,實現你自己的策略。
我還寫了一個稍微複雜一點點的版本,對付這幾個示例策略還是可以一戰的。
程式碼在此:
https:// gitee.com/crossin/snippet/tree/master/tank 或者在公號(Crossin的程式設計教室)裡回覆關鍵字“ 坦克 ”獲取。
你可以下載到你的目錄中,這樣就可以和我隔空對戰了。歡迎大家把自己的策略發上來。
除了這個 Python 版本的 Robocode 之外,騰訊也做過一個很類似的 HTML5 版本,叫 CodeTank (鵝廠當年還不太習慣收購)。雖說 idea 不新鮮,但有個很大優勢是 可以線上使用 ,不用下載搭建環境了,而且你可以看到其他開發者提交的程式碼。對於瞭解一些 JS 的學習者來說,這非常方便。關於 JS 我們暫時不展開說了。但即使你不太會 JS,也可以複製一些別人的程式碼,嘗試改點引數,這個並不複雜。
在 CodeTank 裡,你也可以挑戰我,從 坦克庫 - 坦克對戰 裡搜 crossin 就能找到了。
希望大家寓教於樂,玩得開心~
════