在我向您展示這一技巧之前,您必須了解 Robocode 的一些基礎知識。首先 ,它攻擊和防守使用的是一個能量倉。這就帶來了有趣的博弈決定:您必須決定 何時使用能量向對手開炮,何時保存能量以應付可能的損失。
其次,機器人對於周圍環境的了解非常有限。它可以知道其它機器人的距離 、方位、方向、速度和能量等級。但是,它看不到子彈,不過也許根據這些線索 ,您可以猜想如何發現其它機器人正向它開炮。
DodgeBot 靜止不動,不斷的跟蹤對手的前一能量等級。當它的能量下降一定 的量時,DodgeBot 就認為它開炮了,並移向左邊或右邊。令人吃驚的是,這將 會迷惑大多數機器人的瞄准方法。它們要麼直接向目標開炮,要麼試著根據您的 速度和方向來推算位置。如果您的機器人不移動,兩種算法都會正好沖著這個機 器人開炮。而您的機器人猜到了這一點,向旁邊躍出一小步,但子彈仍是沿原來 的方向。圖 1 展示了實際的 DodgeBot。
圖 1. DodgeBot 對 Tracker(上當了!)
清單 1展示了 DodgeBot 的代碼。每當雷達覺察到敵人時執行主代碼部分。 DodgeBot 保持自己的直角狀態,另外還有 30 度傾向對手。以 90 度角靜止使 機器人避開子彈的能力達到最大。附加的 30 度傾斜使機器人具有一定的攻擊力 ,並逐漸接近目標。接著是代碼的關鍵部分:如果機器人覺察到能量下降介於 0.1 和 3.0 之間(火力范圍),那麼機器人就立即切換方向,向左或向右移動 。很簡單。它會切換炮和雷達掃描的方向,假定如果它在最後一次掃描中看到了 一個機器人,那麼當它再次掃過同一區域時還會再發現它。這時機器人就會開炮 。因為我把炮和雷達聯系在一起,而掃描器是在它面朝對手的那一刻被調用的, 所以炮會正對著對手開炮。最後,我會為下一回合記下對手的能量。
清單 1. DodgeBot 的代碼
import robocode.*;
public class DodgeBot extends AdvancedRobot
double previousEnergy = 100;
int movementDirection = 1;
int gunDirection = 1;
public void run() {
setTurnGunRight(99999);
}
public void onScannedRobot(
ScannedRobotEvent e) {
// Stay at right angles to the opponent
setTurnRight(e.getBearing()+90-
30*movementDirection);
// If the bot has small energy drop,
// assume it fired
double changeInEnergy =
previousEnergy-e.getEnergy();
if (changeInEnergy>0 &&
changeInEnergy<=3) {
// Dodge!
movementDirection =
-movementDirection;
setAhead((e.getDistance()/4+25)movementDirection);
}
// When a bot is spotted,
// sweep the gun and radar
gunDirection = -gunDirection;
setTurnGunRight(99999*gunDirection);
// Fire directly at target
f i r e ( 2 ) ;
// Track the energy level
previousEnergy = e.getEnergy();
}
}
我在叫做 Wolverine 的機器人上使用了這一技巧,它另外使用了一些感應器 信息以使感覺更准確。當對手擊中我的機器人時,對手得重新充能量。當我的機 器人擊中對手時,能量等級就會下降。機器人可能同時感受到這兩件事情,所以 Wolverine 利用這一信息來抵消對等的能量波動。
這個技巧還存在問題。子彈一發射,機器人就移動,所以它最終可能會移回 炮彈軌跡之內。最好是在估計子彈要到達時再移動。
更嚴重的問題是,即使您能夠迷惑平常的瞄准,但實際上向旁邊一步一步的 移動很容易預測。使用這一技巧的最佳方式可能是讓信息指導您的移動,而不是 讓它控制。
您也許會想,這個技巧這麼簡單,您自己原本也是想得到的。不錯。這個游 戲就是這樣玩的,這也正是它為什麼如此吸引人的緣故。Robocode 就象棋類游 戲,每新走一步都會是一個新的想法。