/*******************************************************************************
* Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/epl-v10.html
*
* Contributors:
* Joshua Galecki
* - Initial implementation
* Flemming N. Larsen
* - Small adjustments + extended javadocs
*******************************************************************************/
package robocode;
import static java.lang.Math.toRadians;
import static java.lang.Math.toDegrees;
/**
* This advanced robot type allows you to set a rate for each of the robot's movements.
* <p/>
* You can set the rate for:<ul>
* <li>velocity - pixels per turn</li>
* <li>robot turn - radians per turn</li>
* <li>gun rotation - radians per turn</li>
* <li>radar rotation - radians per turn</li>
* </ul>
* When you set a rate for one of the above movements, the movement will continue the move by
* specified rate for ever, until the rate is changed. In order to move ahead or right, the
* rate must be set to a positive value. If a negative value is used instead, the movement
* will go back or to the left. In order to stop the movement, the rate must be
* set to 0.
* <p/>
* Note: When calling {@code setVelocityRate()}, {@code setTurnRate()}, {@code setGunRotationRate()},
* {@code setRadarRotationRate()} and variants, Any previous calls to "movement" functions outside of
* {@code RateControlRobot}, such as {@code setAhead()}, {@code setTurnLeft()},
* {@code setTurnRadarRightRadians()} and similar will be overridden when calling the
* {@link #execute() execute()} on this robot class.
* <p/>
* Look into the source code for the {@code sample.VelociRobot} in order to see how to use this
* robot type.
*
* @author Joshua Galecki
* @since 1.7.1.3
*/
public class RateControlRobot extends TeamRobot {
private double velocityRate; // Pixels per turn
private double turnRate; // Radians per turn
private double gunRotationRate; // Radians per turn
private double radarRotationRate; // Radians per turn
/**
* Sets the speed the robot will move (forward), in pixels per turn.
* <p/>
* This call returns immediately, and will not execute until you call
* execute() or take an action that executes.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot will move backwards
* <p/>
* Example:
* <pre>
* // Set the robot to move forward 2 pixels per turn
* setVelocityRate(2);
*
* // Set the robot to move backwards 8 pixels per turn
* // (overrides the previous order)
* setVelocityRate(-8);
*
* ...
* // Executes the last setVelocityRate()
* execute();
* </pre>
*
* Note: This method overrules {@link robocode.AdvancedRobot#setAhead(double)} and
* {@link robocode.AdvancedRobot#setBack(double)}.
*
* @param velocityRate pixels per turn the robot will move.
*
* @see #getVelocityRate()
* @see #setTurnRate(double)
* @see #setGunRotationRate(double)
* @see #setRadarRotationRate(double)
* @see AdvancedRobot#setAhead(double)
* @see AdvancedRobot#setBack(double)
*/
public void setVelocityRate(double velocityRate) {
this.velocityRate = velocityRate;
}
/**
* Returns the speed the robot will move, in pixels per turn.
* Positive values means that the robot will move forward.
* Negative values means that the robot will move backwards.
* If the value is 0, the robot will stand still.
*
* @return The speed of the robot in pixels per turn
*
* @see #setVelocityRate(double)
*/
public double getVelocityRate() {
return velocityRate;
}
/**
* Sets the robot's clockwise (right) rotation per turn, in degrees.
* <p/>
* This call returns immediately, and will not execute until you call
* execute() or take an action that executes.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot turns counterclockwise (left)
* <p/>
* Example:
* <pre>
* // Set the robot to turn right 10 degrees per turn
* setTurnRate(10);
*
* // Set the robot to turn left 4 degrees per turn
* // (overrides the previous order)
* setTurnRate(-5);
*
* ...
* // Executes the last setTurnRate()
* execute();
* </pre>
*
* @param turnRate angle of the clockwise rotation, in degrees.
*
* @see #getTurnRate()
* @see #setVelocityRate(double)
* @see #setGunRotationRate(double)
* @see #setRadarRotationRate(double)
* @see AdvancedRobot#setTurnRight(double)
* @see AdvancedRobot#setTurnLeft(double)
*/
public void setTurnRate(double turnRate) {
this.turnRate = toRadians(turnRate);
}
/**
* Gets the robot's clockwise rotation per turn, in degrees.
* Positive values means that the robot will turn to the right.
* Negative values means that the robot will turn to the left.
* If the value is 0, the robot will not turn.
*
* @return Angle of the clockwise rotation, in degrees.
*
* @see #setTurnRate(double)
*/
public double getTurnRate() {
return toDegrees(turnRate);
}
/**
* Sets the robot's clockwise (right) rotation per turn, in radians.
* <p/>
* This call returns immediately, and will not execute until you call
* execute() or take an action that executes.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot turns counterclockwise (left)
* <p/>
* Example:
* <pre>
* // Set the robot to turn right pi / 32 radians per turn
* setTurnRateRadians(Math.PI / 32);
*
* // Set the robot to turn left pi / 20 radians per turn
* // (overrides the previous order)
* setTurnRateRadians(-Math.PI / 20);
*
* ...
* // Executes the last setTurnRateRadians()
* execute();
* </pre>
*
* @param turnRate angle of the clockwise rotation, in radians.
*
* @see #getTurnRateRadians()()
* @see #setVelocityRate(double)
* @see #setGunRotationRateRadians(double)
* @see #setRadarRotationRateRadians(double)
* @see AdvancedRobot#setTurnRightRadians(double)
* @see AdvancedRobot#setTurnLeftRadians(double)
*/
public void setTurnRateRadians(double turnRate) {
this.turnRate = turnRate;
}
/**
* Gets the robot's clockwise rotation per turn, in radians.
* Positive values means that the robot will turn to the right.
* Negative values means that the robot will turn to the left.
* If the value is 0, the robot will not turn.
*
* @return Angle of the clockwise rotation, in radians.
*
* @see #getTurnRateRadians()
*/
public double getTurnRateRadians() {
return turnRate;
}
/**
* Sets the gun's clockwise (right) rotation per turn, in degrees.
* <p/>
* This call returns immediately, and will not execute until you call
* execute() or take an action that executes.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the gun turns counterclockwise (left)
* <p/>
* Example:
* <pre>
* // Set the gun to turn right 15 degrees per turn
* setGunRotationRate(15);
*
* // Set the gun to turn left 9 degrees per turn
* // (overrides the previous order)
* setGunRotationRate(-9);
*
* ...
* // Executes the last setGunRotationRate()
* execute();
* </pre>
*
* @param gunRotationRate angle of the clockwise rotation, in degrees.
*
* @see #getGunRotationRate()
* @see #setVelocityRate(double)
* @see #setTurnRate(double)
* @see #setRadarRotationRate(double)
* @see AdvancedRobot#setTurnGunRight(double)
* @see AdvancedRobot#setTurnGunLeft(double)
*/
public void setGunRotationRate(double gunRotationRate) {
this.gunRotationRate = toRadians(gunRotationRate);
}
/**
* Gets the gun's clockwise rotation per turn, in degrees.
* Positive values means that the gun will turn to the right.
* Negative values means that the gun will turn to the left.
* If the value is 0, the gun will not turn.
*
* @return Angle of the clockwise rotation, in degrees.
*
* @see #setGunRotationRate(double)
*/
public double getGunRotationRate() {
return toDegrees(gunRotationRate);
}
/**
* Sets the gun's clockwise (right) rotation per turn, in radians.
* <p/>
* This call returns immediately, and will not execute until you call
* execute() or take an action that executes.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the gun turns counterclockwise (left)
* <p/>
* Example:
* <pre>
* // Set the gun to turn right pi / 16 radians per turn
* setGunRotationRateRadians(Math.PI / 16);
*
* // Set the gun to turn left pi / 12 radians per turn
* // (overrides the previous order)
* setGunRotationRateRadians(-Math.PI / 12);
*
* ...
* // Executes the last setGunRotationRateRadians()
* execute();
* </pre>
*
* @param gunRotationRate angle of the clockwise rotation, in radians.
*
* @see #getGunRotationRateRadians()
* @see #setVelocityRate(double)
* @see #setTurnRateRadians(double)
* @see #setRadarRotationRateRadians(double)
* @see AdvancedRobot#setTurnGunRightRadians(double)
* @see AdvancedRobot#setTurnGunLeftRadians(double)
*/
public void setGunRotationRateRadians(double gunRotationRate) {
this.gunRotationRate = gunRotationRate;
}
/**
* Gets the gun's clockwise rotation per turn, in radians.
* Positive values means that the gun will turn to the right.
* Negative values means that the gun will turn to the left.
* If the value is 0, the gun will not turn.
*
* @return Angle of the clockwise rotation, in radians.
*
* @see #setGunRotationRateRadians(double)
*/
public double getGunRotationRateRadians() {
return gunRotationRate;
}
/**
* Sets the radar's clockwise (right) rotation per turn, in degrees.
* <p/>
* This call returns immediately, and will not execute until you call
* execute() or take an action that executes.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the radar turns counterclockwise (left)
* <p/>
* Example:
* <pre>
* // Set the radar to turn right 45 degrees per turn
* setRadarRotationRate(45);
*
* // Set the radar to turn left 15 degrees per turn
* // (overrides the previous order)
* setRadarRotationRate(-15);
*
* ...
* // Executes the last setRadarRotationRate()
* execute();
* </pre>
*
* @param radarRotationRate angle of the clockwise rotation, in degrees.
*
* @see #getRadarRotationRate()
* @see #setVelocityRate(double)
* @see #setTurnRate(double)
* @see #setGunRotationRate(double)
* @see AdvancedRobot#setTurnRadarRight(double)
* @see AdvancedRobot#setTurnRadarLeft(double)
*/
public void setRadarRotationRate(double radarRotationRate) {
this.radarRotationRate = toRadians(radarRotationRate);
}
/**
* Gets the radar's clockwise rotation per turn, in degrees.
* Positive values means that the radar will turn to the right.
* Negative values means that the radar will turn to the left.
* If the value is 0, the radar will not turn.
*
* @return Angle of the clockwise rotation, in degrees.
*
* @see #setRadarRotationRate(double)
*/
public double getRadarRotationRate() {
return toDegrees(radarRotationRate);
}
/**
* Sets the radar's clockwise (right) rotation per turn, in radians.
* <p/>
* This call returns immediately, and will not execute until you call
* execute() or take an action that executes.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the radar turns counterclockwise (left)
* <p/>
* Example:
* <pre>
* // Set the radar to turn right pi / 4 radians per turn
* setRadarRotationRateRadians(Math.PI / 4);
*
* // Set the radar to turn left pi / 8 radians per turn
* // (overrides the previous order)
* setRadarRotationRateRadians(-Math.PI / 8);
*
* ...
* // Executes the last setRadarRotationRateRadians()
* execute();
* </pre>
*
* @param radarRotationRate angle of the clockwise rotation, in radians.
*
* @see #getRadarRotationRateRadians()
* @see #setVelocityRate(double)
* @see #setTurnRateRadians(double)
* @see #setGunRotationRateRadians(double)
* @see AdvancedRobot#setTurnRadarRightRadians(double)
* @see AdvancedRobot#setTurnRadarLeftRadians(double)
*/
public void setRadarRotationRateRadians(double radarRotationRate) {
this.radarRotationRate = radarRotationRate;
}
/**
* Gets the radar's clockwise rotation per turn, in radians.
* Positive values means that the radar will turn to the right.
* Negative values means that the radar will turn to the left.
* If the value is 0, the radar will not turn.
*
* @return Angle of the clockwise rotation, in radians.
*
* @see #setRadarRotationRateRadians(double)
*/
public double getRadarRotationRateRadians() {
return radarRotationRate;
}
/**
* Executes any pending actions, or continues executing actions that are
* in process. This call returns after the actions have been started.
* <p/>
* Note that advanced robots <em>must</em> call this function in order to
* execute pending set* calls like e.g. {@code setVelocityRate()}, {@code setFire()},
* {@code setTurnRate()} etc. Otherwise, these calls will never get executed.
* <p/>
* Any previous calls to "movement" functions outside of {@code RateControlRobot},
* such as {@code setAhead()}, {@code setTurnLeft()}, {@code setTurnRadarLeftRadians()}
* etc. will be overridden when this method is called on this robot class.
* <p/>
* In this example the robot will move while turning:
* <pre>
* setVelocityRate(6);
* setTurnRate(7);
*
* while (true) {
* execute();
* }
* </pre>
*/
@Override
public void execute() {
setMaxVelocity(velocityRate);
if (velocityRate > 0) {
setAhead(Double.POSITIVE_INFINITY);
} else if (velocityRate < 0) {
setBack(Double.POSITIVE_INFINITY);
} else {
setAhead(0);
}
setTurnGunRightRadians(gunRotationRate);
setTurnRadarRightRadians(radarRotationRate);
setTurnRightRadians(turnRate);
super.execute();
}
}