|
Noran I'm trying to use this engine in the first bot I'm making. I'm new to robocode, but I'm an expert java programmer. I understand how it works and I'm using a goTo movement function to move to the point I need to go to, but I can't add any gravity points to the AGravEngine? becuase I get a null pointer exception in my onScannedRobot() method everytime. I initialize it at the top of run(), and add a center GravPoint?, and that doesn't mess up at all, but when I even try to call agEngine.reset() at the top of onScannedRobot() I get a null pointer exception. In battle my bot just swings the radar around, but it never moves anywhere, due to the NPE. Any help? -xLittleP |
|
Noran |
package neh;
import java.util.Vector;
import neh.RobocodeUtils;
import neh.GravPoint;
/**
* AGravEngine -> an engine encapsulating the Anti-gravity movement
* algorithm. By NEH (aka Hanji)
**/
public class AGravEngine {
/**The Points that it is concerned with.**/
protected Vector gravPoints = new Vector();
/**
* The force, if any, of the walls. It is assumed that the walls will
* never attract, so this is always positive (meaning repulsion in this
* case).
**/
protected double wallForce = 0.0;
/**The width of the battlefield.**/
protected double width;
/**The height of the battlefield**/
protected double height;
/*The components of the force**/
protected double xForce = 0.0;
protected double yForce = 0.0;
/**
* The exponent used in cacluating a point's effect on a location.
* The effect is proportionate to distance^pointDropoff. This field
* has an initial value of 2.0.
**/
protected double pointDropoff = 2.0;
/**
* The exponent used in cacluating the walls' effect on a location.
* The effect is proportionate to distance^wallDropoff. This field
* has an initial value of 3.0.
**/
protected double wallDropoff = 3.0;
/**Initializes the width and height to 0**/
public AGravEngine() {
this(0,0);
}
/**Initializes the dimensions to the specified values**/
public AGravEngine(double width, double height) {
this.width = width;
this.height = height;
}
/**Adds a point to the list.**/
public void addPoint(GravPoint g) {
gravPoints.add(g);
}
/**Removes a point from the list.**/
public boolean removePoint(GravPoint g) {
return gravPoints.remove(g);
}
/**Returns the number of points currently contained.**/
public long getNumPoints() {
return gravPoints.size();
}
/**Returns the force with which the walls repel.**/
public double getWallForce() {
return wallForce;
}
/**Sets the force with which the walls repel.**/
public void setWallForce(double wf) {
wallForce = wf;
}
/**Returns the value of the point dropoff exponent.**/
public double getPointDropoff() {
return pointDropoff;
}
/**Sets the value of the point dropoff exponent.**/
public void setPointDropoff(double pdf) {
pointDropoff = pdf;
}
/**Returns the value of the wall dropoff exponent.**/
public double getWallDropoff() {
return wallDropoff;
}
/**Sets the value of the wall dropoff exponent.**/
public void setWallDropoff(double wdf) {
wallDropoff = wdf;
}
/**Removes all points from the list.**/
public void reset() {
gravPoints = new Vector();
}
/**
* Calculates the current force and kills any GravPoints
* that have gone past their lifetimes
* @param curX The X coordinate of the point for which
* gravity is being calculated.
* @param curY The Y coordinate of the point for which
* gravity is being calculated.
* @param time The current time.
**/
public void update(double curX, double curY, long time) {
xForce = 0.0;
yForce = 0.0;
Vector deadPoints = new Vector();
GravPoint g;
double force;
double angle;
for(int i=0;i<gravPoints.size();i++) {
g = (GravPoint) gravPoints.elementAt(i);
if(g.update(time)) {
deadPoints.add(g);
continue;
}
force = g.strength/Math.pow(
RobocodeUtils.dist(curX, curY, g.x, g.y),
pointDropoff);
angle = RobocodeUtils.getBearing(curX, curY, g.x, g.y);
xForce += force * Math.sin(angle);
yForce += force * Math.cos(angle);
}
xForce += wallForce/Math.pow(curX, wallDropoff);
xForce -= wallForce/Math.pow(width-curX, wallDropoff);
yForce -= wallForce/Math.pow(height-curY, wallDropoff);
yForce += wallForce/Math.pow(curY, wallDropoff);
for(int i=0;i<deadPoints.size();i++) {
gravPoints.remove(deadPoints.elementAt(i));
}
}
/**
* Returns the force in the X direction (calculated in
* update())
**/
public double getXForce() {
return xForce;
}
/**
* Returns the force in the Y direction (calculated in
* update())
**/
public double getYForce() {
return yForce;
}
}
This class also requires the /GravPoint class, and you will have to either replace the calls to RobocodeUtils.* with your own equivalents, or grab that class as well.
I'm working on a bot with this engine. It took me quite a while to find some good values for the dropoffs and wallforce. I neeeded to change the lines:
xForce += force * Math.sin(angle); yForce += force * Math.cos(angle);
into:
xForce -= force * Math.sin(angle); yForce -= force * Math.cos(angle);
otherwise other bots attracted my bot. It works pretty good if you place some additional points (e.g. center and corners).
Noran