User:Axe/RoboLeague Analyser

From Robowiki
< User:Axe
Revision as of 14:34, 14 February 2011 by Nat (talk | contribs) (fix category)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

I allways suffered a lot running RoboLeague, something like 5 seasons of 35 rounds match in a TestBed of 20 bots or how. And also suffered after, trying to excel the results of those many tables.
In order to to help me analyse the results of RoboLeague, i built this modest analyser.
It reads the .xml file resulting of running RoboLeague division mode, focused in your bot, against a TestBed of n bots in m seasons. Process The info of the xml and give me an output as a table with this kind of colums:

dos.writeBytes("Opponent" + sep + "PBI(%)" + sep + "My score" + sep
					+ "Opp Score" + sep + "My bull.dmg." + sep
					+ "Opp bull.dmg." + "\r\n");

Averaged by the seasons quantity.
That means that i have now a single table with the results averaged. This by itself is usefull to me, but the real reason that made me post this, is that it is a very simple code accessing the output .xml file of RoboLeague, and demontrates the basic manipulation of xml structures with Java APIs. Its very crude and simple, but I prefer that way, it is (i think) easier to understand and adapt/use. Feel u all free to use this code (RWPCL).

Usage: axe.LeagueAnalyser <RoboLeague_xml_file> <bot_name_with_underscore_in_spaces>


The Code:

Download it

LeagueAnalyser.java:

package axe;

import java.io.*;
import java.text.DecimalFormat;
import java.util.*;

import javax.xml.parsers.*;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.*;
/** 
 * LeagueAnalyser - 10/06/2004
 * @author Axe
 * 
 * This code is released under the RoboWiki Public Code Licence (RWPCL),
 * datailed on:
 * http://robowiki.net/?RWPCL
 * (Basically it means you must keep the code public if you base any code on
 * it.)
 * Not basically, i think it means that the knowledge should not be 
 * retained, but shared. We must all remember that the veins of the Knowledge 
 * must flow. Quoting(or some) PEZ´s comment about OpenSouce: "At least is a 
 * good Karma".
 */
public class LeagueAnalyser {

	private Document document;
	private String bot;
	private HashMap matches = new HashMap();

	public LeagueAnalyser(String srcFile, String robot) {
		super();
		this.bot = robot.replaceAll("_", " ");
		System.out.println("processing file " + srcFile + " for bot "
				+ this.bot);
		setXML(srcFile);
		Node root = document.getDocumentElement();
		ArrayList seasons = getChilds(root, "SEASON");
		System.out.println("Seasons:" + seasons.size());
		BotPair pair = new BotPair();
		String sep = "\u0009";
		for (int i = 0; i < seasons.size(); i++) {

			Node season = (Node) seasons.get(i);
			ArrayList groupings = getChilds(season, "GROUPING");
			System.out
					.println("Season " + i + " groupings " + groupings.size());
			for (int j = 0; j < groupings.size(); j++) {
				Node grouping = (Node) groupings.get(j);
				ArrayList results = getChilds(grouping, "RESULTS");
				BotReg myReg = null;
				BotReg oppReg = null;

				for (int k = 0; k < results.size(); k++) {
					Element result = (Element) results.get(k);

					BotReg reg = new BotReg(result);
					if (reg.getBot().equals(bot)) {
						myReg = reg;
					} else {
						oppReg = reg;
					}
				}
				if (myReg != null && oppReg != null) {
					pair = new BotPair();
					if (matches.containsKey(oppReg.getBot())) {
						pair = (BotPair) matches.get(oppReg.getBot());

						myReg = pair.getMe().add(myReg);
						oppReg = pair.getHim().add(oppReg);
					}
					pair.setHim(oppReg);
					pair.setMe(myReg);
					matches.put(oppReg.getBot(), pair);

				}
			}
		}
		DecimalFormat forma = new DecimalFormat("0.00");

		ArrayList keys = new ArrayList(matches.keySet());
		Collections.sort(keys);
		File output = new File(bot + ".results");
		try {
			FileOutputStream fos = new FileOutputStream(output);
			DataOutputStream dos = new DataOutputStream(fos);
			dos.writeBytes("Results for " + bot + " " + seasons.size()
					+ " seasons\r\n");
			dos.writeBytes("Opponent" + sep + "PBI(%)" + sep + "My score" + sep
					+ "Opp Score" + sep + "My bull.dmg." + sep
					+ "Opp bull.dmg." + "\r\n");

			System.out.println("performing results for " + keys.size()
					+ " matches.");
			for (int i = 0; i < keys.size(); i++) {

				pair = (BotPair) matches.get(keys.get(i));
				BotReg me = pair.getMe();
				BotReg he = pair.getHim();

				double percent = (me.getScore() * 100D)
						/ (he.getScore() + me.getScore());
				System.out.println(he.getBot() + ":" + forma.format(percent));
				System.out.println(he.getBot() + ": " + forma.format(percent)
						+ "% " + me.getScore() + "/" + he.getScore());
				dos.writeBytes(he.getBot() + sep + forma.format(percent) + sep
						+ me.getScore() + sep + he.getScore() + sep
						+ me.getBullet_damage() + sep + he.getBullet_damage()
						+ "\r\n");
			}
			dos.close();
			fos.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * LeagueAnalyser main vm method
	 * Usage: axe.LeagueAnalyser <RoboLeague_xml_file> <bot_name_with_underscore_in_spaces>
	 */
	public static void main(String[] args) {
		new LeagueAnalyser(args[0], args[1]);
	}

	public void setXML(String xmlFile) {
		try {
			File src = new File(xmlFile);

			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			document = builder.parse(src);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private ArrayList getChilds(Node localRoot, String childName) {
		ArrayList groupings = new ArrayList();

		NodeList childs = localRoot.getChildNodes();
		for (int i = 0; i < childs.getLength(); i++) {
			Node child = childs.item(i);
			if (child.getNodeName().equals(childName)) {
				groupings.add(child);
			}
		}
		return groupings;
	}

}

BotReg.java:

package axe;

import org.w3c.dom.Element;
/** 
 * BotReg - 10/06/2004
 * @author Axe
 * 
 * This code is released under the RoboWiki Public Code Licence (RWPCL),
 * datailed on:
 * http://robowiki.net/?RWPCL
 * (Basically it means you must keep the code public if you base any code on
 * it.)
 * Not basically, i think it means that the knowledge should not be 
 * retained, but shared. We must all remember that the veins of the Knowledge 
 * must flow. Quoting(or some) PEZ´s comment about OpenSouce: "At least is a 
 * good Karma".
 */
public class BotReg {

	private String bot = null;
	private int score = 0;
	private int survival = 0;
	private int last_survivor_bonus = 0;
	private int bullet_damage = 0;
	private int bullet_damage_bonus = 0;
	private int ram_damage = 0;
	private int ram_damage_bonus = 0;
	private int n_first_rank = 0;
	private int n_second_rank = 0;
	private int n_third_rank = 0;

	public BotReg() {
		super();
	}

	public BotReg(Element reg) {
		super();
		bot = reg.getAttribute("id");
		score = Integer.parseInt(reg.getAttribute("total_score"));
		survival = Integer.parseInt(reg.getAttribute("survival"));
		last_survivor_bonus = Integer.parseInt(reg
				.getAttribute("last_survivor_bonus"));
		bullet_damage = Integer.parseInt(reg.getAttribute("bullet_damage"));
		bullet_damage_bonus = Integer.parseInt(reg
				.getAttribute("bullet_damage_bonus"));
		ram_damage = Integer.parseInt(reg.getAttribute("ram_damage"));
		ram_damage_bonus = Integer.parseInt(reg
				.getAttribute("ram_damage_bonus"));
		n_first_rank = Integer.parseInt(reg.getAttribute("n_first_rank"));
		n_second_rank = Integer.parseInt(reg.getAttribute("n_second_rank"));
		n_third_rank = Integer.parseInt(reg.getAttribute("n_third_rank"));
	}

	public BotReg add(BotReg reg) {
		if (!reg.equals(this)) {
			System.err.println("BotReg.add(), bots don´t match:" + reg.getBot()
					+ "," + this.getBot());
			return null;
		}
		BotReg ret = new BotReg();
		ret.bot = this.bot;
		ret.score = this.score + reg.score;
		ret.survival = this.survival + reg.survival;
		ret.last_survivor_bonus = this.last_survivor_bonus
				+ reg.last_survivor_bonus;
		ret.bullet_damage = this.bullet_damage + reg.bullet_damage;
		ret.bullet_damage_bonus = this.bullet_damage_bonus
				+ reg.bullet_damage_bonus;
		ret.ram_damage = this.ram_damage + reg.ram_damage;
		ret.ram_damage_bonus = this.ram_damage_bonus + reg.ram_damage_bonus;
		ret.n_first_rank = this.n_first_rank + reg.n_first_rank;
		ret.n_second_rank = this.n_second_rank + reg.n_second_rank;
		ret.n_third_rank = this.n_third_rank + reg.n_third_rank;
		return ret;
	}

	public String getBot() {
		return bot;
	}
	public int getScore() {
		return score;
	}
	public boolean equals(Object o) {
		if (!(o instanceof BotReg)) {
			return false;
		}
		return ((BotReg) o).getBot().equals(this.getBot());
	}
	public int hashCode() {
		return getBot().hashCode();
	}
	public int getBullet_damage() {
		return bullet_damage;
	}
}

BotPair.java:

package axe;

/** 
 * BotPair - 10/06/2004
 * @author Axe
 * 
 * This code is released under the RoboWiki Public Code Licence (RWPCL),
 * datailed on:
 * http://robowiki.net/?RWPCL
 * (Basically it means you must keep the code public if you base any code on
 * it.)
 * Not basically, i think it means that the knowledge should not be 
 * retained, but shared. We must all remember that the veins of the Knowledge 
 * must flow. Quoting(or some) PEZ´s comment about OpenSouce: "At least is a 
 * good Karma".
 */
public class BotPair {

	private BotReg me;
	private BotReg him;

	public BotPair() {
		super();
	}
	public BotPair(BotReg me, BotReg him) {
		super();
		this.me = me;
		this.him = him;
	}
	public BotReg getHim() {
		return him;
	}
	public void setHim(BotReg him) {
		this.him = him;
	}
	public BotReg getMe() {
		return me;
	}
	public void setMe(BotReg me) {
		this.me = me;
	}
}