Permalink
Browse files

Support for regenerating bot input from a replay

  • Loading branch information...
1 parent 46334d5 commit 7b5f26f71432fdd89dbb94e51c2125dd25b9ee2f @mleise mleise committed Oct 19, 2011
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,28 @@
+package com.aicontest.visualizer;
+
+public class BotInputOptions {
+
+ private final String player;
+ private final int min;
+ private final int max;
+
+ public BotInputOptions(String argString) {
+ String[] args = argString.split(",");
+ player = args[0];
+ String[] turns = args[1].split("-");
+ min = Integer.parseInt(turns[0]);
+ max = Integer.parseInt(turns[turns.length - 1]);
+ }
+
+ public String getPlayer() {
+ return player;
+ }
+
+ public int getMin() {
+ return min;
+ }
+
+ public int getMax() {
+ return max;
+ }
+}
@@ -14,10 +14,12 @@
import java.net.URI;
import java.net.URISyntaxException;
+import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Undefined;
import com.aicontest.visualizer.js.dom.HTMLDocument;
+import com.aicontest.visualizer.js.dom.XMLHttpRequest;
public class Main implements IVisualizerUser, WindowListener {
@@ -39,6 +41,7 @@ public static void main(String[] args) {
String fileName = null;
VideoOptions video = null;
boolean moreOptions = true;
+ BotInputOptions botInput = null;
for (String arg : args) {
if (moreOptions && arg.startsWith("--")) {
try {
@@ -50,6 +53,9 @@ public static void main(String[] args) {
} else if (arg.startsWith("--video=")) {
String vidArgString = arg.substring(8);
video = new VideoOptions(vidArgString);
+ } else if (arg.startsWith("--botinput=")) {
+ String argString = arg.substring(11);
+ botInput = new BotInputOptions(argString);
} else if (arg.startsWith("--decorated=")) {
decorated = Boolean.parseBoolean(arg
.substring(12));
@@ -86,7 +92,7 @@ public static void main(String[] args) {
System.err.println("(The visualizer needs a file name.)");
System.exit(1);
}
- new Main(fileName, video);
+ new Main(fileName, video, botInput);
}
} catch (Exception e) {
e.printStackTrace();
@@ -103,13 +109,16 @@ private static void invalidOption(String arg) {
private static void printHelp(PrintStream out) {
out.println("Syntax: <options> filename");
out.println("Options:");
- out.println(" -h / --help : Prints this help.");
- out.println(" --width=<int> : Set the display width in pixels.");
- out.println(" --height=<int> : Set the display height in pixels.");
- out.println(" --decorated=[true/false] : Enables or disable GUI elements around the visualizer.");
- out.println(" --video=<fpt>,<fmt> : Enable video output mode at");
- out.println(" <fpt> frames per turn using");
- out.println(" <ext> as file extension.");
+ out.println(" -h / --help : Prints this help.");
+ out.println(" --width=<int> : Set the display width in pixels.");
+ out.println(" --height=<int> : Set the display height in pixels.");
+ out.println(" --decorated=[true/false] : Enables or disable GUI elements around the visualizer.");
+ out.println(" --video=<fpt>,<fmt> : Enable video output mode at");
+ out.println(" <fpt> frames per turn using");
+ out.println(" <ext> as file extension.");
+ out.println("--botinput=<player>,<turn(s)> : Generate bot intput for a replay.");
+ out.println(" <player> name of the bot");
+ out.println(" <turn(s)> A single turn number or a range like 1-1000.");
out.println();
out.println("Video images will be numbered 00000000.<fmt> to 99999999.<fmt>.");
out.println("Example call that generates ten frames per turn without user interface:");
@@ -118,8 +127,8 @@ private static void printHelp(PrintStream out) {
out.println(" ffmpeg -i %08d.png movie.mp4");
}
- private ScriptableObject init(boolean resizable) throws InstantiationException,
- IllegalAccessException, IOException {
+ private ScriptableObject init(boolean resizable)
+ throws InstantiationException, IllegalAccessException, IOException {
visualizer = new Visualizer(this, width, height, resizable);
document = visualizer.getDomWindow().getDocument();
ScriptableObject options = visualizer.construct("Options", null);
@@ -141,7 +150,8 @@ private ScriptableObject construct(ScriptableObject options, Object config,
document, options, Undefined.instance, Undefined.instance,
config });
if (video != null) {
- videoCapture = new VideoCapture(visualizer, frame, video.getFormat());
+ videoCapture = new VideoCapture(visualizer, frame,
+ video.getFormat());
ScriptableObject.defineProperty(visualizer.global, "video",
videoCapture, ScriptableObject.DONTENUM);
visualizer.invoke(vis, "javaVideoOutput",
@@ -150,19 +160,27 @@ private ScriptableObject construct(ScriptableObject options, Object config,
return vis;
}
- public Main(String replay, VideoOptions video)
+ public Main(String replay, VideoOptions video, BotInputOptions botInput)
throws InstantiationException, IllegalAccessException, IOException,
URISyntaxException {
if (replay.endsWith(".stream")) {
if (video != null) {
System.err
.println("Cannot record videos for logged streaming replays. Use a storage format replay instead.");
System.exit(1);
+ } else if (botInput != null) {
+ System.err
+ .println("Cannot create bot input from logged streaming replays. Use a storage format replay instead.");
+ System.exit(1);
} else {
startStream(new FileInputStream(replay));
}
} else {
- startReplay(replay, video);
+ if (botInput != null) {
+ startBotInput(replay, botInput);
+ } else if (botInput == null || video != null) {
+ startReplay(replay, video);
+ }
}
}
@@ -177,6 +195,54 @@ private void startStream(InputStream inputStream)
private void startReplay(String replay, VideoOptions video)
throws URISyntaxException, InstantiationException,
IllegalAccessException, IOException {
+ URI uri = replayStringToUri(replay);
+ ScriptableObject options = init(video == null);
+ ScriptableObject vis = construct(options, Undefined.instance, video);
+ visualizer.invoke(vis, "loadReplayDataFromURI", new Object[] { uri });
+ visualizer.loop();
+ }
+
+ private void startBotInput(String replaySource, BotInputOptions botInput)
+ throws URISyntaxException, InstantiationException,
+ IllegalAccessException, IOException {
+ WebWrapper ww = new WebWrapper(getJavaScriptPath());
+ ww.loadProgram(getProgram());
+ ww.runProgram();
+ URI uri = replayStringToUri(replaySource);
+ XMLHttpRequest xhr = new XMLHttpRequest();
+ xhr.open("GET", uri.toString());
+ try {
+ xhr.send();
+ } catch (IOException e) {
+ System.err.println("Could not load " + replaySource + ": " + e);
+ System.exit(1);
+ }
+ String replayStr = xhr.getResponseText();
+ ScriptableObject replay = ww.construct("Replay",
+ new Object[] { replayStr });
+ ScriptableObject meta = (ScriptableObject) replay.get("meta", replay);
+ NativeArray playernames = (NativeArray) meta.get("playernames", meta);
+ int userIndex = playernames.indexOf(botInput.getPlayer());
+ if (userIndex == -1) {
+ System.err.println(botInput.getPlayer()
+ + " does not exist in the replay");
+ System.exit(1);
+ } else if (botInput.getMin() < 1
+ || botInput.getMax() > (Double) replay.get("duration", replay)
+ || botInput.getMin() > botInput.getMax()) {
+ System.err.println("You requested turns " + botInput.getMin() + "-"
+ + botInput.getMax() + ", but the range is 1-"
+ + ((Double) replay.get("duration", replay)).intValue());
+ }
+ String result = (String) ww.invoke(
+ replay,
+ "generateBotInput",
+ new Object[] { userIndex, botInput.getMin() - 1,
+ botInput.getMax() - 1 });
+ System.out.print(result);
+ }
+
+ private URI replayStringToUri(String replay) throws URISyntaxException {
URI uri = null;
try {
uri = new URI(replay);
@@ -185,10 +251,7 @@ private void startReplay(String replay, VideoOptions video)
if (uri == null || uri.getScheme() == null) {
uri = new URI("file", replay, null);
}
- ScriptableObject options = init(video == null);
- ScriptableObject vis = construct(options, Undefined.instance, video);
- visualizer.invoke(vis, "loadReplayDataFromURI", new Object[] { uri });
- visualizer.loop();
+ return uri;
}
public Main() throws IOException, InstantiationException,
@@ -41,7 +41,7 @@
private int id;
private boolean initialized;
- public Stream(ScriptableObject vis, Visualizer visualizer,
+ public Stream(ScriptableObject vis, WebWrapper visualizer,
InputStream inputStream, String name) {
activatePrototypeMap(MAX_ID);
ScriptableObject global = visualizer.getGlobal();
@@ -18,13 +18,13 @@
public class VideoCapture {
- private final Visualizer visualizer;
+ private final WebWrapper visualizer;
private final Frame frame;
private int num = 0;
private VideoCompressorPool videoCompressorPool;
private long start;
- public VideoCapture(Visualizer visualizer, Frame frame, String format)
+ public VideoCapture(WebWrapper visualizer, Frame frame, String format)
throws IOException {
this.visualizer = visualizer;
this.frame = frame;
@@ -49,9 +49,7 @@ public Visualizer(IVisualizerUser app, int width, int height,
Object document = Context.javaToJS(domWindow.getDocument(), global);
ScriptableObject.putProperty(global, "document", document);
loadProgram(app.getProgram());
- for (WebWrapper.Script script : scripts) {
- script.run();
- }
+ runProgram();
drawPanel = new VisualizerPanel(this, width, height);
drawPanel.addComponentListener(this);
drawPanel.addMouseMotionListener(this);
@@ -18,6 +18,9 @@
import java.util.Map.Entry;
import java.util.concurrent.locks.ReentrantLock;
+import javax.swing.JOptionPane;
+import javax.swing.UIManager;
+
import org.mozilla.javascript.CompilerEnvirons;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ErrorReporter;
@@ -92,10 +95,27 @@ public WebWrapper(String baseDir) {
XMLHttpRequest.class);
global.put("XMLHttpRequest", global, xmlHttpRequest);
new Console(global, "console");
- cx.evaluateString(global,
- "alert = function(x) { java.lang.System.out.println(x) }",
- "<web-wrapper>", 1, null);
jsonParser = new JsonParser(cx, global);
+ String[] names = { "alert", "prompt", "confirm" };
+ global.defineFunctionProperties(names, WebWrapper.class,
+ ScriptableObject.DONTENUM);
+ }
+
+ public static void alert(Object o) {
+ String message = o.toString();
+ JOptionPane.showMessageDialog(null, message);
+ }
+
+ public static boolean confirm(Object o) {
+ String message = o.toString();
+ return JOptionPane.showConfirmDialog(null, message,
+ UIManager.getString("OptionPane.titleText"),
+ JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION;
+ }
+
+ public static String prompt(Object o, Object def) {
+ String message = o.toString();
+ return JOptionPane.showInputDialog(message, def.toString());
}
private Class<?> recompile(String file) throws IOException {
@@ -309,4 +329,10 @@ public void exit() {
public ScriptableObject getGlobal() {
return global;
}
+
+ protected void runProgram() {
+ for (WebWrapper.Script script : scripts) {
+ script.run();
+ }
+ }
}
@@ -2,12 +2,21 @@
import java.applet.Applet;
import java.awt.Container;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import javax.swing.JFileChooser;
+
+import netscape.javascript.JSObject;
import org.mozilla.javascript.Function;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.aicontest.visualizer.Visualizer;
+import com.aicontest.visualizer.WebWrapper;
import com.aicontest.visualizer.js.tasks.DelayedExecutionUnit;
import com.aicontest.visualizer.js.tasks.TimeoutExecutionUnit;
@@ -130,6 +139,36 @@ public boolean setFullscreen(boolean enable) {
return webWrapper.setFullscreen(enable);
}
+ public void saveText(String text, String fileNameProposal)
+ throws UnsupportedEncodingException {
+ if (webWrapper.getContainer() instanceof Applet) {
+ System.out.println(text);
+ JSObject jsRoot = webWrapper.getJsRoot();
+ JSObject window = (JSObject) jsRoot.getMember("window");
+ String dataUri = "data:text/plain;charset=utf-8,"
+ + URLEncoder.encode(text, "UTF-8").replace("+", "%20");
+ Object[] params = new Object[] { dataUri, "_blank" };
+ window.call("open", params);
+ } else {
+ JFileChooser fc = new JFileChooser();
+ fc.setSelectedFile(new File(fileNameProposal));
+ if (fc.showSaveDialog(webWrapper.getContainer()) == JFileChooser.APPROVE_OPTION) {
+ File file = fc.getSelectedFile();
+ FileWriter fileWriter;
+ try {
+ fileWriter = new FileWriter(file);
+ try {
+ fileWriter.write(text);
+ } finally {
+ fileWriter.close();
+ }
+ } catch (Exception e) {
+ WebWrapper.alert("Error while saving: " + e);
+ }
+ }
+ }
+ }
+
public LocalStorage getLocalStorage() {
if (localStorage == null) {
Container container = webWrapper.getContainer();
@@ -81,7 +81,7 @@ public void setRequestHeader(String header, String value) {
conn.addRequestProperty(header, value);
}
- public void send() throws Exception {
+ public void send() throws IOException {
InputStream is = conn.getInputStream();
if ("x-gzip".equals(conn.getContentEncoding())) {
is = new GZIPInputStream(is);
Oops, something went wrong.

0 comments on commit 7b5f26f

Please sign in to comment.