Module/Targeting/GFTargetingWaves
Jump to navigation
Jump to search
A screenshot before the code showing a Module Bot throwing waves to get the offsets, and turning the gun accordingly.
package jab.targeting;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.util.Enumeration;
import java.util.Vector;
import robocode.util.Utils;
import jab.Module;
import jab.Targeting;
/**
* Credits
* GFTargetingWaves by jab. Code license: RWPCL
* A simple GuessFactorTargeting using waves and without segmentation
*/
public class GFTargetingWaves extends Targeting {
public GFTargetingWaves(Module bot) {
super(bot);
}
// The last waves of the historical to calculate the meanOffset
static final int LIMIT = 10;
// Throw a wave
static final int TICKS = 3;
Vector<Wave> waves = new Vector<Wave>();
Vector<Offset> offsets = new Vector<Offset>();
public void target() {
updateWaves();
if ((int) bot.getTime() % TICKS == 0)
throwWave();
calculateMeanOffsetAndTurnGun();
}
private void updateWaves() {
Enumeration<Wave> e = waves.elements();
while (e.hasMoreElements()) {
Wave wave = e.nextElement();
wave.time++;
// The current enemy has changed
if (!wave.enemyName.equals(bot.enemy.name)) {
waves.remove(wave);
offsets.clear();
}
// The wave breaks
else if (wave.velocity * wave.time > Point2D.distance(wave.originX,
wave.originY, bot.enemy.x, bot.enemy.y)) {
double thetaFireTime = Utils
.normalAbsoluteAngle(Math.atan2(wave.enemyX
- wave.originX, wave.enemyY - wave.originY));
double thetaBreak = Utils
.normalAbsoluteAngle(Math.atan2(bot.enemy.x
- wave.originX, bot.enemy.y - wave.originY));
offsets.add(new Offset(bot.enemy.name, Utils
.normalRelativeAngle(thetaFireTime - thetaBreak)));
waves.remove(wave);
}
}
}
private void throwWave() {
waves.add(new Wave(bot.getX(), bot.getY(), bot.bulletPower,
bot.enemy.name, bot.enemy.x, bot.enemy.y));
}
private void calculateMeanOffsetAndTurnGun() {
double meanOffset = 0;
double offsetsCounter = 0;
int i = offsets.size() - 1;
while (i >= 0 && offsetsCounter < LIMIT) {
Offset o = offsets.get(i);
if (o.enemyName.equals(bot.enemy.name) && offsetsCounter <= LIMIT) {
meanOffset += o.offset;
offsetsCounter++;
}
i--;
}
if (offsetsCounter != 0)
meanOffset /= offsetsCounter;
double absoluteBearing = bot.getHeadingRadians()
+ bot.enemy.bearingRadians - meanOffset;
bot.setTurnGunRightRadians(robocode.util.Utils
.normalRelativeAngle(absoluteBearing
- bot.getGunHeadingRadians()));
}
// Draw the waves
public void onPaint(Graphics2D g) {
Enumeration<Wave> e = waves.elements();
while (e.hasMoreElements()) {
g.setColor(Color.BLUE);
Wave wave = e.nextElement();
double travelledDistance = wave.time * wave.velocity;
g.drawOval((int) wave.originX - (int) travelledDistance,
(int) wave.originY - (int) travelledDistance,
(int) travelledDistance * 2, (int) travelledDistance * 2);
g.drawLine((int) wave.originX, (int) wave.originY,
(int) wave.enemyX, (int) wave.enemyY);
g.setColor(Color.GREEN);
g.drawLine((int) wave.originX, (int) wave.originY,
(int) bot.enemy.x, (int) bot.enemy.y);
}
}
public class Wave {
public double time;
public double originX, originY;
public double velocity;
public double enemyX, enemyY;
public String enemyName;
public Wave(double x, double y, double bulletPower, String enemyName,
double enemyX, double enemyY) {
originX = x;
originY = y;
velocity = 20.0 - 3.0 * bulletPower;
time = 0;
this.enemyName = enemyName;
this.enemyX = enemyX;
this.enemyY = enemyY;
}
}
public class Offset {
public double offset;
public String enemyName;
public Offset(String enemyName, double offset) {
this.enemyName = enemyName;
this.offset = offset;
}
}
}