/*******************************************************************************
* 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:
* Mathew A. Nelson
* - Initial API and implementation
* Flemming N. Larsen
* - Added setColors(Color, Color, Color, Color, Color), setAllColors(),
* setBodyColor(), setGunColor(), setRadarColor(), setBulletColor(), and
* setScanColor()
* - Updated Javadocs
* - The finalize() is now protected instead of public
* - Added onKeyPressed(), onKeyReleased(), onKeyTyped() events
* - Added onMouseMoved(), onMouseClicked(), onMouseReleased(),
* onMouseEntered(), onMouseExited(), onMouseDragged(), onMouseWheelMoved()
* events
* - The uninitializedException() method does not need a method name as input
* parameter anymore
* - The PrintStream 'out' has been moved to the new _RobotBase class
* Matthew Reeder
* - Fix for HyperThreading hang issue
* Stefan Westen (RobocodeGL) & Flemming N. Larsen
* - Added onPaint() method for painting the robot
* Pavel Savara
* - Re-work of robot interfaces
* - Added getGraphics()
*******************************************************************************/
package robocode;
import robocode.robotinterfaces.*;
import robocode.robotinterfaces.peer.IStandardRobotPeer;
import java.awt.*;
/**
* The basic robot class that you will extend to create your own robots.
* <p/>
* <p>Please note the following standards will be used:
* <br> heading - absolute angle in degrees with 0 facing up the screen,
* positive clockwise. 0 <= heading < 360.
* <br> bearing - relative angle to some object from your robot's heading,
* positive clockwise. -180 < bearing <= 180
* <br> All coordinates are expressed as (x,y).
* <br> All coordinates are positive.
* <br> The origin (0,0) is at the bottom left of the screen.
* <br> Positive x is right.
* <br> Positive y is up.
*
* @author Mathew A. Nelson (original)
* @author Flemming N. Larsen (contributor)
* @author Matthew Reeder (contributor)
* @author Stefan Westen (contributor)
* @author Pavel Savara (contributor)
* @see <a target="_top" href="http://robocode.sourceforge.net">
* robocode.sourceforge.net</a>
* @see <a href="http://robocode.sourceforge.net/myfirstrobot/MyFirstRobot.html">
* Building your first robot<a>
* @see JuniorRobot
* @see AdvancedRobot
* @see TeamRobot
* @see Droid
*/
public class Robot extends _Robot implements IInteractiveRobot, IPaintRobot, IBasicEvents3, IInteractiveEvents, IPaintEvents {
private static final int
WIDTH = 40,
HEIGHT = 40;
/**
* Constructs a new robot.
*/
public Robot() {}
/**
* {@inheritDoc}}
*/
public final Runnable getRobotRunnable() {
return this;
}
/**
* {@inheritDoc}}
*/
public final IBasicEvents getBasicEventListener() {
return this;
}
/**
* {@inheritDoc}}
*/
public final IInteractiveEvents getInteractiveEventListener() {
return this;
}
/**
* {@inheritDoc}}
*/
public final IPaintEvents getPaintEventListener() {
return this;
}
/**
* Immediately moves your robot ahead (forward) by distance measured in
* pixels.
* <p/>
* This call executes immediately, and does not return until it is complete,
* i.e. when the remaining distance to move is 0.
* <p/>
* If the robot collides with a wall, the move is complete, meaning that the
* robot will not move any further. If the robot collides with another
* robot, the move is complete if you are heading toward the other robot.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot is set to move backward
* instead of forward.
* <p/>
* Example:
* <pre>
* // Move the robot 100 pixels forward
* ahead(100);
*
* // Afterwards, move the robot 50 pixels backward
* ahead(-50);
* </pre>
*
* @param distance the distance to move ahead measured in pixels.
* If this value is negative, the robot will move back instead of ahead.
* @see #back(double)
* @see #onHitWall(HitWallEvent)
* @see #onHitRobot(HitRobotEvent)
*/
public void ahead(double distance) {
if (peer != null) {
peer.move(distance);
} else {
uninitializedException();
}
}
/**
* Immediately moves your robot backward by distance measured in pixels.
* <p/>
* This call executes immediately, and does not return until it is complete,
* i.e. when the remaining distance to move is 0.
* <p/>
* If the robot collides with a wall, the move is complete, meaning that the
* robot will not move any further. If the robot collides with another
* robot, the move is complete if you are heading toward the other robot.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot is set to move forward instead
* of backward.
* <p/>
* Example:
* <pre>
* // Move the robot 100 pixels backward
* back(100);
*
* // Afterwards, move the robot 50 pixels forward
* back(-50);
* </pre>
*
* @param distance the distance to move back measured in pixels.
* If this value is negative, the robot will move ahead instead of back.
* @see #ahead(double)
* @see #onHitWall(HitWallEvent)
* @see #onHitRobot(HitRobotEvent)
*/
public void back(double distance) {
if (peer != null) {
peer.move(-distance);
} else {
uninitializedException();
}
}
/**
* Returns the width of the current battlefield measured in pixels.
*
* @return the width of the current battlefield measured in pixels.
*/
public double getBattleFieldWidth() {
if (peer != null) {
return peer.getBattleFieldWidth();
}
uninitializedException();
return 0; // never called
}
/**
* Returns the height of the current battlefield measured in pixels.
*
* @return the height of the current battlefield measured in pixels.
*/
public double getBattleFieldHeight() {
if (peer != null) {
return peer.getBattleFieldHeight();
}
uninitializedException();
return 0; // never called
}
/**
* Returns the direction that the robot's body is facing, in degrees.
* The value returned will be between 0 and 360 (is excluded).
* <p/>
* Note that the heading in Robocode is like a compass, where 0 means North,
* 90 means East, 180 means South, and 270 means West.
*
* @return the direction that the robot's body is facing, in degrees.
* @see #getGunHeading()
* @see #getRadarHeading()
*/
public double getHeading() {
if (peer != null) {
double rv = 180.0 * peer.getBodyHeading() / Math.PI;
while (rv < 0) {
rv += 360;
}
while (rv >= 360) {
rv -= 360;
}
return rv;
}
uninitializedException();
return 0; // never called
}
/**
* Returns the height of the robot measured in pixels.
*
* @return the height of the robot measured in pixels.
* @see #getWidth()
*/
public double getHeight() {
if (peer == null) {
uninitializedException();
}
return HEIGHT;
}
/**
* Returns the width of the robot measured in pixels.
*
* @return the width of the robot measured in pixels.
* @see #getHeight()
*/
public double getWidth() {
if (peer == null) {
uninitializedException();
}
return WIDTH;
}
/**
* Returns the robot's name.
*
* @return the robot's name.
*/
public String getName() {
if (peer != null) {
return peer.getName();
}
uninitializedException();
return null; // never called
}
/**
* Returns the X position of the robot. (0,0) is at the bottom left of the
* battlefield.
*
* @return the X position of the robot.
* @see #getY()
*/
public double getX() {
if (peer != null) {
return peer.getX();
}
uninitializedException();
return 0; // never called
}
/**
* Returns the Y position of the robot. (0,0) is at the bottom left of the
* battlefield.
*
* @return the Y position of the robot.
* @see #getX()
*/
public double getY() {
if (peer != null) {
return peer.getY();
}
uninitializedException();
return 0; // never called
}
/**
* The main method in every robot. You must override this to set up your
* robot's basic behavior.
* <p/>
* Example:
* <pre>
* // A basic robot that moves around in a square
* public void run() {
* while (true) {
* ahead(100);
* turnRight(90);
* }
* }
* </pre>
*/
public void run() {}
/**
* Immediately turns the robot's body to the left by degrees.
* <p/>
* This call executes immediately, and does not return until it is complete,
* i.e. when the angle remaining in the robot's turn is 0.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot's body is set to turn right
* instead of left.
* <p/>
* Example:
* <pre>
* // Turn the robot 180 degrees to the left
* turnLeft(180);
*
* // Afterwards, turn the robot 90 degrees to the right
* turnLeft(-90);
* </pre>
*
* @param degrees the amount of degrees to turn the robot's body to the left.
* If {@code degrees} > 0 the robot will turn left.
* If {@code degrees} < 0 the robot will turn right.
* If {@code degrees} = 0 the robot will not turn, but execute.
* @see #turnRight(double)
* @see #turnGunLeft(double)
* @see #turnGunRight(double)
* @see #turnRadarLeft(double)
* @see #turnRadarRight(double)
*/
public void turnLeft(double degrees) {
if (peer != null) {
peer.turnBody(-Math.toRadians(degrees));
} else {
uninitializedException();
}
}
/**
* Immediately turns the robot's body to the right by degrees.
* This call executes immediately, and does not return until it is complete,
* i.e. when the angle remaining in the robot's turn is 0.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot's body is set to turn left
* instead of right.
* <p/>
* Example:
* <pre>
* // Turn the robot 180 degrees to the right
* turnRight(180);
*
* // Afterwards, turn the robot 90 degrees to the left
* turnRight(-90);
* </pre>
*
* @param degrees the amount of degrees to turn the robot's body to the right.
* If {@code degrees} > 0 the robot will turn right.
* If {@code degrees} < 0 the robot will turn left.
* If {@code degrees} = 0 the robot will not turn, but execute.
* @see #turnLeft(double)
* @see #turnGunLeft(double)
* @see #turnGunRight(double)
* @see #turnRadarLeft(double)
* @see #turnRadarRight(double)
*/
public void turnRight(double degrees) {
if (peer != null) {
peer.turnBody(Math.toRadians(degrees));
} else {
uninitializedException();
}
}
/**
* Do nothing this turn, meaning that the robot will skip it's turn.
* <p/>
* This call executes immediately, and does not return until the turn is
* over.
*/
public void doNothing() {
if (peer != null) {
peer.execute();
} else {
uninitializedException();
}
}
/**
* Immediately fires a bullet. The bullet will travel in the direction the
* gun is pointing.
* <p/>
* The specified bullet power is an amount of energy that will be taken from
* the robot's energy. Hence, the more power you want to spend on the
* bullet, the more energy is taken from your robot.
* <p/>
* The bullet will do (4 * power) damage if it hits another robot. If power
* is greater than 1, it will do an additional 2 * (power - 1) damage.
* You will get (3 * power) back if you hit the other robot. You can call
* {@link Rules#getBulletDamage(double)} for getting the damage that a
* bullet with a specific bullet power will do.
* <p/>
* The specified bullet power should be between
* {@link Rules#MIN_BULLET_POWER} and {@link Rules#MAX_BULLET_POWER}.
* <p/>
* Note that the gun cannot fire if the gun is overheated, meaning that
* {@link #getGunHeat()} returns a value > 0.
* <p/>
* A event is generated when the bullet hits a robot
* ({@link BulletHitEvent}), wall ({@link BulletMissedEvent}), or another
* bullet ({@link BulletHitBulletEvent}).
* <p/>
* Example:
* <pre>
* // Fire a bullet with maximum power if the gun is ready
* if (getGunHeat() == 0) {
* fire(Rules.MAX_BULLET_POWER);
* }
* </pre>
*
* @param power the amount of energy given to the bullet, and subtracted
* from the robot's energy.
* @see #fireBullet(double)
* @see #getGunHeat()
* @see #getGunCoolingRate()
* @see #onBulletHit(BulletHitEvent)
* @see #onBulletHitBullet(BulletHitBulletEvent)
* @see #onBulletMissed(BulletMissedEvent)
*/
public void fire(double power) {
if (peer != null) {
peer.setFire(power);
peer.execute();
} else {
uninitializedException();
}
}
/**
* Immediately fires a bullet. The bullet will travel in the direction the
* gun is pointing.
* <p/>
* The specified bullet power is an amount of energy that will be taken from
* the robot's energy. Hence, the more power you want to spend on the
* bullet, the more energy is taken from your robot.
* <p/>
* The bullet will do (4 * power) damage if it hits another robot. If power
* is greater than 1, it will do an additional 2 * (power - 1) damage.
* You will get (3 * power) back if you hit the other robot. You can call
* {@link Rules#getBulletDamage(double)} for getting the damage that a
* bullet with a specific bullet power will do.
* <p/>
* The specified bullet power should be between
* {@link Rules#MIN_BULLET_POWER} and {@link Rules#MAX_BULLET_POWER}.
* <p/>
* Note that the gun cannot fire if the gun is overheated, meaning that
* {@link #getGunHeat()} returns a value > 0.
* <p/>
* A event is generated when the bullet hits a robot
* ({@link BulletHitEvent}), wall ({@link BulletMissedEvent}), or another
* bullet ({@link BulletHitBulletEvent}).
* <p/>
* Example:
* <pre>
* // Fire a bullet with maximum power if the gun is ready
* if (getGunHeat() == 0) {
* Bullet bullet = fireBullet(Rules.MAX_BULLET_POWER);
*
* // Get the velocity of the bullet
* if (bullet != null) {
* double bulletVelocity = bullet.getVelocity();
* }
* }
* </pre>
*
* @param power the amount of energy given to the bullet, and subtracted
* from the robot's energy.
* @return a {@link Bullet} that contains information about the bullet if it
* was actually fired, which can be used for tracking the bullet after it
* has been fired. If the bullet was not fired, {@code null} is returned.
* @see #fire(double)
* @see Bullet
* @see #getGunHeat()
* @see #getGunCoolingRate()
* @see #onBulletHit(BulletHitEvent)
* @see #onBulletHitBullet(BulletHitBulletEvent)
* @see #onBulletMissed(BulletMissedEvent)
*/
public Bullet fireBullet(double power) {
if (peer != null) {
return peer.fire(power);
}
uninitializedException();
return null;
}
/**
* Returns the rate at which the gun will cool down, i.e. the amount of heat
* the gun heat will drop per turn.
* <p/>
* The gun cooling rate is default 0.1 / turn, but can be changed by the
* battle setup. So don't count on the cooling rate being 0.1!
*
* @return the gun cooling rate
* @see #getGunHeat()
* @see #fire(double)
* @see #fireBullet(double)
*/
public double getGunCoolingRate() {
if (peer != null) {
return peer.getGunCoolingRate();
}
uninitializedException();
return 0; // never called
}
/**
* Returns the direction that the robot's gun is facing, in degrees.
* The value returned will be between 0 and 360 (is excluded).
* <p/>
* Note that the heading in Robocode is like a compass, where 0 means North,
* 90 means East, 180 means South, and 270 means West.
*
* @return the direction that the robot's gun is facing, in degrees.
* @see #getHeading()
* @see #getRadarHeading()
*/
public double getGunHeading() {
if (peer != null) {
return peer.getGunHeading() * 180.0 / Math.PI;
}
uninitializedException();
return 0; // never called
}
/**
* Returns the current heat of the gun. The gun cannot fire unless this is
* 0. (Calls to fire will succeed, but will not actually fire unless
* getGunHeat() == 0).
* <p/>
* The amount of gun heat generated when the gun is fired is
* 1 + (firePower / 5). Each turn the gun heat drops by the amount returned
* by {@link #getGunCoolingRate()}, which is a battle setup.
* <p/>
* Note that all guns are "hot" at the start of each round, where the gun
* heat is 3.
*
* @return the current gun heat
* @see #getGunCoolingRate()
* @see #fire(double)
* @see #fireBullet(double)
*/
public double getGunHeat() {
if (peer != null) {
return peer.getGunHeat();
}
uninitializedException();
return 0; // never called
}
/**
* Returns the number of rounds in the current battle.
*
* @return the number of rounds in the current battle
* @see #getRoundNum()
*/
public int getNumRounds() {
if (peer != null) {
return peer.getNumRounds();
}
uninitializedException();
return 0; // never called
}
/**
* Returns how many opponents that are left in the current round.
*
* @return how many opponents that are left in the current round.
*/
public int getOthers() {
if (peer != null) {
return peer.getOthers();
}
uninitializedException();
return 0; // never called
}
/**
* Returns the direction that the robot's radar is facing, in degrees.
* The value returned will be between 0 and 360 (is excluded).
* <p/>
* Note that the heading in Robocode is like a compass, where 0 means North,
* 90 means East, 180 means South, and 270 means West.
*
* @return the direction that the robot's radar is facing, in degrees.
* @see #getHeading()
* @see #getGunHeading()
*/
public double getRadarHeading() {
if (peer != null) {
return peer.getRadarHeading() * 180.0 / Math.PI;
}
uninitializedException();
return 0; // never called
}
/**
* Returns the current round number (0 to {@link #getNumRounds()} - 1) of
* the battle.
*
* @return the current round number of the battle (zero indexed).
* @see #getNumRounds()
*/
public int getRoundNum() {
if (peer != null) {
return peer.getRoundNum();
}
uninitializedException();
return 0; // never called
}
/**
* Returns the game time of the current round, where the time is equal to
* the current turn in the round.
* <p/>
* A battle consists of multiple rounds.
* <p/>
* Time is reset to 0 at the beginning of every round.
*
* @return the game time/turn of the current round.
*/
public long getTime() {
if (peer != null) {
return peer.getTime();
}
uninitializedException();
return 0; // never called
}
/**
* Returns the velocity of the robot measured in pixels/turn.
* <p/>
* The maximum velocity of a robot is defined by {@link Rules#MAX_VELOCITY}
* (8 pixels / turn).
*
* @return the velocity of the robot measured in pixels/turn.
* @see Rules#MAX_VELOCITY
*/
public double getVelocity() {
if (peer != null) {
return peer.getVelocity();
}
uninitializedException();
return 0; // never called
}
/**
* {@inheritDoc}
*/
public void onBulletHit(BulletHitEvent event) {}
/**
* {@inheritDoc}
*/
public void onBulletHitBullet(BulletHitBulletEvent event) {}
/**
* {@inheritDoc}
*/
public void onBulletMissed(BulletMissedEvent event) {}
/**
* {@inheritDoc}
*/
public void onDeath(DeathEvent event) {}
/**
* {@inheritDoc}
*/
public void onHitByBullet(HitByBulletEvent event) {}
/**
* {@inheritDoc}
*/
public void onHitRobot(HitRobotEvent event) {}
/**
* {@inheritDoc}
*/
public void onHitWall(HitWallEvent event) {}
/**
* {@inheritDoc}
*/
public void onRobotDeath(RobotDeathEvent event) {}
/**
* {@inheritDoc}
*/
public void onScannedRobot(ScannedRobotEvent event) {}
/**
* {@inheritDoc}
*/
public void onWin(WinEvent event) {}
/**
* {@inheritDoc}
*/
public void onRoundEnded(RoundEndedEvent event) {}
/**
* {@inheritDoc}
*/
public void onBattleEnded(BattleEndedEvent event) {}
/**
* Scans for other robots. This method is called automatically by the game,
* as long as the robot is moving, turning its body, turning its gun, or
* turning its radar.
* <p/>
* Scan will cause {@link #onScannedRobot(ScannedRobotEvent)
* onScannedRobot(ScannedRobotEvent)} to be called if you see a robot.
* <p/>
* There are 2 reasons to call {@code scan()} manually:
* <ol>
* <li>You want to scan after you stop moving.
* <li>You want to interrupt the {@code onScannedRobot} event. This is more
* likely. If you are in {@code onScannedRobot} and call {@code scan()},
* and you still see a robot, then the system will interrupt your
* {@code onScannedRobot} event immediately and start it from the top.
* </ol>
* <p/>
* This call executes immediately.
*
* @see #onScannedRobot(ScannedRobotEvent)
* @see ScannedRobotEvent
*/
public void scan() {
if (peer != null) {
((IStandardRobotPeer) peer).rescan();
} else {
uninitializedException();
}
}
/**
* Sets the gun to turn independent from the robot's turn.
* <p/>
* Ok, so this needs some explanation: The gun is mounted on the robot's
* body. So, normally, if the robot turns 90 degrees to the right, then the
* gun will turn with it as it is mounted on top of the robot's body. To
* compensate for this, you can call {@code setAdjustGunForRobotTurn(true)}.
* When this is set, the gun will turn independent from the robot's turn,
* i.e. the gun will compensate for the robot's body turn.
* <p/>
* Note: This method is additive until you reach the maximum the gun can
* turn. The "adjust" is added to the amount you set for turning the robot,
* then capped by the physics of the game. If you turn infinite, then the
* adjust is ignored (and hence overridden).
* <p/>
* Example, assuming both the robot and gun start out facing up (0 degrees):
* <pre>
* // Set gun to turn with the robot's turn
* setAdjustGunForRobotTurn(false); // This is the default
* turnRight(90);
* // At this point, both the robot and gun are facing right (90 degrees)
* turnLeft(90);
* // Both are back to 0 degrees
*
* -- or --
*
* // Set gun to turn independent from the robot's turn
* setAdjustGunForRobotTurn(true);
* turnRight(90);
* // At this point, the robot is facing right (90 degrees), but the gun is still facing up.
* turnLeft(90);
* // Both are back to 0 degrees.
* </pre>
* <p/>
* Note: The gun compensating this way does count as "turning the gun".
* See {@link #setAdjustRadarForGunTurn(boolean)} for details.
*
* @param independent {@code true} if the gun must turn independent from the
* robot's turn; {@code false} if the gun must turn with the robot's turn.
* @see #setAdjustRadarForGunTurn(boolean)
*/
public void setAdjustGunForRobotTurn(boolean independent) {
if (peer != null) {
((IStandardRobotPeer) peer).setAdjustGunForBodyTurn(independent);
} else {
uninitializedException();
}
}
/**
* Sets the radar to turn independent from the robot's turn.
* <p/>
* Ok, so this needs some explanation: The radar is mounted on the gun, and
* the gun is mounted on the robot's body. So, normally, if the robot turns
* 90 degrees to the right, the gun turns, as does the radar. Hence, if the
* robot turns 90 degrees to the right, then the gun and radar will turn
* with it as the radar is mounted on top of the gun. To compensate for
* this, you can call {@code setAdjustRadarForRobotTurn(true)}. When this is
* set, the radar will turn independent from the robot's turn, i.e. the
* radar will compensate for the robot's turn.
* <p/>
* Note: This method is additive until you reach the maximum the radar can
* turn. The "adjust" is added to the amount you set for turning the robot,
* then capped by the physics of the game. If you turn infinite, then the
* adjust is ignored (and hence overridden).
* <p/>
* Example, assuming the robot, gun, and radar all start out facing up (0
* degrees):
* <pre>
* // Set radar to turn with the robots's turn
* setAdjustRadarForRobotTurn(false); // This is the default
* turnRight(90);
* // At this point, the body, gun, and radar are all facing right (90 degrees);
*
* -- or --
*
* // Set radar to turn independent from the robot's turn
* setAdjustRadarForRobotTurn(true);
* turnRight(90);
* // At this point, the robot and gun are facing right (90 degrees), but the radar is still facing up.
* </pre>
*
* @param independent {@code true} if the radar must turn independent from
* the robots's turn; {@code false} if the radar must turn with the robot's
* turn.
* @see #setAdjustGunForRobotTurn(boolean)
* @see #setAdjustRadarForGunTurn(boolean)
*/
public void setAdjustRadarForRobotTurn(boolean independent) {
if (peer != null) {
((IStandardRobotPeer) peer).setAdjustRadarForBodyTurn(independent);
} else {
uninitializedException();
}
}
/**
* Sets the radar to turn independent from the gun's turn.
* <p/>
* Ok, so this needs some explanation: The radar is mounted on the robot's
* gun. So, normally, if the gun turns 90 degrees to the right, then the
* radar will turn with it as it is mounted on top of the gun. To compensate
* for this, you can call {@code setAdjustRadarForGunTurn(true)}. When this
* is set, the radar will turn independent from the robot's turn, i.e. the
* radar will compensate for the gun's turn.
* <p/>
* Note: This method is additive until you reach the maximum the radar can
* turn. The "adjust" is added to the amount you set for turning the gun,
* then capped by the physics of the game. If you turn infinite, then the
* adjust is ignored (and hence overridden).
* <p/>
* Example, assuming both the gun and radar start out facing up (0 degrees):
* <pre>
* // Set radar to turn with the gun's turn
* setAdjustRadarForGunTurn(false); // This is the default
* turnGunRight(90);
* // At this point, both the radar and gun are facing right (90 degrees);
*
* -- or --
*
* // Set radar to turn independent from the gun's turn
* setAdjustRadarForGunTurn(true);
* turnGunRight(90);
* // At this point, the gun is facing right (90 degrees), but the radar is still facing up.
* </pre>
* Note: Calling {@code setAdjustRadarForGunTurn(boolean)} will
* automatically call {@link #setAdjustRadarForRobotTurn(boolean)} with the
* same value, unless you have already called it earlier. This behavior is
* primarily for backward compatibility with older Robocode robots.
*
* @param independent {@code true} if the radar must turn independent from
* the gun's turn; {@code false} if the radar must turn with the gun's
* turn.
* @see #setAdjustRadarForRobotTurn(boolean)
* @see #setAdjustGunForRobotTurn(boolean)
*/
public void setAdjustRadarForGunTurn(boolean independent) {
if (peer != null) {
((IStandardRobotPeer) peer).setAdjustRadarForGunTurn(independent);
} else {
uninitializedException();
}
}
/**
* Sets the color of the robot's body, gun, and radar in the same time.
* <p/>
* You may only call this method one time per battle. A {@code null}
* indicates the default (blue) color.
* <p/>
* Example:
* <pre>
* // Don't forget to import java.awt.Color at the top...
* import java.awt.Color;
* ...
*
* public void run() {
* setColors(null, Color.RED, new Color(150, 0, 150));
* ...
* }
* </pre>
*
* @param bodyColor the new body color
* @param gunColor the new gun color
* @param radarColor the new radar color
* @see #setColors(Color, Color, Color, Color, Color)
* @see #setAllColors(Color)
* @see #setBodyColor(Color)
* @see #setGunColor(Color)
* @see #setRadarColor(Color)
* @see #setBulletColor(Color)
* @see #setScanColor(Color)
* @see Color
*/
public void setColors(Color bodyColor, Color gunColor, Color radarColor) {
if (peer != null) {
peer.setBodyColor(bodyColor);
peer.setGunColor(gunColor);
peer.setRadarColor(radarColor);
} else {
uninitializedException();
}
}
/**
* Sets the color of the robot's body, gun, radar, bullet, and scan arc in
* the same time.
* <p/>
* You may only call this method one time per battle. A {@code null}
* indicates the default (blue) color for the body, gun, radar, and scan
* arc, but white for the bullet color.
* <p/>
* Example:
* <pre>
* // Don't forget to import java.awt.Color at the top...
* import java.awt.Color;
* ...
*
* public void run() {
* setColors(null, Color.RED, Color.GREEN, null, new Color(150, 0, 150));
* ...
* }
* </pre>
*
* @param bodyColor the new body color
* @param gunColor the new gun color
* @param radarColor the new radar color
* @param bulletColor the new bullet color
* @param scanArcColor the new scan arc color
* @see #setColors(Color, Color, Color)
* @see #setAllColors(Color)
* @see #setBodyColor(Color)
* @see #setGunColor(Color)
* @see #setRadarColor(Color)
* @see #setBulletColor(Color)
* @see #setScanColor(Color)
* @see Color
* @since 1.1.3
*/
public void setColors(Color bodyColor, Color gunColor, Color radarColor, Color bulletColor, Color scanArcColor) {
if (peer != null) {
peer.setBodyColor(bodyColor);
peer.setGunColor(gunColor);
peer.setRadarColor(radarColor);
peer.setBulletColor(bulletColor);
peer.setScanColor(scanArcColor);
} else {
uninitializedException();
}
}
/**
* Sets all the robot's color to the same color in the same time, i.e. the
* color of the body, gun, radar, bullet, and scan arc.
* <p/>
* You may only call this method one time per battle. A {@code null}
* indicates the default (blue) color for the body, gun, radar, and scan
* arc, but white for the bullet color.
* <p/>
* <pre>
* Example:
* // Don't forget to import java.awt.Color at the top...
* import java.awt.Color;
* ...
*
* public void run() {
* setAllColors(Color.RED);
* ...
* }
* </pre>
*
* @param color the new color for all the colors of the robot
* @see #setColors(Color, Color, Color)
* @see #setColors(Color, Color, Color, Color, Color)
* @see #setBodyColor(Color)
* @see #setGunColor(Color)
* @see #setRadarColor(Color)
* @see #setBulletColor(Color)
* @see #setScanColor(Color)
* @see Color
* @since 1.1.3
*/
public void setAllColors(Color color) {
if (peer != null) {
peer.setBodyColor(color);
peer.setGunColor(color);
peer.setRadarColor(color);
peer.setBulletColor(color);
peer.setScanColor(color);
} else {
uninitializedException();
}
}
/**
* Sets the color of the robot's body.
* <p/>
* A {@code null} indicates the default (blue) color.
* <p/>
* <pre>
* Example:
* // Don't forget to import java.awt.Color at the top...
* import java.awt.Color;
* ...
*
* public void run() {
* setBodyColor(Color.BLACK);
* ...
* }
* </pre>
*
* @param color the new body color
* @see #setColors(Color, Color, Color)
* @see #setColors(Color, Color, Color, Color, Color)
* @see #setAllColors(Color)
* @see #setGunColor(Color)
* @see #setRadarColor(Color)
* @see #setBulletColor(Color)
* @see #setScanColor(Color)
* @see Color
* @since 1.1.2
*/
public void setBodyColor(Color color) {
if (peer != null) {
peer.setBodyColor(color);
} else {
uninitializedException();
}
}
/**
* Sets the color of the robot's gun.
* <p/>
* A {@code null} indicates the default (blue) color.
* <p/>
* <pre>
* Example:
* // Don't forget to import java.awt.Color at the top...
* import java.awt.Color;
* ...
*
* public void run() {
* setGunColor(Color.RED);
* ...
* }
* </pre>
*
* @param color the new gun color
* @see #setColors(Color, Color, Color)
* @see #setColors(Color, Color, Color, Color, Color)
* @see #setAllColors(Color)
* @see #setBodyColor(Color)
* @see #setRadarColor(Color)
* @see #setBulletColor(Color)
* @see #setScanColor(Color)
* @see Color
* @since 1.1.2
*/
public void setGunColor(Color color) {
if (peer != null) {
peer.setGunColor(color);
} else {
uninitializedException();
}
}
/**
* Sets the color of the robot's radar.
* <p/>
* A {@code null} indicates the default (blue) color.
* <p/>
* <pre>
* Example:
* // Don't forget to import java.awt.Color at the top...
* import java.awt.Color;
* ...
*
* public void run() {
* setRadarColor(Color.YELLOW);
* ...
* }
* </pre>
*
* @param color the new radar color
* @see #setColors(Color, Color, Color)
* @see #setColors(Color, Color, Color, Color, Color)
* @see #setAllColors(Color)
* @see #setBodyColor(Color)
* @see #setGunColor(Color)
* @see #setBulletColor(Color)
* @see #setScanColor(Color)
* @see Color
* @since 1.1.2
*/
public void setRadarColor(Color color) {
if (peer != null) {
peer.setRadarColor(color);
} else {
uninitializedException();
}
}
/**
* Sets the color of the robot's bullets.
* <p/>
* A {@code null} indicates the default white color.
* <p/>
* <pre>
* Example:
* // Don't forget to import java.awt.Color at the top...
* import java.awt.Color;
* ...
*
* public void run() {
* setBulletColor(Color.GREEN);
* ...
* }
* </pre>
*
* @param color the new bullet color
* @see #setColors(Color, Color, Color)
* @see #setColors(Color, Color, Color, Color, Color)
* @see #setAllColors(Color)
* @see #setBodyColor(Color)
* @see #setGunColor(Color)
* @see #setRadarColor(Color)
* @see #setScanColor(Color)
* @see Color
* @since 1.1.2
*/
public void setBulletColor(Color color) {
if (peer != null) {
peer.setBulletColor(color);
} else {
uninitializedException();
}
}
/**
* Sets the color of the robot's scan arc.
* <p/>
* A {@code null} indicates the default (blue) color.
* <p/>
* <pre>
* Example:
* // Don't forget to import java.awt.Color at the top...
* import java.awt.Color;
* ...
*
* public void run() {
* setScanColor(Color.WHITE);
* ...
* }
* </pre>
*
* @param color the new scan arc color
* @see #setColors(Color, Color, Color)
* @see #setColors(Color, Color, Color, Color, Color)
* @see #setAllColors(Color)
* @see #setBodyColor(Color)
* @see #setGunColor(Color)
* @see #setRadarColor(Color)
* @see #setBulletColor(Color)
* @see Color
* @since 1.1.2
*/
public void setScanColor(Color color) {
if (peer != null) {
peer.setScanColor(color);
} else {
uninitializedException();
}
}
/**
* Immediately stops all movement, and saves it for a call to
* {@link #resume()}. If there is already movement saved from a previous
* stop, this will have no effect.
* <p/>
* This method is equivalent to {@code #stop(false)}.
*
* @see #resume()
* @see #stop(boolean)
*/
public void stop() {
stop(false);
}
/**
* Immediately stops all movement, and saves it for a call to
* {@link #resume()}. If there is already movement saved from a previous
* stop, you can overwrite it by calling {@code stop(true)}.
*
* @param overwrite If there is already movement saved from a previous stop,
* you can overwrite it by calling {@code stop(true)}.
* @see #resume()
* @see #stop()
*/
public void stop(boolean overwrite) {
if (peer != null) {
((IStandardRobotPeer) peer).stop(overwrite);
} else {
uninitializedException();
}
}
/**
* Immediately resumes the movement you stopped by {@link #stop()}, if any.
* <p/>
* This call executes immediately, and does not return until it is complete.
*
* @see #stop()
* @see #stop(boolean)
*/
public void resume() {
if (peer != null) {
((IStandardRobotPeer) peer).resume();
} else {
uninitializedException();
}
}
/**
* Immediately turns the robot's gun to the left by degrees.
* <p/>
* This call executes immediately, and does not return until it is complete,
* i.e. when the angle remaining in the gun's turn is 0.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot's gun is set to turn right
* instead of left.
* <p/>
* Example:
* <pre>
* // Turn the robot's gun 180 degrees to the left
* turnGunLeft(180);
*
* // Afterwards, turn the robot's gun 90 degrees to the right
* turnGunLeft(-90);
* </pre>
*
* @param degrees the amount of degrees to turn the robot's gun to the left.
* If {@code degrees} > 0 the robot's gun will turn left.
* If {@code degrees} < 0 the robot's gun will turn right.
* If {@code degrees} = 0 the robot's gun will not turn, but execute.
* @see #turnGunRight(double)
* @see #turnLeft(double)
* @see #turnRight(double)
* @see #turnRadarLeft(double)
* @see #turnRadarRight(double)
* @see #setAdjustGunForRobotTurn(boolean)
*/
public void turnGunLeft(double degrees) {
if (peer != null) {
peer.turnGun(-Math.toRadians(degrees));
} else {
uninitializedException();
}
}
/**
* Immediately turns the robot's gun to the right by degrees.
* This call executes immediately, and does not return until it is complete,
* i.e. when the angle remaining in the gun's turn is 0.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot's gun is set to turn left
* instead of right.
* <p/>
* Example:
* <pre>
* // Turn the robot's gun 180 degrees to the right
* turnGunRight(180);
*
* // Afterwards, turn the robot's gun 90 degrees to the left
* turnGunRight(-90);
* </pre>
*
* @param degrees the amount of degrees to turn the robot's gun to the right.
* If {@code degrees} > 0 the robot's gun will turn right.
* If {@code degrees} < 0 the robot's gun will turn left.
* If {@code degrees} = 0 the robot's gun will not turn, but execute.
* @see #turnGunLeft(double)
* @see #turnLeft(double)
* @see #turnRight(double)
* @see #turnRadarLeft(double)
* @see #turnRadarRight(double)
* @see #setAdjustGunForRobotTurn(boolean)
*/
public void turnGunRight(double degrees) {
if (peer != null) {
peer.turnGun(Math.toRadians(degrees));
} else {
uninitializedException();
}
}
/**
* Immediately turns the robot's radar to the left by degrees.
* <p/>
* This call executes immediately, and does not return until it is complete,
* i.e. when the angle remaining in the radar's turn is 0.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot's radar is set to turn right
* instead of left.
* <p/>
* Example:
* <pre>
* // Turn the robot's radar 180 degrees to the left
* turnRadarLeft(180);
*
* // Afterwards, turn the robot's radar 90 degrees to the right
* turnRadarLeft(-90);
* </pre>
*
* @param degrees the amount of degrees to turn the robot's radar to the left.
* If {@code degrees} > 0 the robot's radar will turn left.
* If {@code degrees} < 0 the robot's radar will turn right.
* If {@code degrees} = 0 the robot's radar will not turn, but execute.
* @see #turnRadarRight(double)
* @see #turnLeft(double)
* @see #turnRight(double)
* @see #turnGunLeft(double)
* @see #turnGunRight(double)
* @see #setAdjustRadarForRobotTurn(boolean)
* @see #setAdjustRadarForGunTurn(boolean)
*/
public void turnRadarLeft(double degrees) {
if (peer != null) {
((IStandardRobotPeer) peer).turnRadar(-Math.toRadians(degrees));
} else {
uninitializedException();
}
}
/**
* Immediately turns the robot's radar to the right by degrees.
* This call executes immediately, and does not return until it is complete,
* i.e. when the angle remaining in the radar's turn is 0.
* <p/>
* Note that both positive and negative values can be given as input,
* where negative values means that the robot's radar is set to turn left
* instead of right.
* <p/>
* Example:
* <pre>
* // Turn the robot's radar 180 degrees to the right
* turnRadarRight(180);
*
* // Afterwards, turn the robot's radar 90 degrees to the left
* turnRadarRight(-90);
* </pre>
*
* @param degrees the amount of degrees to turn the robot's radar to the right.
* If {@code degrees} > 0 the robot's radar will turn right.
* If {@code degrees} < 0 the robot's radar will turn left.
* If {@code degrees} = 0 the robot's radar will not turn, but execute.
* @see #turnRadarLeft(double)
* @see #turnLeft(double)
* @see #turnRight(double)
* @see #turnGunLeft(double)
* @see #turnGunRight(double)
* @see #setAdjustRadarForRobotTurn(boolean)
* @see #setAdjustRadarForGunTurn(boolean)
*/
public void turnRadarRight(double degrees) {
if (peer != null) {
((IStandardRobotPeer) peer).turnRadar(Math.toRadians(degrees));
} else {
uninitializedException();
}
}
/**
* Returns the robot's current energy.
*
* @return the robot's current energy.
*/
public double getEnergy() {
if (peer != null) {
return peer.getEnergy();
}
uninitializedException();
return 0; // never called
}
/**
* Returns a graphics context used for painting graphical items for the robot.
* <p/>
* This method is very useful for debugging your robot.
* <p/>
* Note that the robot will only be painted if the "Paint" is enabled on the
* robot's console window; otherwise the robot will never get painted (the
* reason being that all robots might have graphical items that must be
* painted, and then you might not be able to tell what graphical items that
* have been painted for your robot).
* <p/>
* Also note that the coordinate system for the graphical context where you
* paint items fits for the Robocode coordinate system where (0, 0) is at
* the bottom left corner of the battlefield, where X is towards right and Y
* is upwards.
*
* @return a graphics context used for painting graphical items for the robot.
* @see #onPaint(Graphics2D)
* @since 1.6.1
*/
public Graphics2D getGraphics() {
if (peer != null) {
return peer.getGraphics();
}
uninitializedException();
return null; // never called
}
/**
* Sets the debug property with the specified key to the specified value.
* <p/>
* This method is very useful when debugging or reviewing your robot as you
* will be able to see this property displayed in the robot console for your
* robots under the Debug Properties tab page.
*
* @param key the name/key of the debug property.
* @param value the new value of the debug property, where {@code null} or
* the empty string is used for removing this debug property.
* @since 1.6.2
*/
public void setDebugProperty(String key, String value) {
if (peer != null) {
peer.setDebugProperty(key, value);
return;
}
uninitializedException();
}
/**
* {@inheritDoc}
*/
public void onPaint(Graphics2D g) {}
/**
* {@inheritDoc}
*/
public void onKeyPressed(java.awt.event.KeyEvent e) {}
/**
* {@inheritDoc}
*/
public void onKeyReleased(java.awt.event.KeyEvent e) {}
/**
* {@inheritDoc}
*/
public void onKeyTyped(java.awt.event.KeyEvent e) {}
/**
* {@inheritDoc}
*/
public void onMouseClicked(java.awt.event.MouseEvent e) {}
/**
* {@inheritDoc}
*/
public void onMouseEntered(java.awt.event.MouseEvent e) {}
/**
* {@inheritDoc}
*/
public void onMouseExited(java.awt.event.MouseEvent e) {}
/**
* {@inheritDoc}
*/
public void onMousePressed(java.awt.event.MouseEvent e) {}
/**
* {@inheritDoc}
*/
public void onMouseReleased(java.awt.event.MouseEvent e) {}
/**
* {@inheritDoc}
*/
public void onMouseMoved(java.awt.event.MouseEvent e) {}
/**
* {@inheritDoc}
*/
public void onMouseDragged(java.awt.event.MouseEvent e) {}
/**
* {@inheritDoc}
*/
public void onMouseWheelMoved(java.awt.event.MouseWheelEvent e) {}
/**
* {@inheritDoc}
*/
public void onStatus(StatusEvent e) {}
}