Robo Home | ModdedBot | Changes | Preferences | AllPages

This is the source code to version 1.1 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
 * version 1.1
 * Last edited on December 5, 2003

package mod;
import robocode.*;
import java.util.*;
import robocode.exception.EventInterruptedException;

/* 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 pr ivate 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() {
        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
     * onXXX(XXXEvent) methods.
    private void events() {
        if (events != null) events.clear();
        events = super.getAllEvents();
        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
                Event newevent = new RobotDeathEvent(hit.getName());
                //DON'T FORGET to set the priority and time of the event!
                //add RobotDeathEvent to eventsfake (NOT events)
                //remove the BulletHitEvent

                //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.
    /* These variables handle prioritization. */
    private boolean isHandlingEvents = false;
    private int currentEventPriority = Integer.MIN_VALUE;
    private boolean[] interruptible = new boolean[101];
    /* This method handles setting interruptibility. Since we hold all blocking
     * calls from the robot, we have to handle interruptibility manually.
    public void setInterruptible(boolean interruptible) {
        if (!isHandlingEvents) return;
        this.interruptible[currentEventPriority] = interruptible;
    /* This event parses the events and calls the proper event handlers.
     * This method is configured to automatically handle interruptibility the
     * same way Robocode does. An error is thrown through the robot's event
     * handler and caught by ModdedBot to interrupt an event.
    private void dump() {
        //set this to true. we shouldn't have to worry about setting it false
        // again because from then on we always handle events.
        isHandlingEvents = true;
        if (events == null) return;
        while (events.size() > 0) {
            Event event = (Event)events.firstElement();
            //since the list is sorted, all events remaining are lower priority
            // than the current one, so we cannot interrupt it and so we can
            // stop dumping events.
            if (event.getPriority() < currentEventPriority)
            //we need to interrupt the current event
            if (event.getPriority() == currentEventPriority && interruptible[currentEventPriority]) {
                interruptible[currentEventPriority] = false;
                throw new EventInterruptedException(event.getPriority());

            //we haven't interrupted the current event; since the list is
            // sorted, all events after this one will have the same or lower
            // priority, so we can stop dumping events.
            if (event.getPriority() == currentEventPriority)
            //we can now remove the event from the vector. we remove it after
            // interrupting so that we don't remove the event that we
            // want to interrupt with!
            int oldEventPriority = currentEventPriority;
            currentEventPriority = event.getPriority();

            try {

                //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 (event instanceof ScannedRobotEvent)
                else if (event instanceof RobotDeathEvent)

                else if (event instanceof HitRobotEvent)
                else if (event instanceof HitWallEvent)
                else if (event instanceof HitByBulletEvent)

                else if (event instanceof BulletHitEvent)
                else if (event instanceof BulletMissedEvent)
                else if (event instanceof BulletHitBulletEvent)

                else if (event instanceof CustomEvent)
                else if (event instanceof SkippedTurnEvent)
                else if (event instanceof WinEvent)
                else if (event instanceof DeathEvent)
                    printError("Unknown Event!! This event is unhandled: "  + event.getClass().getName());

            } catch (EventInterruptedException e) {
                //we dropped down the stack, and we resume event dumping with
                // the new events vector using the old dump method.
            currentEventPriority = oldEventPriority;
        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() {
        //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
    /* 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() {
    public void doNothing() {execute();}
    public void scan() {
    public void fire(double power) {
    public Bullet fireBullet(double power) {
        Bullet bullet = super.fireBullet(power);
        return bullet;
    public void ahead(double distance) {
        while (getDistanceRemaining() > 0) {
    public void back(double distance) {ahead(-distance);}
    public void turnRightRadians(double angle) {
        while (getTurnRemaining() != 0) {
    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) {
        while (getGunTurnRemaining() != 0) {
    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) {
        while (getRadarTurnRemaining() != 0) {
    public void turnRadarLeftRadians(double angle) {turnRadarRightRadians(-angle);}
    public void turnRadarRight(double angle) {turnRadarRightRadians(Math.toRadians(angle));}
    public void turnRadarLeft(double angle) {turnRadarRight(-angle);}

Robo Home | ModdedBot | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited December 6, 2003 3:09 EST by Vuen (diff)