User:Voidious/LocationBot
From RoboWiki
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); }