[Home]Hanji/AGravEngine

Robo Home | Hanji | Changes | Preferences | AllPages

Showing revision 8
This class encapsulates the AntiGravityMovement Algorithm. Hopefully the comments will make things clear enough, but feel free to ask questions. I also have a subclass, /AGravEngineGL, which draws GravPoints? to the screen using RobocodeGLV014
 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.
Questions or comments:

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

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


Robo Home | Hanji | Changes | Preferences | AllPages
Edit revision 8 of this page | View other revisions | View current revision
Edited May 13, 2005 2:54 EST by Xlittlep (diff)
Search: