statGrapher = new StatGrapher(); statGrapher.setStats(yourStatsArray?); statGrapher.setFrame(0, 0, getBattleFieldWidth?(), getBattleFieldHeight?());And then the following in your onScannedRobot event:
statGrapher.selectSegment(new int[] {a, b, c, d}); statGrapher.draw();Where a, b, c, and d are the indices for your segments that would normally select your current stats array, like "yourStatsArray?[a][b][c][d]". If you don't have any segments, there is no need to call selectSegment(). It will work without it. If you do call it and you have no segments, you must pass either null or an empty int array. You may display multiple graphs as well, if you like, and put them wherever you want on the background.
I hope someone finds this useful! If you have any feature requests, just let me know.
package wiki.graphing; import robocode.robocodeGL.LineGL; import robocode.robocodeGL.system.GLRenderer; import java.awt.Color; import java.lang.reflect.*; public class StatGrapher { private LineGL[] graph; private Object stats; private Object selected; private double x, y, width, height; private double lineWidth = 2; private Color color = Color.GREEN; public void setFrame(double x, double y, double width, double height) { setX(x); setY(y); setWidth(width); setHeight(height); } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } public void setWidth(double width) { this.width = width; } public void setHeight(double height) { this.height = height; } public void setStats(Object stats) { this.stats = this.selected = stats; } public void setColor(Color color) { this.color = color; } public void selectSegment(int[] indices) { Object temp = stats; for (int i = 0; indices != null && i < indices.length; i++) temp = Array.get(temp, indices[i]); selected = temp; } public void draw() { double highestValue = 1; remove(); graph = new LineGL[Array.getLength(selected) - 1]; for (int i = 0; i < Array.getLength(selected); i++) if (Array.getDouble(selected, i) > highestValue) highestValue = Array.getDouble(selected, i); for (int i = 0; i < graph.length; i++) { graph[i] = new LineGL(); graph[i].setColor(color); graph[i].setWidth(lineWidth); graph[i].setLine(x + width * i / graph.length, y + height * Array.getDouble(selected, i) / highestValue, x + width * (i + 1) / graph.length, y + height * Array.getDouble(selected, i + 1) / highestValue); GLRenderer.getInstance().addRenderElement(graph[i]); } } public void remove() { if (graph != null) { for (int i = 0; i < graph.length; i++) { if (graph[i] != null) graph[i].remove(); } } } }
Wow, great tool... thanks nano! --David Alves
No problem! :) -- nano
public StatGrapher(Color color) { this.color = color; }Convenient when you want to paint several graphs. Also, the way I do waves makes statGrapher truly easy to use. Like so:
... import wiki.graphing.*; ... public class Pugilist extends AdvancedRobot { ... StatGrapher ewGrapher = new StatGrapher(Color.GREEN); ... public void run() { ... ewGrapher.setFrame(0, 0, getBattleFieldWidth(), getBattleFieldHeight()); ... } ... public void onScannedRobot(ScannedRobotEvent e) { ... EnemyWave ew = new EnemyWave(); ... ew.visits = moveFactors[distanceIndex = (int)(enemyDistance / (MAX_DISTANCE / DISTANCE_INDEXES))] [(int)(enemyFirePower / 0.65)]; ... ewGrapher.setStats(ew.visits); ewGrapher.draw(); ... } ... }Where "visits" is my int[] visit counts array held by my Wave instances. Anyone try doing this with totally unsegmented EnemyWaves and watch the graph move! It's a learning experience.
-- PEZ