/**
*
*/
package rampancy.micro;
import java.awt.*;
import robocode.AdvancedRobot;
import robocode.HitWallEvent;
import robocode.ScannedRobotEvent;
import robocode.util.Utils;
/**
* @author Matthew Chun-Lum
*
*/
public class Harbinger extends AdvancedRobot {
private static StringBuffer history;
private static double previousHeading;
private double targetX, targetY;
private double moveDist;
private double lastEnergy;
public void run() {
setColors(new Color(0x660C17), new Color(0x454545), new Color(0x454545), Color.white, new Color(0x454545));
this.setAdjustGunForRobotTurn(true);
this.setAdjustRadarForGunTurn(true);
this.setAdjustRadarForRobotTurn(true);
if(history == null)
history = new StringBuffer();
while(getRadarTurnRemainingRadians() == 0) {
setTurnRadarLeftRadians(Math.PI * 5);
}
}
public void onScannedRobot(ScannedRobotEvent e) {
double radarBearingOffset = Utils.normalRelativeAngle(getRadarHeadingRadians() - (e.getBearingRadians() + getHeadingRadians()));
int sign = (radarBearingOffset < 0 ? -1 : 1 );
setTurnRadarLeftRadians(radarBearingOffset + sign * (Math.PI / 6));
// record state in history
double heading = e.getHeadingRadians();
char dh = toChar(Utils.normalRelativeAngle(heading - previousHeading));
previousHeading = heading;
char vel = toChar(e.getVelocity());
history.append("A" + dh + "B" + vel);
double absB = Utils.normalAbsoluteAngle(e.getBearingRadians() + getHeadingRadians());
double x = getX();
double y = getY();
targetX = projectX(x, absB, e.getDistance());
targetY = projectY(y, absB, e.getDistance());
double power = e.getEnergy() == 0 ? 0.1 : e.getDistance() < 30 ? 3.0 : -1;
double maxPower = getEnergy() < 30 ? 0.5 : 2.0;
// gun code
if(history.length() > 320) {
int ind = history.indexOf(history.substring(history.length() - 32, history.length()));
if(e.getEnergy() > 0 && power != 3.0 && ind != -1 && ind < (history.length() - 32 - 4 * 20)) {
String match = history.substring(ind, history.length() - 32);
for(int i = 0; i < match.length(); i = i + 4) {
heading += toDouble(match.charAt(i+1));
double velocity = toDouble(match.charAt(i+3));
targetX = projectX(targetX, heading, velocity);
targetY = projectY(targetY, heading, velocity);
double pow = (20.0 - distance(x, y, targetX, targetY)/(i/4+1)) / 3.0;
if(pow > power) {
power = pow;
}
if(pow > maxPower)
break;
}
}
double angle = Utils.normalRelativeAngle(Utils.normalAbsoluteAngle(Math.atan2(targetX - x, targetY - y)) - getGunHeadingRadians());
setTurnGunRightRadians(angle);
if(power >= 0.1) {
setFire(power);
}
}
// movement
if(e.getEnergy() > lastEnergy) {
moveDist = Math.random() * 20000 - 10000;
}
lastEnergy = e.getEnergy();
setAhead(moveDist);
setTurnRightRadians(Utils.normalRelativeAngle(absB + Math.PI / 2 - getHeadingRadians()));
}
public void onHitWall(HitWallEvent e) {
moveDist = -moveDist;
}
public char toChar(double value) {
return (char) (value * 1000 + 32767);
}
public double toDouble(char ch) {
return (double) ((int) ch - 32767) / (1000.0);
}
public double projectX(double sx, double angle, double dist) {
return sx + Math.sin(angle) * dist;
}
public double projectY(double sy, double angle, double dist) {
return sy + Math.cos(angle) * dist;
}
public double distance(double x1, double y1, double x2, double y2) {
x1 -= x2;
y1 -= y2;
return Math.sqrt(x1 * x1 + y1 * y1);
}
}