RoboTweaker

From Robowiki
Revision as of 19:36, 12 May 2016 by RobertWalker (talk | contribs) (RoboTweaker)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

RoboTweaker is a tool currently under development by RobertWalker to help you optimize your bot's performance. It's not currently available, but below is a description of how it is intended to work.

Example

Let's say you the following constant declared in your bot:

private static final double FIRE_POWER = 3.0;

After reading the Selecting Fire Power article on RoboWiki, you begin to wonder whether it might not be a good idea to experiment with the amount of energy you pour into each shot. You could tweak the FIRE_POWER constant, run your bot, and repeat until you zero in on a good value; but RoboTweaker can do that grunt work for you.

The first task is to convert your constants so that they read values from the system properties. Below is a class that can facilitate this:

import java.lang.reflect.Method;

public class Props {
	private String prefix;

	public Props(String prefix) {
		this.prefix = prefix + ".";
	}

	public boolean get(String key, boolean def) {
		String value = get(key);
		return value != null ? Boolean.parseBoolean(value) : def;
	}

	public int get(String key, int def) {
		String value = get(key);
		return value != null ? Integer.parseInt(value) : def;
	}

	public long get(String key, long def) {
		String value = get(key);
		return value != null ? Long.parseLong(value) : def;
	}

	public double get(String key, double def) {
		String value = get(key);
		return value != null ? Double.parseDouble(value) : def;
	}

	@SuppressWarnings("unchecked")
	public <T extends Enum<?>> T get(String key, Class<T> enumClass, T def) {
		String value = get(key);

		if (value != null) {
			try {
				Method method = enumClass.getMethod("name", String.class);
				return (T) method.invoke(null, key);
			} catch (ReflectiveOperationException ex) {
				throw new RuntimeException(ex);
			}
		}

		return def;
	}

	public String get(String key, String def) {
		return System.getProperty(prefix + key, def);
	}

	private String get(String key) {
		return System.getProperty(prefix + key);
	}
}

Now you can write this:

private static final Props PROPS = new Props("myname.mybot");
private static final double FIRE_POWER = PROPS.get("firePower", 30.0);

This means that now you can alter the amount of energy your robot uses when it shoots by setting the myname.mybot.firePower system property. RoboTweaker automates the process of trying many different values for a property and running battles for each. At its most basic level, you can directly use the BattleRunner class like this:

import rjw.robotweaker.*;
import java.util.Iterator;

public class Test {
	public static final void main(String[] args) {
		DoubleTweak tweak = new DoubleTweak("myname.mybot.firePower", 0.1, 3.0, 0.1);

		for (Iterator<Void> iter = tweak.iterator(); iter.hasNext(); ) {
			System.out.println();
			System.out.println(iter);
			iter.next();
			new BattleRunner("C:\\robocode")
			.rounds(100)
			.addRobots("myname.mybot*", "sample.Crazy")
			.go();
		}
	}
}

Objects which implement the Tweak interface define properties that can be tweaked. In this case, it's a double value, which we want to start at 0.1 and end at 3.0, incrementing by 0.1 each time. We then pit our bot against sample.Crazy with 100 rounds per battle. The DoubleTweak class sets the system property through each iteration, then BattleRunner will execute the battle. Eventually, I'll provide the ability to provide custom handlers for analyzing the results, but as it currently stands BattleRunner dumps the results to the console, allowing you to see what happened at each setting.

Future Plans

  • Execute tweak runs from a configuration file so that you don't have to write any code to use RoboTweaker.
  • Provide a mechanism to use results listeners instead of just dumping to the console.
  • Create a results listener that will provide fancy charts.
  • Create a results listener to dump the data to CSV for further analysis.
  • Create a Tweak implementation that will allow you to tweak multiple properties at once and run battles for all permutations.