How to write my robot?

MASTER THE JAVASCRIPT ROBOT API AND RULE THE WORLD

Introduction

Coding your robots is very easy and should be natural if you've ever had any Javascript experience. Let's see an example of a very simple robot:

function Robot(robot) {}

// well, we need to do something...
// whenever our robot is idle, this method gets called.
Robot.prototype.onIdle = function(ev) {
    var robot;
    robot = ev.robot;
    robot.ahead(150);
    robot.rotateCannon(360);
    robot.back(100);
    robot.rotateCannon(360);
    robot.turn(20);
};

// this method gets called whenever we hit another robot...
Robot.prototype.onRobotCollision = function(ev) {};

// this method gets called whenever we hit a wall...
Robot.prototype.onWallCollision = function(ev) {};

// yay we see another robot! time to wreak some havoc...
Robot.prototype.onScannedRobot = function(ev) {
    var robot;
    robot = ev.robot;
    robot.fire(1);
};

// ohhh... we were hit by another robot...
Robot.prototype.onHitByBullet = function(ev) {
    var robot;
    robot = ev.robot;
    robot.turn(90 - ev.bulletBearing);
};
            

There's a bunch of methods in there that you probably don't quite understand yet, but we'll see more about them in a minute.

Robot Structure

Your robot is just a plain old Javascript constructor function. fightcode will use your constructor function to create the instance that will fight against other robots.

This is the simplest possible robot you can build (it doesn't do much, though):

function Robot() {} Robot.prototype.onIdle = function(ev) { };

OnIdle Function

The onIdle function is your robot game loop. fightcode will call it every time your robot runs out of actions to do.

You can use it to run, turn, shoot or anything your robot can do. We can implement it with:

function Robot() {}

Robot.prototype.onIdle = function(ev) {
    var robot = ev.robot;
    robot.turn(90); // keep turning 90 degrees when idle
};
            

onIdle is a function that takes one argument called ev. The structure of ev is this:

{
    robot: {
        // INFORMATION ON THE CURRENT GAME
        id,                    // Id from your robot
        angle,                 // Current angle from your robot in degrees
        cannonRelativeAngle,   // Current angle from your cannon
                               // relative to your robot
        cannonAbsoluteAngle,   // Current angle from your cannon
                               // relative to the board
        position: {
            x,                 // X position in the board from your robot
            y                  // Y position in the board from your robot
        },
        life,                  // Percentage of the life from your robot
        gunCoolDownTime,       // Time remaining in the cooldown from your
                               // cannon after shooting
        availableClones,       // Number of available clones you can use
        availableDisappears,   // Number of available disappears you can use
        parentId,              // In the case of being a clone, the id
                               // from your parent element. null otherwise
        arenaWidth,            // Width from the board
        arenaHeight            // Height from the board

        // AVAILABLE ACTIONS

        // Moves the given amount ahead
        ahead: function(amount),

        // Moves the given amount backwards
        back: function(amount),

        // Moves ahead if direction equals to 1, backwards otherwise
        move: functon(amount, direction),

        // Rotates your cannon angle by the specified number of degrees
        rotateCannon: function(amount),

        // Turns the cannon gun left relative to the robot by the specified
        // number of degrees (equivalent to rotateCannon(-1 * amount))
        turnGunLeft: function(degrees),

        // Turns the cannon gun right relative to the robot by the specified
        // number of degrees (equivalent to rotateCannon(amount))
        turnGunRight: function(degrees),

        // Rotates your robot the by the specified number of degrees
        turn: function(degrees),

        // Rotates your robot to the left by the specified number of
        // degrees (equivalent to turn(-1 * degrees))
        turnLeft: function(degrees),

        // Rotates your robot to the right by the specified number of
        // degrees (equivalent to turn(degrees))
        turnRight: function(degrees),

        // Fires your cannon. This functin has a cooldown before you can
        // use it again.
        fire: function(),

        // Subscribe to get notified whenever this action gets called
        // in the queue.
        notify: function(callback),

        // Removes all remaining actions your robot has from the queue
        stop: function(),

        // Clones your robot into another robot and can only be used once
        // per fight. Remember to check the parentId property to stop
        // your clone from shooting you.
        clone: function(),

        // Disappear your robot for 200 rounds, doing your robot undetected
        // by enemy robots (onScannedRobot the event is not triggered) and
        // can only be used once per fight.
        disappear: function(),

        // Logs message to the console.
        log: function(message),

        // Stops your robot from listening a given event (onWallColision,
        // for instance).
        ignore: function(eventName),

        // Starts listening a given event (onWallColision, for instance).
        listen: function(eventName)
    }
}
            

The information available in this object is the base for all other events. In the other event's we'll only document their additional properties.

Your constructor function receives just the "robot" key present in the above object. This means that in your constructor you don't need to assign ev.robot to a variable.

onRobotCollision

This event will be called whenever your robot hits another robot.

We can implement it as so:

function Robot() {}

Robot.prototype.onIdle = function(ev) {
    // do something
};

Robot.prototype.onRobotCollision = function(ev) {
    var robot = ev.robot;
    robot.turn(20);
    robot.ahead(100); // trying to run away
};
            

The object that this function takes as argument is pretty similar to the onIdle function with the following added properties:

{
    robot: {
        // Same as onIdle
    },
    bearing,            // Degrees that the other robot relative to my robot
                        // this property can vary from -180 to 180 degrees
    collidedRobot: {    // Information on the robot that collided with mine
        id,             // Id from the robot
        position: {
            x,          // X position from the other robot relative to the board
            y           // Y position from the other robot relative to the board
        },
        angle,          // Angle from the other robot
        cannonAngle,    // Cannon angle relative to the other robot
        life,           // Percentage of life from the other robot
        parentId        // If this is a clone, the clone's parent id.
                        // null otherwise
    },
    myFault             // Boolean value that indicates whether I hit the other
                        // robot or the opposite
}
            

onWallCollision

This event will be called whenever your robot hits a wall.

We can implement it as so:

function Robot() {}

Robot.prototype.onIdle = function(ev) {
    // do something
};

Robot.prototype.onWallCollision = function(ev) {
    var robot = ev.robot;
    robot.turn(ev.bearing); // turn enought to be in a straight
                            // angle with the wall.
};
            

The object that this function takes as argument is pretty similar to the onIdle function with the following added properties:

{
    robot: {
        // Same as onIdle
    },
    bearing            // Degrees of the wall relative to my robot
                       // this property can vary from -180 to 180 degrees
}
            

onScannedRobot

This event will be called whenever you see another robot. It's a very important event since it's usually when you want to fire.

This can happen due to a number of things:

We can implement it as so:

function Robot() {}

Robot.prototype.onIdle = function(ev) {
    // do something
};

Robot.prototype.onScannedRobot = function(ev) {
    var robot = ev.robot;
    robot.fire(); // YAY!
};
            

The object that this function takes as argument is pretty similar to the onIdle function with the following added properties:

{
    robot: {
        // Same as onIdle
    },
    scannedRobot: {
        id,             // Id from the robot
        position: {
            x,          // X position from the other robot relative to the board
            y,          // Y position from the other robot relative to the board
        },
        angle,          // Angle from the other robot
        cannonAngle,    // Cannon angle relative to the other robot
        life,           // Percentage of life from the other robot
        parentId        // If this is a clone, the clone's parent id.
                        // null otherwise
    }
}
            

onHitByBullet

This event will be called whenever a bullet hits your robot.

We can implement it as so:

function Robot() {}

Robot.prototype.onIdle = function(ev) {
    // do something
};

Robot.prototype.onHitByBullet = function(ev) {
    var robot = ev.robot;
    robot.turn(ev.bearing); // Turn to wherever the bullet was fired
                            // so we can see who shot it
};
            

The object that this function takes as argument is pretty similar to the onIdle function with the following added properties:

{
    robot: {
        // Same as onIdle
    },
    bearing     // angle that the bullet came from relative
                // to my tank's angle
}