While Robocode is a great educational tool, it is also complex and deep. The phrase "easy to play, difficult to master" comes to mind. This is especially apparent when viewing the source code of the various movement and targeting strategies on the Robocode wiki. As part of our brief introduction, we were asked to implement the simple robots listed on the assignment page. While implementing the robots, I got to know the Robocode API really well. I did implement all of them, but not without some trouble.

Moving the robot to a specified point is not as simple as "moveRobot(a, b)". While I could've written an implementation that doesn't require trigonometry, I chose to brush up on my old math skills. I created two functions; one that determines how much the robot should turn and one to actually turn the robot.

` /**`

* Gets the angle to a point on the battlefield.

* @param x X coordinate of the point to move to.

* @param y Y coordinate of the point to move to.

*

* @return The angle between the point and the Y axis in degrees.

*/

private double getAngleToPoint(double x, double y) {

//Get heading to the center.

double distX = x - this.getX();

double distY = y - this.getY();

double angle = Math.atan(distX / distY) * (180.0/Math.PI);

//Check if the robot needs to move south instead of north.

if(distY < 0) {

angle += 180.0;

}

return angle;

}

/**

* Turns the robot to set its heading to point (x, y).

* @param x X coordinate of the point.

* @param y Y coordinate of the point.

*/

private void turnToPoint(double x, double y) {

double turnAngle = this.getAngleToPoint(x, y) + (360 - this.getHeading());

this.turnRight(turnAngle);

}

The trickiest part was implementing Firing04. To track the robot, we needed to predict where the enemy robot was going next and then turn in that direction. Fortunately, the ScannedRobotEvent class provides a lot of information about where the robot is going. We just needed to calculate the angle at which we should turn to track the robot. Using both the law of cosines and the law of sines from trigonometry, I think I came up with a reasonable solution to tracking the robot.

`//Steps through turning the gun by this interval.`

private static final double TURN_INTERVAL = 20.0;

private ScannedRobotEvent currentEvent;

public void run() {

this.setAdjustRadarForGunTurn(false);

while(true) {

//Scan for a robot.

if(this.currentEvent == null) {

this.turnGunRight(TURN_INTERVAL);

}

//If a robot is found, track it.

else {

double absoluteHeading = this.getHeading() + currentEvent.getBearing();

//Use the law of cosines to approximate the new distance after the enemy moves.

double predictedAngle = 360.0 - currentEvent.getHeading() - (180 - absoluteHeading);

double predictedDist = Math.pow(currentEvent.getDistance(), 2) + Math.pow(currentEvent.getVelocity(), 2) -

(2 * currentEvent.getDistance() * currentEvent.getVelocity() * Math.cos(predictedAngle));

//Use the law of sines to approximate the new absolute heading

double turnAngle = Math.asin((currentEvent.getVelocity() / predictedDist) * Math.sin(predictedAngle));

//With this information, turn the gun to find the enemy

this.turnGunRight(absoluteHeading + turnAngle - this.getGunHeading());

//Reset the current event and find the enemy again.

this.currentEvent = null;

this.scan();

}

}

}

public void onScannedRobot(ScannedRobotEvent event) {

this.currentEvent = event;

}

With Firing04, I think I can make a robot that tries to predict the enemy's location and then fires a bullet there. Robots with complicated movements will probably throw it off, but I think I can make a reasonable guess if I incorporate the enemy's size. Implementing a complex movement pattern seems to be the best way to stay alive as well.

(I did post code and I'm done a little early. Please be nice and attribute me if you use it.)

## No comments:

## Post a Comment