Some days ago I read
this article about evolving
Robocode robots using
Genetic Algorithms (GA). I just loved the idea because I really enjoy Robocode and I had already made some simple things with GA, but I never did anything with such tangible results.
I started to follow the links, but I couldn’t find any downloadable content, a YouTube video or anything else to show me how far the guy that wrote it was able to go with it. Based on that, I decided to implement something on this area.
The idea of this text is to present to you the main problems that I faced until I get the first results.
My first thought was to generate random Java code and do the genetic operations such as
crossover and
mutation on the code it self. It’s quite simple to see how bad this idea is when you imagine how many possibilities and how many invalid results it would have.
So, my first step was to create a piece of code that generates a Java class that extends
AdvancedRobot using a String as seed, so each robot is represented by the String that generated him. This way I can generate a random robot just by creating a random String.
If are you wondering: “How can he generate a Java code from a String?” here is a piece of the code that generates the Java code:
for (byte code : genome.getBytes()) {
int command = code % 20;
switch (command) {
case 0:
if (code % 50 == 0) {
return;
}
case 1:
out.write(("setAhead(" + code + ");").getBytes());
break;
case 2:
out.write(("back(" + code + ");").getBytes());
break;
case 3:
out.write(("setTurnRight(" + code + ");").getBytes());
break;
case 4:
out.write(("turnLeft(" + code + ");").getBytes());
break;
// keep going...
As you can see, it’s not rocket science and, using this technique, the genetic operations are really simple too:
private static String cross(String genome1, String genome2) {
int crosses = (int) (Math.random() * 10) + 1;
for (int i = 0; i < crosses; i++) {
int cut = (int) Math.floor(Math.random() * Math.min(genome1.length(), genome2.length()));
String temp = genome1.substring(0, cut) + genome2.substring(cut, genome2.length());
genome2 = genome2.substring(0, cut) + genome1.substring(cut, genome1.length());
genome1 = temp;
}
return genome1;
}
After generate and compile many random robots, the next step is to evaluate each robot. The unique fair way to do this is run each generated robot on a Robocode battlefield against another robot and see how much points it does.
I couldn’t find any documentation about it on the Robocode page, but I figured out after some trys that’s possible to add the robocode.jar that comes with the Robocode to a Java project to run a predefined battle and get the result data. Here is how to do it:
private void evaluate() {
RobocodeEngine engine = new RobocodeEngine();
BattlefieldSpecification battleField = new BattlefieldSpecification();
for (Robot robot : robots) {
RobotSpecification[] specifications = new RobotSpecification[2];
for (RobotSpecification specification : engine.getLocalRepository()) {
if (specification.getName().equals(robot.name)) {
specifications[0] = specification;
} else if (specification.getName().equals("sample.Crazy")) {
specifications[1] = specification;
}
}
BattleSpecification battle = new BattleSpecification(25, battleField, specifications);
engine.runBattle(battle, true);
}
Collections.sort(robots);
}
So… that’s it.
Until the moment, I wasn’t able to evolve any competitive robot, but this project already created robots with some cool behaviors and it just has some days of live and a few lines of code, so I’ll keep going on it to see how far I can go.