This is one of the classic Robocode practice questions: Going to the middle of the map. I didn't want to move twice (once for x-axis and once for y-axis), but instead get the bearing towards the middle and move in a single motion after setting my robot's bearing.
To my dismay, it seems to be not working. Instead, the behavior I observed from the robots is that they turn 180 degrees and move ahead for the value of 'r', which is the hypotenuse of the "triangle" towards the middle. The distance seems to be getting smaller each loop, so I think that the formula for 'r' is right. My suspicion is towards the methods setWest() and setEast() I wrote. Their purpose is to set the robot parallel to the horizontal facing either East or West. Then I once again rotate the robot towards the middle by using theta (which is the second iffy part) and move it.
The methods implemented in Robocode are pretty self-explanatory, not mine though. Here is the code I've written:
public class MyFirstRobot extends Robot {
public void setWest(){
// If it's looking NW
if(getHeading() > 270 && getHeading() < 0)
turnLeft(getHeading() - 270);
// If it's looking SE or SW
else if(getHeading() >= 90 && getHeading() <= 270)
turnRight(270 - getHeading());
// If it's looking NE
else if(getHeading() >= 0 && getHeading() < 90)
turnLeft(90 + getHeading());
// If my coding is undercooked spaghetti
else {
System.out.println("Error");
}
}
public void setEast(){
// If it's looking NW
if(getHeading() > 270 && getHeading() < 0)
turnRight(450 - getHeading());
// If it's looking SE or SW
else if(getHeading() >= 90 && getHeading() <= 270)
turnLeft(getHeading() - 90);
// If it's looking NE
else if(getHeading() >= 0 && getHeading() < 90)
turnRight(90 - getHeading());
// If my coding is undercooked spaghetti
else {
System.out.println("Error");
}
}
public void run() {
double x = 0.0;
double y = 0.0;
double r = 0.0;
double theta = 0.0;
while (true) {
x = getBattleFieldWidth() / 2.0 - getX();
y = getBattleFieldHeight() / 2.0 - getY();
r = Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
// Find the angle with respect to the horizontal.
theta = Math.atan((Math.toRadians(y) / Math.toRadians(x)));
/*
* Align tank towards the middle
* depending on the "quadrant" it's in.
*/
// 1st Quadrant
if(x < 0 && y < 0){
setWest();
turnLeft(theta);
}
// 2nd Quadrant
else if(x >= 0 && y < 0){
setEast();
turnRight(theta);
}
// 3rd Quadrant
else if(x >= 0 && y >= 0) {
setEast();
turnLeft(theta);
}
// 4th Quadrant
else if(x < 0 && y >= 0) {
setWest();
turnRight(theta);
}
// Move to the middle after the final rotation.
ahead(r);
}
}
Please don't mind the infinite loop, it's just to observe the behavior. run() is the main method of the robot; it is called by default.
I will answer my own question in case someone wonders what the answer is. There were a few fixes:
getHeading()returns a value between 0 <=getHeading()< 360 in degrees. I mistakenly set one of the if conditions togetHeading() < 0, which isn't possible. I also decided to store the heading in a variable to avoid callinggetHeading()multiple times. Here is the fix for that part:The difference here being 0.0 for the first check being changed to 360.0 0.
Theta was stored in radians instead of degrees.
turnLeft()orturnRight()needs a parameter in degrees for it to work properly. Putting in radians won't give you an error. It also won't work as intended. Theta also had to be stored as a positive number, sincesetWest()andsetEast()already accounts for the direction. It was simply fixed by usingMath.abs()andMath.toDegrees(). As shown below:If you had some lingering questions about it, I hope this helped.