A bot that records raw wave data while firing with
RandomTargeting in a TC mode. Part of my recent
Segmentation Research, and meant to be analyzed with
WaveReader. --
Voidious
package voidious.test;
import robocode.*;
import robocode.util.Utils;
import java.awt.geom.*;
import robocode.RobocodeFileWriter;
/**
* WaveRecorder.java
*
* Some GuessFactorTargeting analysis by Voidious.
*
* This code is open source, released under the RoboWiki Public Code License:
* http://robowiki.net/cgi-bin/robowiki?RWPCL
*/
public class WaveRecorder extends AdvancedRobot {
public static Point2D.Double _myLocation;
public static Point2D.Double _enemyLocation;
private static double _enemyAbsoluteBearing;
private static int _lastGunOrientation;
private static double _lastDistance;
private double _timeSinceVChange = 0;
private static int _enemyVelocity;
private static String _enemyName = "";
private static java.awt.geom.Rectangle2D.Double _fieldRect
= new java.awt.geom.Rectangle2D.Double(18, 18, 764, 564);
private static String _waveLog = "";
private static String _roundWaveLog = "";
public void run() {
_roundWaveLog = "";
setAdjustGunForRobotTurn(true);
setAdjustRadarForGunTurn(true);
do {
turnRadarRightRadians(Double.POSITIVE_INFINITY);
} while (true);
}
public void onScannedRobot(ScannedRobotEvent e) {
_enemyName = e.getName();
setTurnRadarRightRadians(Utils.normalRelativeAngle((_enemyAbsoluteBearing = getHeadingRadians() + e.getBearingRadians()) - getRadarHeadingRadians()) * 2);
////////////////////////////////////////////////////////
// CREDIT: RaikoMicro's gun, by Jamougha
// http://robowiki.net?RaikoMicro
////////////////////////////////////////////////////////
Wave w;
addCustomEvent(w = new Wave());
_enemyLocation =
project((_myLocation = new Point2D.Double(getX(), getY())),
_enemyAbsoluteBearing, _lastDistance = e.getDistance());
double power = 3;
w.distanceTraveled = 0;
double enemyLatVel;
_lastGunOrientation = sign(enemyLatVel = (e.getVelocity())*Math.sin(e.getHeadingRadians() - _enemyAbsoluteBearing));
_timeSinceVChange++;
int newVelocity, accel;
accel = 1;
if (_enemyVelocity != (newVelocity = (int)(Math.abs(enemyLatVel)))) {
_timeSinceVChange = 0;
accel = 2;
if (_enemyVelocity > newVelocity) {
accel = 0;
}
}
_enemyVelocity = newVelocity;
double maxEscapeAngle = Math.asin(8D/(20 - (3 * power)));
double wallDistance = 3;
for (double d = 0; d < 3; d += 0.01) {
if (!gunWallDistance(d * maxEscapeAngle)) {
wallDistance = d;
break;
}
}
w.bulletVelocity = (20 - (3 * power));
w.orientation = _lastGunOrientation;
w.velocity = Math.abs(e.getVelocity());
w.relativeHeading = Utils.normalAbsoluteAngle(e.getHeadingRadians() + (e.getVelocity() < 0?Math.PI:0) - _enemyAbsoluteBearing);
if (w.relativeHeading > Math.PI) {
w.relativeHeading = ((2 * Math.PI) - w.relativeHeading);
}
w.latVel = Math.abs(enemyLatVel);
w.distance = _lastDistance;
w.timeSinceVChange = (long)_timeSinceVChange;
w.wallDistance = wallDistance;
w.accel = accel;
w.sourceLocation = _myLocation;
w.directAngle = _enemyAbsoluteBearing;
setTurnGunRightRadians(Utils.normalRelativeAngle(_enemyAbsoluteBearing - getGunHeadingRadians() + ((_lastGunOrientation*maxEscapeAngle)*((Math.random() * 2) - 1)) ));
if (setFireBullet(3) != null) {
w.firing = true;
}
}
public void onCustomEvent(CustomEvent e) {
removeCustomEvent(e.getCondition());
}
private static double getGuessFactor(Wave w, Point2D.Double botLocation) {
return (Utils.normalRelativeAngle(
w.absoluteBearing(botLocation)
- w.directAngle) * w.orientation)
/ Math.asin(8D/w.bulletVelocity);
}
public static void logHit(Wave w, Point2D.Double targetLocation,
int roundNum) {
String output = "";
output += roundNum + " : ";
output += (w.firing?1:0) + " : ";
output += w.orientation + " : ";
output += round(getGuessFactor(w, targetLocation), 5) + " : ";
output += round(w.velocity, 2) + " : ";
output += round(w.latVel, 2) + " : ";
output += w.accel + " : ";
output += w.timeSinceVChange + " : ";
output += round(w.distance, 1) + " : ";
output += round(w.wallDistance, 3) + " : ";
output += round(w.relativeHeading, 4) + "\n";
_roundWaveLog += output;
}
public void onWin(WinEvent e) {
roundOver();
}
public void onDeath(DeathEvent e) {
roundOver();
}
public void roundOver() {
_waveLog += _roundWaveLog;
if (getRoundNum() == getNumRounds() - 1) {
try {
int x = 0;
while (x < 1000 && getDataFile(_enemyName + "." + x + ".txt").exists()) {
x++;
}
RobocodeFileWriter writer = new RobocodeFileWriter(
getDataFile(_enemyName + "." + x + ".txt"));
writer.write(_waveLog);
writer.close();
} catch (Exception e) { }
}
}
/*
private static double limit(double min, double value, double max) {
return Math.max(min, Math.min(value, max));
}
*/
// CREDIT: ganked from CassiusClay, by PEZ
// http://robowiki.net?CassiusClay
private static Point2D.Double project(Point2D.Double sourceLocation, double angle, double length) {
return new Point2D.Double(sourceLocation.x + Math.sin(angle) * length,
sourceLocation.y + Math.cos(angle) * length);
}
private static int sign(double d) {
if (d < 0) { return -1; }
return 1;
}
private static double round(double d, int i) {
long powerTen = 1;
for (int x = 0; x < i; x++) {
powerTen *= 10;
}
return ((double)Math.round(d * powerTen)) / powerTen;
}
private static boolean gunWallDistance(double wallDistance) {
return _fieldRect.contains(project(_myLocation, _enemyAbsoluteBearing + (_lastGunOrientation*wallDistance), _lastDistance));
}
class Wave extends Condition {
Point2D.Double sourceLocation;
double bulletVelocity, directAngle, distanceTraveled;
int orientation, weight, roundNum;
long timeSinceVChange;
int accel;
double velocity, distance, latVel, wallDistance, relativeHeading;
boolean firing = false;
public double distanceToPoint(Point2D.Double p) {
return sourceLocation.distance(p);
}
public double absoluteBearing(Point2D.Double target) {
return Math.atan2(target.x - sourceLocation.x, target.y - sourceLocation.y);
}
public boolean test() {
if (distanceToPoint(WaveRecorder._enemyLocation)
<= (distanceTraveled+=bulletVelocity) + (.5*bulletVelocity)) {
WaveRecorder.logHit(this, WaveRecorder._enemyLocation,
getRoundNum());
return true;
}
return false;
}
}
}