This is the source code to version 1.0 of
ModdedBot. It is included within the .jar, which you can obtain here:
http://www.robocoderepository.com/BotDetail.jsp?id=1831
/*
* ModdedBot.java
* by: Vuen
*
* Last edited on November 7, 2003
*/
package mod;
import robocode.*;
import java.util.Vector;
import java.util.Iterator;
/* This is the robot template for creating a Robocode mod. Robots playing your
* mod should extend this rather than AdvancedRobot; you can then add any
* functionality you like.
*/
public class ModdedBot extends AdvancedRobot {
//These are private variables that hold needed info
private boolean isInit;
private Vector events; //Holds all robot events
private Vector eventsfake; //Holds fake events before they are added to events vector
/* This is the initialization method of your robot. It gets called at the
* start of every round. The robot usually can perform a few calculations
* before this is called, but you should not have to worry; if you would
* like this to be guaranteed to be called before the robot does something,
* an example of this is below.
*/
private void init() {
if (isInit) return;
isInit = true;
super.addCustomEvent(new Condition("ModdedBot", 99) {public boolean test() {events(); return false;}});
eventsfake = new Vector();
//Add any code you would like that initializes your mod in here.
}
/* Suppose we would like to guarantee that the robot be initialized before
* the robot uses getHeading():
*/
public double getHeading() {
init();
return super.getHeading();
}
/* You can delete this example method if you like. */
/* This method handles the events in the robot. Whatever you would like the
* mod to do upon receiving an event, do it here. Do NOT override the
* onBla(BlaEvent) methods.
*/
private void events() {
if (events != null) events.clear();
events = super.getAllEvents();
eventsfake.clear();
super.clearAllEvents();
Iterator i = events.iterator();
while (i.hasNext()) {
Event event = (Event)i.next();
//This is where we handle the events we want to handle.
//This contains sample code to remove certain scans, and
// to catch robot deaths. Remove the below sample code when
// you create your mod.
if (event instanceof ScannedRobotEvent) {
//Suppose we would like to disallow a robot from scanning a ScoreBot:
ScannedRobotEvent scan = (ScannedRobotEvent)event;
if (scan.getName().indexOf("ScoreBot") > -1)
i.remove(); //remove the event from the events vector
//it is now impossible for the robot to receive ScoreBot scans.
} else if (event instanceof BulletMissedEvent) {
//Suppose we want to do something when a bullet goes offscreen:
BulletMissedEvent miss = (BulletMissedEvent)event;
//do stuff using this event
//Note that the robot will still receive this event even if we used it.
} else if (event instanceof BulletHitEvent) {
//Suppose we want to generate a RobotDeathEvent instead of a
// BulletHitEvent when the enemy's bullet hits another robot
BulletHitEvent hit = (BulletHitEvent)event;
//create new RobotDeathEvent and add to fakes
eventsfake.add(new RobotDeathEvent(hit.getName()));
//remove the BulletHitEvent
i.remove();
//The robot will now receive a RobotDeathEvemt instead of a
// BulletHitEvent; the robot will not be able to tell the
// difference between the real RobotDeathEvents and the ones
// created by the mod.
}
}
/**Here you can create any fake events you would like. You can also
* make your own event classes, or make event classes that extend
* some of the events that already exist. I suggest you package custom
* event classes in the same package as your ModdedBot. Whatever events
* you create, add them to the eventsfake Vector when you want them to
* be sent to the robot.
*/
events.addAll(eventsfake);
eventsfake.clear();
}
/* This event parses the events and calls the proper event handlers.*/
private void dump() {
if (events == null) return;
for (int i = 0; i < events.size(); i++) {
//If you have created any of your own custom event classes, add them
// here BEFORE the rest of the events get parsed, and change the
// next line to else if so that any events you have extended won't
// fire twice.
//If you haven't created any custom event classes, you don't need
// to modify this method.
if (events.get(i) instanceof ScannedRobotEvent)
onScannedRobot((ScannedRobotEvent)events.get(i));
else if (events.get(i) instanceof RobotDeathEvent)
onRobotDeath((RobotDeathEvent)events.get(i));
else if (events.get(i) instanceof HitRobotEvent)
onHitRobot((HitRobotEvent)events.get(i));
else if (events.get(i) instanceof HitWallEvent)
onHitWall((HitWallEvent)events.get(i));
else if (events.get(i) instanceof HitByBulletEvent)
onHitByBullet((HitByBulletEvent)events.get(i));
else if (events.get(i) instanceof BulletHitEvent)
onBulletHit((BulletHitEvent)events.get(i));
else if (events.get(i) instanceof BulletMissedEvent)
onBulletMissed((BulletMissedEvent)events.get(i));
else if (events.get(i) instanceof BulletHitBulletEvent)
onBulletHitBullet((BulletHitBulletEvent)events.get(i));
else if (events.get(i) instanceof CustomEvent)
onCustomEvent((CustomEvent)events.get(i));
else if (events.get(i) instanceof SkippedTurnEvent)
onSkippedTurn((SkippedTurnEvent)events.get(i));
else if (events.get(i) instanceof WinEvent)
onWin((WinEvent)events.get(i));
else if (events.get(i) instanceof DeathEvent)
onDeath((DeathEvent)events.get(i));
else
printError("Unknown Event!! This event is unhandled: " + events.get(i).getClass().getName());
}
events.clear();
events = null;
}
/* This is your go method. This is always called at the end of every tick,
* after the robot has performed its actions.
*/
private void go() {
init();
//Put anything you would like your mod to do each tick in here.
}
/* The following chunk of methods provides the functionality of all the
* getXXXEvents methods in the robot. Since we parse the events manually,
* we have to rebuild these methods to allow the extending robot to use
* them. If you have any custom event classes, you should add a
* getXXXEvents for your class to provide the robot with this function.
* Note that if you extend any of the existing events, they will NOT be
* returned by the getXXXEvents method of the class they extend; you can
* modify the parseEvents method to provide this functionality if you want.
*
* If you have not created any custom event classes, you do not need to
* modify this code.
*/
public Vector getAllEvents() {return events;}
public void clearAllEvents() {events.clear(); events = null;}
public Vector getScannedRobotEvents() {return parseEvents("robocode.ScannedRobotEvent");}
public Vector getRobotDeathEvents() {return parseEvents("robocode.RobotDeathEvent");}
public Vector getHitRobotEvents() {return parseEvents("robocode.HitRobotEvent");}
public Vector getHitWallEvents() {return parseEvents("robocode.HitWallEvent");}
public Vector getHitByBulletEvents() {return parseEvents("robocode.HitByBulletEvent");}
public Vector getBulletHitEvents() {return parseEvents("robocode.BulletHitEvent");}
public Vector getBulletMissedEvents() {return parseEvents("robocode.BulletMissedEvent");}
public Vector getBulletHitBulletEvents() {return parseEvents("robocode.BulletHitBulletEvent");}
private Vector parseEvents(String type) {
Vector newevents = new Vector();
for (int i = 0; i < events.size(); i++) {if (events.get(i).getClass().getName().equals(type)) newevents.add(events.get(i));}
return newevents;
}
public void addCustomEvent(Condition condition) {
init(); //make sure our condition is first
super.addCustomEvent(condition);
}
/* Here's the fun part: you can now add any mod methods to the robot you
* want! Suppose the robot has a powerup, and we want it to return the time
* remaining on the powerup:
*/
private long powerUpTime;
public long getPowerUpTime() {
return powerUpTime;
}
/* You can see here that you can add to your mod any method you could
* possibly want the extending robot to call. Note that for methods like
* this, you would put in the go() method the code to handle the amount
* of time remaining on the powerup.
*/
//This is just a debugger method; it will call whenever an error occurs
// within the mod. You can call this or remove this or do whatever you want
// with it; debug your mod however you like.
private void printError(String text) {
System.out.println("[" + getTime() + "] Mod Error! " + text);
}
/* The following block of code is what allows the extending robot to use
* any blocking calls they wish, and still allow the mod to get a go()
* every tick. You should not need to modify any of the below code, unless
* you want to prevent the robot from performing any of these actions.
*/
public void execute() {
go();
super.execute();
dump();
}
public void doNothing() {execute();}
public void scan() {
go();
super.scan();
dump();
}
public void fire(double power) {
go();
super.fire(power);
dump();
}
public Bullet fireBullet(double power) {
go();
Bullet bullet = super.fireBullet(power);
dump();
return bullet;
}
public void ahead(double distance) {
setAhead(distance);
while (getDistanceRemaining() > 0) {
scan();
}
}
public void back(double distance) {ahead(-distance);}
public void turnRightRadians(double angle) {
setTurnLeftRadians(angle);
while (getTurnRemaining() != 0) {
scan();
}
}
public void turnLeftRadians(double angle) {turnRightRadians(-angle);}
public void turnRight(double angle) {turnRightRadians(Math.toRadians(angle));}
public void turnLeft(double angle) {turnRight(-angle);}
public void turnGunRightRadians(double angle) {
setTurnGunRightRadians(angle);
while (getGunTurnRemaining() != 0) {
scan();
}
}
public void turnGunLeftRadians(double angle) {turnGunRightRadians(-angle);}
public void turnGunRight(double angle) {turnGunRightRadians(Math.toRadians(angle));}
public void turnGunLeft(double angle) {turnGunRight(-angle);}
public void turnRadarRightRadians(double angle) {
setTurnRadarRightRadians(angle);
while (getRadarTurnRemaining() != 0) {
scan();
}
}
public void turnRadarLeftRadians(double angle) {turnRadarRightRadians(-angle);}
public void turnRadarRight(double angle) {turnRadarRightRadians(Math.toRadians(angle));}
public void turnRadarLeft(double angle) {turnRadarRight(-angle);}
}