Difference between revisions of "User:Voidious/LocationBot"
Jump to navigation
Jump to search
(helper bot for testing precise prediction) |
(add test method signature / sample) |
||
(One intermediate revision by the same user not shown) | |||
Line 11: | Line 11: | ||
import robocode.HitRobotEvent; | import robocode.HitRobotEvent; | ||
import robocode.HitWallEvent; | import robocode.HitWallEvent; | ||
− | import | + | import robocode.util.Utils; |
public class LocationBot extends AdvancedRobot { | public class LocationBot extends AdvancedRobot { | ||
Line 30: | Line 30: | ||
setMaxVelocity(8); | setMaxVelocity(8); | ||
do { | do { | ||
− | double goAngle = | + | double goAngle = absoluteBearing(myLocation(), startPoint); |
− | + | setBackAsFront(this, goAngle); | |
execute(); | execute(); | ||
} while (myLocation().distanceSq(startPoint) > 0.1); | } while (myLocation().distanceSq(startPoint) > 0.1); | ||
Line 139: | Line 139: | ||
private Point2D.Double myLocation() { | private Point2D.Double myLocation() { | ||
return new Point2D.Double(getX(), getY()); | 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); | ||
+ | } | ||
} | } | ||
} | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Sample test method: | ||
+ | <syntaxhighlight> | ||
+ | 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); | ||
+ | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Latest revision as of 22:48, 10 June 2012
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);
}