Search code examples
javarobocode

Is it possible to call a robot method outside of "main" robot class?


I'm trying to make a robot in the robocode environment. My question is, if I want (for example) to call the method "fire()" outside of my robot class (so the class that extends Robot and has the run, onHitBybullet, ... methods), how do I do it?

This is just one of the things I tried (my latest):

package sample;

import robocode.HitByBulletEvent;
import robocode.Robot;
import robocode.ScannedRobotEvent;
import sample.Interpretater;

public class MyFirstRobot extends Robot {

Interpretater inter;

public void run() {
    intel = new Interpretator();
    while (true) {
        ahead(50); // Move ahead 100
        //turnGunRight(360); // Spin gun around
        back(50); // Move back 100
        //turnGunRight(360); // Spin gun around
    }
}

public void onScannedRobot(ScannedRobotEvent e) {
    /*If I write fire() here, it will work, but I want to call it 
    from some other class (intel)*/
    inter.onScan();
}

public void onHitByBullet(HitByBulletEvent e) {
    turnLeft(90 - e.getBearing());
}
}   

Interpreter code :

package sample;

public class Interpretator extends MyFirstRobot
{
public Interpretator(){

}

public void onScan(){
    fire(1); //won't work, throws "you cannot call fire() before run()"
}
}

I'm not an expert in java at all, so maybe I'm missing something, but I tried creating another class and making it extend my robot class (therefore inheriting the Robot methods) but then java threw errors since a class that extends Robot needs the run, onHitByBullet .. methods.


Solution

  • This seems like a design problem.

    Your solution works, but when you add more methods than onScan, you will need to pass this to every call you make from MyFirstRobot

    Instead, pass a reference to this in Interpretater's constructor.

    Your error happens because Interpretator extends MyFirstRobot. When you call fire(1) without the robot reference, it calls it on Interpretator, which hasn't run run() yet. It looks like you're only using Interpretator as a reference to make decisions based on the robot, so Interpretator is not a Robot.

    Making these changes (along with formatting) gets:

    package sample;
    
    import robocode.HitByBulletEvent;
    import robocode.Robot;
    import robocode.ScannedRobotEvent;
    import sample.Interpretater;
    
    public class MyFirstRobot extends Robot {
    
        Interpretater inter;
    
        public void run() {
            inter = new Interpretator(this); // intel looked like a typo
            while (true) {
                ahead(50); // Move ahead 100
                // turnGunRight(360); // Spin gun around
                back(50); // Move back 100
                // turnGunRight(360); // Spin gun around
            }
        }
    
        public void onScannedRobot(ScannedRobotEvent e) {
            /*
             * If I write fire() here, it will work, but I want to call it from some
             * other class (intel)
             */
            inter.onScan();
        }
    
        public void onHitByBullet(HitByBulletEvent e) {
            turnLeft(90 - e.getBearing());
        }
    }
    

    and

    public class Interpretator {
    
        MyFirstRobot robot;
    
        public Interpretator(MyFirstRobot robot_arg) {
            // constructor sets instance variable
            robot = robot_arg;
        }
    
        public void onScan() {
            robot.fire(1); // use reference
        }
    }