# Robocode 高手的秘诀：圆周瞄准

## 工作原理

`change in x = cos(initialheading) * radius - cos(initialheading + changeinheading) * radius`

`change in y = sin(initialheading + changeinheading) * radius - sin(initialheading) * radius`

### 计算必要的数据

##### 图 1. 沿圆周移动

• 每转的方向变化：我们用 `headingchangeperturn = (heading2 - heading1)/time` 得到这个值，其中 time是两次测量的间隔时间。您还必须使结果标准化，如下面代码中所示。
• 子弹时间：我们使用简单的 `time = getTime()+(range/(20-(3*firepower)))` 就可以满足需要了。其中 range是发射时我们和敌人之间的距离，而 firepower是我们计划使用的射击火力。假定子弹击中时，目标到我方的距离不变，这个假设并不合适，但是我们在本文后面的内容中开发出迭代之前，有它就足够了。
• 半径：我们用 `radius = velocity/headingchangeperturn` 得出这个值。

### 代码

##### 清单 1. 圆周瞄准代码
```public Point2D.Double guessPosition(long when) {
/**time is when our scan data was produced.  when is the time
that we think the bullet will reach the target.  diff is the
difference between the two **/
double diff = when - time;
double newX, newY;
/**if there is a significant change in heading, use circular
path prediction**/
}
/**if the change in heading is insignificant, use linear
path prediction**/
else {
newY = y + Math.cos(heading) * speed * diff;
newX = x + Math.sin(heading) * speed * diff;
}
return new Point2D.Double(newX, newY);
}```

## 改进结果

##### 清单 2. 迭代代码
```/**This function predicts the time of the intersection between the
bullet and the target based on a simple iteration.  It then moves
the gun to the correct angle to fire on the target.**/
void doGun() {
long time;
long nextTime;
Point2D.Double p;
p = new Point2D.Double(target.x, target.y);
for (int i = 0; i < 10; i++){
nextTime =
(intMath.round((getRange(getX(),getY(),p.x,p.y)/(20-(3*firePower))));
time = getTime() + nextTime;
p = target.guessPosition(time);
}
/**Turn the gun to the correct angle**/
(Math.PI/2 - Math.atan2(p.y - getY(), p.x - getX()));
}
double normaliseBearing(double ang) {
if (ang > Math.PI)
ang -= 2*PI;
if (ang < -Math.PI)
ang += 2*Math.PI;
return ang;
}
public double getrange(double x1,double y1, double x2,double y2) {
double x = x2-x1;
double y = y2-y1;
double h = Math.sqrt( x*x + y*y );
return h;
}```

## 改进圆周瞄准的性能

• 平均速度：您也许愿意保持一个补偿加速效应的移动平平均速度，而不是根据目标的最后速度进行计算。
• 每一回合方向的平均变化：测量在每一回合内目标方向变化绝对量的平均值有助于我们对付那些不如 spinbot 有规律的目标。

#### 相关主题

• 下载本示例中使用的 源代码
• 请阅读“ Secrets from the Robocode masters”的全部内容。该页面在有新技巧时会被更新。
• 请从 alphaWorks 下载 Robocode的最新版本。
• Mathew Nelson 是 Robocode 的创建者，他维护着 官方 Robocode 站点。这应当是所有关心 Robocode 的人的第一站。
• RoboLeague是针对 Robocode 的联盟以及赛季管理者，由 Robocodeby Christian Schnell 负责。它确保所有可能的分组实际打好比赛、管理结果并生成 HTML 状态报告。
• Rock 'em, sock 'em Robocode”（ developerWorks，2002 年 1 月）拆解 Robocode，同时带着您着手建造属于自己的、定制的、小而精悍的战斗机器。
• Rock 'em, sock 'em Robocode: Round 2”（ developerWorks，2002 年 5 月）大胆参加高级机器人的构建和团队模式的游戏。
• 请在 developerWorksJava 技术专区查找 Java 方面的其它参考资料。

#### 评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Java technology
ArticleID=53322
ArticleTitle=Robocode 高手的秘诀：圆周瞄准
publish-date=05272002