User:Axe/RoboLeague Analyser
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:
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; } }