User:Voidious/LocationBot
Jump to navigation
Jump to search
A little test bot I built to help me unit test my Precise Prediction code. I run it in a battle against SittingDuck on a 1000x1000 field. He goes to the center of the field, notes his start state, turns to a random heading, moves / turns a random amount, and notes where he starts and ends.
He can print all the raw info or just output a method call with all the data. Of course, you'd have to write that method yourself to use it to test your own predictor. I just take his console output, grep the lines with the method call, and paste them into my unit test.
package voidious.test;
import java.awt.geom.Point2D;
import robocode.AdvancedRobot;
import robocode.HitRobotEvent;
import robocode.HitWallEvent;
import robocode.util.Utils;
public class LocationBot extends AdvancedRobot {
private static final boolean PRINT_DEBUG_INFO = false;
private static final boolean DISCARD_ROBOT_HITS = true;
private static final boolean DISCARD_WALL_HITS = false;
private boolean hitRobot;
private boolean hitWall;
public void run() {
Point2D.Double startPoint = new Point2D.Double(500, 500);
for (int x = 0; x < 100; x++) {
hitRobot = false;
hitWall = false;
StringBuilder debugString = new StringBuilder();
StringBuilder testString = new StringBuilder();
setMaxVelocity(8);
do {
double goAngle = absoluteBearing(myLocation(), startPoint);
setBackAsFront(this, goAngle);
execute();
} while (myLocation().distanceSq(startPoint) > 0.1);
turnRightRadians(Math.random() * 2 * Math.PI);
double distance = (300 + (Math.random() * 1000))
* ((Math.random() > 0.5) ? 1 : -1);
double turn = (Math.random() * 4 * Math.PI) - (2 * Math.PI);
double maxVelocity;
if (Math.random() < 0.5) {
maxVelocity = 8;
} else {
maxVelocity = Math.random() * 7.5 + 0.5;
}
if (PRINT_DEBUG_INFO) {
debugString.append("Start state: ");
debugString.append("\n");
debugString.append(" Location: " + myLocation());
debugString.append("\n");
debugString.append(" Heading: " + getHeadingRadians());
debugString.append("\n");
debugString.append(" Velocity: " + getVelocity());
debugString.append("\n");
debugString.append(" Time: " + getTime());
debugString.append("\n");
debugString.append("Distance: " + distance);
debugString.append("\n");
debugString.append("Turn: " + turn);
debugString.append("\n");
debugString.append("Max Velocity: " + maxVelocity);
debugString.append("\n");
}
Point2D.Double myLocation = myLocation();
testString.append(myLocation.x);
testString.append(", ");
testString.append(myLocation.y);
testString.append(", ");
testString.append(getHeadingRadians());
testString.append(", ");
testString.append(getVelocity());
testString.append(", ");
testString.append(getTime());
testString.append("L, ");
testString.append(distance);
testString.append(", ");
testString.append(turn);
testString.append(", ");
testString.append(maxVelocity);
testString.append(", ");
setMaxVelocity(maxVelocity);
setAhead(distance);
setTurnRightRadians(turn);
do {
execute();
} while (Math.abs(getDistanceRemaining()) > 0.000001);
if (PRINT_DEBUG_INFO) {
debugString.append("End time: " + getTime());
debugString.append("\n");
myLocation = myLocation();
debugString.append("End location: " + myLocation);
debugString.append("\n");
debugString.append("End heading: " + getHeadingRadians());
}
testString.append(getTime());
testString.append("L, ");
myLocation = myLocation();
testString.append(myLocation.x);
testString.append(", ");
testString.append(myLocation.y);
testString.append(", ");
testString.append(getHeadingRadians());
if ((!hitRobot || !DISCARD_ROBOT_HITS)
&& (!hitWall || !DISCARD_WALL_HITS)) {
if (PRINT_DEBUG_INFO) {
System.out.println(debugString.toString());
}
System.out.println("testPrediction(" + testString.toString() + ");");
if (PRINT_DEBUG_INFO) {
System.out.println("***************************************");
}
}
}
}
@Override
public void onHitRobot(HitRobotEvent e) {
if (!hitRobot) {
System.out.println("HIT A ROBOT");
hitRobot = true;
}
}
@Override
public void onHitWall(HitWallEvent e) {
if (!hitWall) {
System.out.println("HIT A WALL");
hitWall = true;
}
}
private Point2D.Double myLocation() {
return new Point2D.Double(getX(), getY());
}
public static double absoluteBearing(Point2D.Double sourceLocation,
Point2D.Double target) {
return Math.atan2(target.x - sourceLocation.x,
target.y - sourceLocation.y);
}
public static void setBackAsFront(AdvancedRobot robot, double goAngle) {
double angle =
Utils.normalRelativeAngle(goAngle - robot.getHeadingRadians());
if (Math.abs(angle) > (Math.PI / 2)) {
if (angle < 0) {
robot.setTurnRightRadians(Math.PI + angle);
} else {
robot.setTurnLeftRadians(Math.PI - angle);
}
robot.setBack(100);
} else {
if (angle < 0) {
robot.setTurnLeftRadians(-1 * angle);
} else {
robot.setTurnRightRadians(angle);
}
robot.setAhead(100);
}
}
}
Sample test method:
private void testPrediction(double startX, double startY,
double startHeading, double startVelocity, long startTime,
double distance, double turn, double maxVelocity, long endTime,
double endX, double endY, double endHeading) {
MovementPredictor predictor = newPredictor();
RobotState startState = new RobotState(newLocation(startX, startY),
startHeading, startVelocity, startTime);
long ticks = endTime - startTime;
RobotState endState = predictor.predict(startState, distance, turn,
maxVelocity, ticks, false);
assertEquals(endX, endState.location.x, 0.01);
assertEquals(endY, endState.location.y, 0.01);
assertEquals(Utils.normalAbsoluteAngle(endHeading),
Utils.normalAbsoluteAngle(endState.heading), 0.01);
}