FuturePosition
Jump to navigation
Jump to search
Precise Prediction code by Albert, used by many Wave Surfers.
The parameters are like follows:
- steps - number of ticks you want to predict.
- b - is your robot. Just use "this".
- maxVel and maxTurnRate - the maximum velocity and turn rate allowed. Use them only if you have used setMaxVelocity() or setMaxTurnRate()
package apv;
import java.awt.geom.Point2D;
import java.util.Vector;
import robocode.util.*;
import robocode.*;
public class MovSim {
private double systemMaxTurnRate = Math.toRadians(10.0);
private double systemMaxVelocity = 8.0;
private double maxBraking = 2.0;
private double maxAcceleration = 1.0;
public double defaultMaxTurnRate = 10.0;
public double defaultMaxVelocity = 8.0;
public MovSim() {};
public MovSimStat[] futurePos(int steps, AdvancedRobot b) { return futurePos(steps, b, defaultMaxVelocity, defaultMaxTurnRate); }
public MovSimStat[] futurePos(int steps, AdvancedRobot b, double maxVel, double maxTurnRate) {
return futurePos(steps, b.getX(), b.getY(), b.getVelocity(), maxVel, b.getHeadingRadians(), b.getDistanceRemaining(), b.getTurnRemainingRadians(), maxTurnRate, b.getBattleFieldWidth(), b.getBattleFieldHeight());
}
private MovSimStat[] futurePos(int steps, double x, double y, double velocity, double maxVelocity, double heading, double distanceRemaining, double angleToTurn, double maxTurnRate, double battleFieldW, double battleFieldH) {
//maxTurnRate in degrees
MovSimStat[] pos = new MovSimStat[steps];
double acceleration = 0;
boolean slowingDown = false;
double moveDirection;
maxTurnRate = Math.toRadians(maxTurnRate);
if (distanceRemaining == 0) moveDirection = 0; else if (distanceRemaining < 0.0) moveDirection = -1; else moveDirection = 1;
//heading, accel, velocity, distance
for (int i=0; i<steps; i ) {
//heading
double lastHeading = heading;
double turnRate = Math.min(maxTurnRate, ((0.4 0.6 * (1.0 - (Math.abs(velocity) / systemMaxVelocity))) * systemMaxTurnRate));
if (angleToTurn > 0.0) {
if (angleToTurn < turnRate) { heading = angleToTurn; angleToTurn = 0.0; }
else { heading = turnRate; angleToTurn -= turnRate; }
} else if (angleToTurn < 0.0) {
if (angleToTurn > -turnRate) { heading = angleToTurn; angleToTurn = 0.0; }
else { heading -= turnRate; angleToTurn = turnRate; }
}
heading = Utils.normalAbsoluteAngle(heading);
//movement
if (distanceRemaining != 0.0 || velocity != 0.0) {
//lastX = x; lastY = y;
if (!slowingDown && moveDirection == 0) {
slowingDown = true;
if (velocity > 0.0) moveDirection = 1;
else if (velocity < 0.0) moveDirection = -1;
else moveDirection = 0;
}
double desiredDistanceRemaining = distanceRemaining;
if (slowingDown) {
if (moveDirection == 1 && distanceRemaining < 0.0) desiredDistanceRemaining = 0.0;
else if (moveDirection == -1 && distanceRemaining > 1.0) desiredDistanceRemaining = 0.0;
}
double slowDownVelocity = (double) (int) (maxBraking / 2.0 * ((Math.sqrt(4.0 * Math.abs(desiredDistanceRemaining) 1.0)) - 1.0));
if (moveDirection == -1) slowDownVelocity = -slowDownVelocity;
if (!slowingDown) {
if (moveDirection == 1) {
if (velocity < 0.0) acceleration = maxBraking;
else acceleration = maxAcceleration;
if (velocity acceleration > slowDownVelocity) slowingDown = true;
} else if (moveDirection == -1) {
if (velocity > 0.0) acceleration = -maxBraking;
else acceleration = -maxAcceleration;
if (velocity acceleration < slowDownVelocity) slowingDown = true;
}
}
if (slowingDown) {
if (distanceRemaining != 0.0 && Math.abs(velocity) <= maxBraking && Math.abs(distanceRemaining) <= maxBraking) slowDownVelocity = distanceRemaining;
double perfectAccel = slowDownVelocity - velocity;
if (perfectAccel > maxBraking) perfectAccel = maxBraking;
else if (perfectAccel < -maxBraking) perfectAccel = -maxBraking;
acceleration = perfectAccel;
}
if (velocity > maxVelocity || velocity < -maxVelocity) acceleration = 0.0;
velocity = acceleration;
if (velocity > maxVelocity) velocity -= Math.min(maxBraking, velocity - maxVelocity);
if (velocity < -maxVelocity) velocity = Math.min(maxBraking, -velocity - maxVelocity);
double dx = velocity * Math.sin(heading); double dy = velocity * Math.cos(heading);
x = dx; y = dy;
//boolean updateBounds = false;
//if (dx != 0.0 || dy != 0.0) updateBounds = true;
if (slowingDown && velocity == 0.0) { distanceRemaining = 0.0; moveDirection = 0; slowingDown = false; acceleration = 0.0; }
//if (updateBounds) updateBoundingBox();
distanceRemaining -= velocity;
if (x<18 || y<18 || x>battleFieldW-18 || y>battleFieldH-18) {
distanceRemaining = 0;
angleToTurn = 0;
velocity = 0;
moveDirection = 0;
x = Math.max(18,Math.min(battleFieldW-18,x));
y = Math.max(18,Math.min(battleFieldH-18,y));
}
}
//add position
pos[i] = new MovSimStat(x,y,velocity,heading,Utils.normalRelativeAngle(heading-lastHeading));
}
return pos;
}
}
package apv;
public class MovSimStat {
public double x;
public double y;
public double v;
public double h;
public double w;
public MovSimStat(double x, double y, double v, double h, double w) {
this.x = x; this.y = y; this.v = v; this.h = h; this.w = w;
}
}