[Home]CodeSnippets/Nano Circular Linear Predictor

Robo Home | CodeSnippets | Changes | Preferences | AllPages

Showing revision 10
Hereunder is the source-code from my bot Nano_Circular_Linear_Predictor, a bot I built just to prove that a circular predictor fits into a NanoBot. :-)


public class Nano_Circular_Linear_Predictor extends AdvancedRobot
{
	static double lastEnemyHeading;
	static double radarturn=1;
	
	public void run()
	{
		do
		{
			setAhead(20*Math.sin(getTime()/10));
			setTurnRadarRightRadians(radarturn);	
			fire(3);
		}while(true);
	}
	
	public void onScannedRobot(ScannedRobotEvent e)
	{
		radarturn=-radarturn;
		double w=e.getHeadingRadians()-lastEnemyHeading;
		lastEnemyHeading=e.getHeadingRadians();
		double absbearing=e.getBearingRadians()+getHeadingRadians();
		double eX=e.getDistance()*Math.sin(absbearing);
		double eY=e.getDistance()*Math.cos(absbearing);

		double db=0;
		double ww=lastEnemyHeading;  // enemy's starting heading
		do
		{
			db+=11; //11 is the velocity of a fire(3) bullet.
			double dx=e.getVelocity()*Math.sin(ww);
			double dy=e.getVelocity()*Math.cos(ww);
			ww+=w;  // turn w radians for next step
			eX+=dx;
			eY+=dy;
		}while (db< Point2D.distance(0,0,eX,eY));	// The bullet travelled far enough to hit
								// our target!
		
		setTurnGunRightRadians(Math.asin(Math.sin(Math.atan2(eX, eY) - getGunHeadingRadians())));
		setTurnRightRadians(e.getBearingRadians() + .5*Math.PI);
	}
}


Smaller code
		double enemyAbsoluteBearing=e.getBearingRadians()+getHeadingRadians();
		double eX=e.getDistance()*Math.sin(enemyAbsoluteBearing);
		double eY=e.getDistance()*Math.cos(enemyAbsoluteBearing);
				
		double db=0;
		double ww=lastEnemyHeading;  // enemy's starting heading
							
		do
		{
			db+=11; //11 is the velocity of a fire(3) bullet.
			//db += (20.0 - 3.0 * bulletPower);
			//double dx=e.getVelocity()*Math.sin(ww);
			//double dy=e.getVelocity()*Math.cos(ww);
			//ww+=w;  // turn w radians for next step
			ww += e.getHeadingRadians()-lastEnemyHeading;
			eX+=e.getVelocity()*Math.sin(ww);//dx;
			eY+=e.getVelocity()*Math.cos(ww);//dy;
		} while (db < Point2D.distance(0,0,eX,eY));	// The bullet travelled far enough to hit our target!

		lastEnemyHeading=e.getHeadingRadians();
				
		setTurnGunRightRadians(Utils.normalRelativeAngle(Math.atan2(eX, eY) - getGunHeadingRadians()));

-- Stelokim


To make the code smaller, set variables inside another line:

double enemyAbsoluteBearing;
double eX = e.getDistance() + Math.sin(enemyAbsoluteBearing = e.getBearingRadians() + getHeadingRadians());
double eY = e.getDistance() + Math.sin(enemyAbsoluteBearing);
-- Kinsen

Don't you mean

double eX = getX() + Math.sin...
double eY = getY() + Math.cos...
-- Starrynte

No, in this example, eX and eY represent the enemy Position relative to yours --Dummy

btw, I'm not sure that putting "lastenemyHeading = e.getHeadingRadians()" after the loop is a good idea, because before the loop, "ww=lastenemyHeading" will get an incorrect value. (though I haven't tested this, I haven't played with RoboCode for years now :-p) -- Dummy

I don't think it would make much of a difference, though. The first tick of the round it would be wrong, but no one can fire the first tick anyway, so it should be irrelevant. I think so, at least. I'm in no way an expert on this, all I know about Java is what I've figured out and what people have told me here at the wiki. --Bayen

Well, the thing is that ww needs to start at the enemies current heading. If you put "lastenemyHeading = ..." after the assignment to ww, you'll be using the enemy heading of the previous scan, and the circular prediction will be a slightly less accurate. This will be even more of a problem if you're not scanning your target every tick, which may be the case during melee. --Dummy


Robo Home | CodeSnippets | Changes | Preferences | AllPages
Edit revision 10 of this page | View other revisions | View current revision
Edited August 20, 2007 22:34 EST by Skilgannon (diff)
Search: