CodeSnippets/Nano Circular Linear Predictor
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);
}
}
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