# CodeSnippets/Nano Circular Linear Predictor

Robo Home | CodeSnippets | Changes | Preferences | AllPages

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
{

public void run()
{
do
{
fire(3);
}while(true);
}

public void onScannedRobot(ScannedRobotEvent e)
{
double eX=e.getDistance()*Math.sin(absbearing);
double eY=e.getDistance()*Math.cos(absbearing);

double db=0;
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!

}
}```

Smaller code
• Removed the variable w.
• Put lastEnemyHeading? after the loop.
• Replace the asin/sin with normalRelativeAngle
```		double enemyAbsoluteBearing=e.getBearingRadians()+getHeadingRadians();
double eX=e.getDistance()*Math.sin(enemyAbsoluteBearing);
double eY=e.getDistance()*Math.cos(enemyAbsoluteBearing);

double db=0;

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
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!

```

-- Stelokim

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

```double enemyAbsoluteBearing;
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

Oh wow, this is gonna sound really retarded, but, couldn't you do something like this? Its probably bigger, but I dislike loops.

```package chase.nano;

import static java.lang.Math.*;
import robocode.*;

public class NanoCircle extends AdvancedRobot {
public static double lastX, lastY, lastHeading;

public void run() {
lastX = lastY = 0;
while(true) {
}
}

public void onScannedRobot(ScannedRobotEvent e) {

x = getX() + sin(absAngle) * e.getDistance();
y = getY() + cos(absAngle) * e.getDistance();

if(lastX != 0) {
//the lines, unmutilated
double m1,m2,b1,r, circleX;;
double circleY = (circleX = ((m2=-tan(heading + PI/2))*x+y -
/ (m1 - m2))*m1+b1;
r = sqrt((circleX-x)*(circleX-x)+(circleY-y)*(circleY-y));

//yay, I found the center, now to project along it
//.. I kinda got lost here, but I would think find
//where the bullet can intercept the robot
}

lastX = x;
lastY = y;