程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 世界robocode機器人的四大運動方式分析

世界robocode機器人的四大運動方式分析

編輯:關於JAVA

前言

Robocode 在短短的時間內風靡全球,全世界的robocode愛好者 設計出了大量的優秀智能機器人,他們都擁有各自的運動方式,有的很容易被擊 中,有的卻很難射擊。設計一個好的運動方式是優秀robocode機器人取勝的關鍵 。上屆世界中級組冠軍Fermat就是靠他讓敵人難以琢磨的運動躲過敵人一發發的 子彈而取得勝利。(當然,他的優秀的瞄准射擊也是取勝的關鍵)怎樣的運動才 能不被敵人擊中,讓敵人琢磨不透呢?這裡我把常見的機器人運動方式分為4類 來詳解。

明顯有規律的主動運動

剛開始玩robocode的很多都會有這種感覺, Samples裡面Walls最強,誰都打不到他。Wall就是一種很典型的明顯有規律的主 動運動,他總是直線繞牆走,如圖1:

圖1

因為它幾乎總是在動,而Sample裡面的機器人的射擊方法幾乎都是直 接射擊敵人的當前位置,由於子彈到達目標需要一定的時間,當子彈飛過去的時 候,Wall已經不在原來那個位置了,所以它們總是打不到它,因此在剛開始時它 看起來是那麼的強大。但是,Walls並不能算一個優秀的機器人,它僅是作為一 個例子來介紹robocode機器人的制作方法,稍厲害一點的機器人都能很得心應手 的射擊它,有的機器人甚至能槍槍必中的打它。他們大多運用了提前量的算法計 算出子彈到達Walls的時候Walls大概走的距離,然後攻擊Walls下一步將要行走 的地方。至於怎樣編碼實現,已經超出了這篇文章的范圍,你可以參考 Predictive targeting。

采取這一類運動方式的機器人很多,它們規律 很明顯,很容易被掌握,像SpinBot總是做圓周運動(圓周運動的射擊方法可以 參見 圓周瞄准),Corners 總是躲在角落不動……你會發現它們 都是很容易對付的角色,是不是要寫出優秀的機器人就不能用這樣的策略呢?當 然不是,在人眼看起來有規律的運動,機器人未必會認為有規律(這要取決於你 的機器人的分析方法)。特別是在群戰的時候,你要顧及大量的敵人,你不可能 只關注一個敵人的運動,你要同時關注A或關注B的運動,因此即使A作了規律很 明顯的運動,你也很難察覺。

典型的例子就是David McCoy的 PrairieWolf,你看它群戰的時候經常待在角落做一種繞角落來回運動,但是你 卻未必能很容易的射擊他,還有就是Paul Evans的SandboxLump,它不僅是在角 落來回,而且還夾雜著很多的弧線運動,如圖2:

圖2

即使是單挑的時候,你的機器人也很難分析出SandboxLump的具體規律 ,所以要擊中它並不容易,確切地說那實在是太難了。這裡我要重要介紹一種被 廣泛采用的來回運動方式,如圖3:

圖3

假如機器人R1在A,B之間作直線來回運動,某一時刻機器人R1和機器人 R2在如圖所示位置,R1目前是直線運動。如果R1的擺幅小於R1到R2的距離,R2用 直線提前量的射擊方法,射擊點在B點右邊的C點,它發射了子彈,但是R1運動到 B點的時候突然反向向A行駛,到達A後又返回向B行駛,如此反復,R2的子彈就總 是打在A點偏左或者B點偏右的地方。這就是來回運動的迷惑性,哈哈,R1能迷惑 敵人了,它很強了吧?不,如果R1的擺幅大於R1與R2 的距離。如圖所顯假設R2 在R2’的位置,它計算的射擊點C’在AB之間,這樣的話則可以擊中 敵人,所以來回運動也不一定總能使敵人打偏,靠你比較近的敵人就顯得非常危 險。還有優秀的機器人一般能識別來回運動的敵人,它能計算出你來回的距離, 這樣你可能就被別人百發百中了。所以如果你要采用這樣的方法的話,可以添加 一些其他因數,比如說弧線來回運動,來回運動隨機距離等等。

隨機性 很強的主動運動

當你掌握了對付Wall和SpinBot的射擊方法後,你是否又 覺得Sample裡面的Crazy也是個令人頭疼的家伙?你用分別用對付 Corner,Walls 和SpinBot的射擊方法跟他對戰,你會發現這三種方法都能打中他,但是命中率 都沒有打Corner,Walls和 SpinBot他們高,這裡我做了個測試:分別用三種方法 來對付Crazy,測試結果如下表1:

子彈參數射擊方法 命中 未中 命中率 對付Corner 的當前位置射擊方法 5 40 % 11.11 對付Walls的直線提前量射擊方法 8 24 %25 對付SpinBot的圓周提 前量射擊方法 7 17 % 29.16

他雖然總是做弧線運動,但是這次弧線運動停 止後又會開始另一個方向的弧線運動。可能你看了Crazy的源代碼後你會懷疑, 代碼裡面一個類似 Math.random()的語句都沒有,怎麼稱這種運動是隨機性很強 的運動呢?這裡的隨機性是相對於你的機器人的運動分析程序的:由於他總是時 而轉動,時而停止換一個方向,時而向前,時而向後,撞到牆又會改變方向。一 般的機器人都難以分辨這種改變,所以通常也稱它為隨機的運動。

雖然 他的隨機性很強,但是用對付SpinBot的圓周提前量射擊方法也達到%29.16的好 成績,顯然這樣的運動也不是很理想。更明顯的隨機運動是在代碼裡加入了類似 ahead(Math.random()*200),turnLeft(Math.random()*360)這樣的代碼,這樣隨 機性就更強,連此機器人的作者也不知道它的下一步會采取怎樣的運動,你又如 何提前預知呢?那麼……這樣運動的機器人是否就打不中呢?你從 對付Crazy的射擊命中率表可以看出,雖然我采取對付另一種有規律運動方式的 的射擊策略來對付一種我不知道的運動方式是不合理的,但是我卻往往也能打中 它,而且命中率並不低。為什麼呢?我舉個例子吧,假設我采取對付Wall的直線 提前量射擊方法射擊Crazy,如圖4:

圖4

圖5

我認為它走的是直線,這顯然是錯誤的,但是在我離它比較近的時候 ,雖然射擊的是如圖的B’點而R1運動到了C點,考慮到機器人有一定的高 寬度,R2也仍然能打到它。

對於另外一種直線隨機距離來回運動的機器 人(前面提到過的一個建議Random),你可以看圖5。你計算到如果你射擊B的話 ,子彈到達B點的時候敵人R1也恰好到達B點處,但是R1隨時都有可能改變方向返 回,這取決於random()方法。如果剛開始ahead(Math.random()*200)中 Math.random()返回一個很大的值,大到足以使R1運動到B點甚至超過B點,那 麼你將擊中敵人;如果這個返回值很小,使R1還沒到達B處就返回了,這樣你這 發子彈就浪費了。所以說你仍然有機會擊中它,它並不是難以掌握的,只是什麼 時候能擊中什麼時候不能擊中,誰都說不清楚。

對瞄准有干擾性的主動 運動

看了上面兩種運動方式的分析,也許在你心頭有這樣的想法,我先 以一種很明顯的規律運動,等敵人誤認為我是那種方式運動後立刻改變為另一種 規律,然後等敵人意識到現在的運動規律後我又改變為原來那種,這樣敵人是否 就被我迷惑了呢?呵呵,的確,這樣是一種很不錯的方法,許多優秀的機器人的 運動有不同程度的干擾迷惑性。我還是先舉個例子來說說吧。假如一個機器人一 開始不動,你會采取怎樣的射擊方法呢?一般都會用對付Corner的當前位置射擊 方法吧?但是當你發射子彈後,它又開始直線運動了,這時如果你的炮管冷卻度 為0的話,你采取第二次射擊,你怎麼辦?用對付Corner的當前位置射擊方法? 你顯然打不中它,因為它在動,但是如果用對付Walls的直線提前量射擊方法的 話,你能肯定它不會在下一個周期(滴答)停下?這是一種典型的對瞄准有干擾 性的主動運動,優秀的機器人Wolverine就是采用了這種方法,它能探測敵人什 麼時候發彈,在敵人發彈的一瞬間改變運動方式如圖6:(具體請見 躲避子彈)

圖6

這樣的運動方式通過代碼已經很難掌握它的具體變化規律,因此在Wolverine 剛出來的時候沒有幾個機器人能打敗Wolverine。後來優秀的機器人不斷進展, 有的能計算敵人停留了多久就會動,動了多遠又會停止,雖然不能很精確,但是 總能時而擊中它了。

更先進的干擾運動有先小距離來回運動,然後走一 段比較長的距離(比如xieming的CX1.33,文件名為cx.MinixHT_1.33);還有先 往一個方向直線運動,估算敵人子彈快要擊中自己的時候改變運動方向,下一個 子彈快擊中時又改變方向(如Glyn Davies的Mooserwirt2)等等。很多優秀的機 器人都采用了類似的運動方式,怎樣才能不被干擾?怎樣才能識別干擾?沒有一 種識別所有干擾的萬能方法,因此只能針對特定一種或某一類干擾進行處理,比 如CX1.33的干擾,你可以記下它的較長運動距離平均(這裡用L表示)是多少?當 他運動距離超過了小距離來回運動的那個距離的時候,你就不要以為他還會掉頭 回去或者就一直走下去,它應該大概在走了L距離後返回。對於眾多的運動方式 ,怎樣識別一個干擾又是一個難題,所以在射擊優秀的機器人時,命中率一般不 會太高。

怎樣讓別人不斷的被干擾成為設計一個優秀運動的重點,也是 樂趣所在。當你設計的運動方式不斷的迷惑敵人的時候,你是否有種嬉笑歡快的 感覺呢!:)

依據對方發彈或者運動而采取的被動運動

前面我們 講到的Wolverine在敵人發彈後才開始運動,是否他也屬於這一類呢?的確,它 的運動方式也應該同時屬於依據對方發彈或者運動而采取的被動運動。

還有一些優秀的機器人很類似Wolverine,它們也是在敵人發彈後才開始運動, 但是他們又有很多不同,如果敵人不發彈,一般來說他就一直不動(Wolverine 也許會開始靠近你,雖然這也許是個好方法),比如我寫的cx.ChookMT,每次如 果它探測到了敵人發了彈,它會采用自己的分析策略自動分析生成一個 EnemyBullet對象,然後實時監控會不會有某個特定的EnemyBullet對它有危險( 快要擊中它),如果有危險,那麼分析哪個方向沒有危險就往哪個方向運動,這 樣如果它分析並生成的EnemyBullet和真正的敵人的Bullet(子彈)運動方向一 致,那麼它幾乎將永遠不會被擊中。顯然這不太可能總是一致,雖然不能達到永 遠不被擊中的效果,但是你會發現他仍然是難以被擊中的。

類似策略的 還有 Daniel Pereira的EveKingpin和Eve等。另外Fermat的運動方式也應該屬於 這一類,雖然很難肯定它的具體躲避策略,但是從對戰中它總能在敵人子彈快要 擊中它的時候改變速度和方向等等(其實它的運動很難看懂,它總在動,有時候 還不停的調整運動方向等)看出來,它應該記錄了敵人的子彈。還有很多機器人 多多少少都有保持自己與敵人的距離的特點,最明顯的莫過於Wolverine和 Fermat,前者總是與敵人保持一段很小的距離(大概200個像素點左右),而 Fermat總要與敵人保持相當遠的距離,你也許經常看到Fermat被敵人追著跑的現 象(這並不意味著Fermat害怕它哦^_^),當你發現你在遠處或者近處的時候你的 射擊非常准或者別人的射擊非常不准的時候,你就該考慮你的機器人是否也應該 與敵人始終保持一定的距離了。

總 結

通過這些分析是否會發現 第三第四種運動方式比第一第二種高級,這是顯然!:)但是你要知道後兩種運 動方式的設計和編碼難度比前兩種也要難得多,而且,也不一定就比前兩種優秀 ,有時候想出一種奇異的簡單運動得到的效果遠遠大於經過大量編碼的復雜運動 ,有很多人的確做到了,現在有很多 little,micro,nano,mini機器人(比如 Grafi的MicroGeek,MiniGeek,Dummy的Eddie等)它們代碼長度往往只有幾十行, 運動規律也比較簡單,但是往往你並不能很好掌握對付它們的射擊策略,你寫了 幾千行代碼辛苦設計的機器人也許根本拿他們沒辦法。

我這裡並不是要 說明哪種類型的運動方式最好,這沒有絕對,而且優秀的機器人並不局限於一種 類型的運動方式,它們或許集幾種方式於一身,在情況不妙的時候就切換運動方 式,或者輸了一局後就在下一局采取另外一個策略(如Manfred Schuster的Ares ,它擁有不少於4種策略)。

好了,就說到這吧,你是否已經在心裡策劃 著你的下一個機器人的運動策略了呢?提醒一點:你的運動策略出來了,或許別 人的相似運動策略也同時出來了,而且有一種機器人能克隆敵人的運動,如 Dummy的Parakeet,Martin Y Lepsoy的Clone等,它們做出與你幾乎相同的運動 ,所以想到了獨特的運動策略也不要忘了設計對付此策略的射擊方法,只有運動 和射擊同樣優秀的機器人才能不斷的獲得勝利。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved