// Dummy.java package net.sf.gogui.tools.dummy; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.Random; import net.sf.gogui.go.GoPoint; import net.sf.gogui.go.PointList; import net.sf.gogui.gtp.GtpCallback; import net.sf.gogui.gtp.GtpCommand; import net.sf.gogui.gtp.GtpEngine; import net.sf.gogui.gtp.GtpError; import net.sf.gogui.version.Version; /** Dummy Go program for testing GTP controlling programs. See the gogui-dummy documentation for information about the extension commands. */ public class Dummy extends GtpEngine { public Dummy(PrintStream log, boolean useRandomSeed, long randomSeed, int resign) throws Exception { super(log); registerCommands(); setName("gogui-dummy"); setVersion(Version.get()); m_random = new Random(); m_resign = resign; if (useRandomSeed) m_random.setSeed(randomSeed); initSize(GoPoint.DEFAULT_SIZE); } public void cmdBWBoard(GtpCommand cmd) { cmd.getResponse().append('\n'); for (int x = 0; x < m_size; ++x) { for (int y = 0; y < m_size; ++y) { cmd.getResponse().append(m_random.nextBoolean() ? 'B' : 'W'); if (y < m_size - 1) cmd.getResponse().append(' '); } cmd.getResponse().append('\n'); } } public void cmdBoardsize(GtpCommand cmd) throws GtpError { cmd.checkNuArg(1); int size = cmd.getIntArg(0, 1, GoPoint.MAX_SIZE); initSize(size); } public void cmdCrash(GtpCommand cmd) { System.err.println("Aborting gogui-dummy"); System.exit(1); } public void cmdClearBoard(GtpCommand cmd) throws GtpError { initSize(m_size); } public void cmdEcho(GtpCommand cmd) { cmd.setResponse(cmd.getArgLine()); } public void cmdEchoErr(GtpCommand cmd) { System.err.println(cmd.getArgLine()); } public void cmdDelay(GtpCommand cmd) throws GtpError { cmd.checkNuArgLessEqual(1); if (cmd.getNuArg() == 1) m_delay = cmd.getIntArg(0, 0, Integer.MAX_VALUE); else cmd.getResponse().append(m_delay); } public void cmdFileOpen(GtpCommand cmd) throws GtpError { try { File f = new File(cmd.getArg()); cmd.setResponse("CanonicalPath: " + f.getCanonicalPath() + "\n" + "Exists: " + f.exists() + "\n" + "CanRead: " + f.canRead() + "\n" + "CanWrite: " + f.canWrite() + "\n"); } catch (IOException e) { throw new GtpError(e.getMessage()); } } public void cmdFileSave(GtpCommand cmd) throws GtpError { File file = new File(cmd.getArg()); try { PrintStream out = new PrintStream(file); out.println("Hello world!"); out.close(); } catch (IOException e) { throw new GtpError(e.getMessage()); } } public void cmdEPList(GtpCommand cmd) throws GtpError { if (cmd.getNuArg() == 1 && cmd.getArg(0).equals("show")) cmd.setResponse(GoPoint.toString(m_ePList)); else m_ePList = cmd.getPointListArg(m_size); } public void cmdGfx(GtpCommand cmd) { cmd.setResponse("LABEL A4 test\n" + "COLOR green A5 A7 B9\n" + "COLOR #980098 B7 B8\n" + "SQUARE B5 C9\n" + "MARK A6 B6\n" + "TRIANGLE A9\n" + "WHITE A1\n" + "BLACK B1\n" + "CIRCLE c8\n" + "INFLUENCE a7 -1 b7 -0.75 c7 -0.5 d7 -0.25 e7 0" + " f7 0.25 g7 0.5 h7 0.75 j7 1\n" + "VAR b c1 w c2 b c3 b c4 w pass b c5\n" + "TEXT Graphics Demo\n"); } public void cmdGoGuiAnalyzeCommands(GtpCommand cmd) throws GtpError { cmd.checkArgNone(); String response = "bwboard/BWBoard/gogui-dummy-bwboard\n" + "none/Crash/gogui-dummy-crash\n" + "none/Delay/gogui-dummy-delay %o\n" + "eplist/EPList/gogui-dummy-eplist\n" + "string/File Open/gogui-dummy-file_open %r\n" + "none/File Save/gogui-dummy-file_save %w\n" + "gfx/Gfx/gogui-dummy-gfx\n" + "none/Invalid/gogui-dummy-invalid\n" + "none/Live Gfx/gogui-dummy-live_gfx\n" + "string/Long Response/gogui-dummy-long_response %s\n" + "none/Next Failure/gogui-dummy-next_failure %s\n" + "none/Next Success/gogui-dummy-next_success %s\n" + "sboard/SBoard/gogui-dummy-sboard\n" + "none/Sleep/gogui-dummy-sleep %s\n" + "none/Sleep 20s/gogui-dummy-sleep\n"; cmd.setResponse(response); } public void cmdGenmove(GtpCommand cmd) { ++m_numberGenmove; if (m_numberGenmove == m_resign) { cmd.setResponse("resign"); return; } int numberPossibleMoves = 0; for (int x = 0; x < m_size; ++x) for (int y = 0; y < m_size; ++y) if (! m_alreadyPlayed[x][y]) ++numberPossibleMoves; GoPoint point = null; if (numberPossibleMoves > 0) { int rand = m_random.nextInt(numberPossibleMoves); int index = 0; for (int x = 0; x < m_size && point == null; ++x) for (int y = 0; y < m_size && point == null; ++y) if (! m_alreadyPlayed[x][y]) { if (index == rand) point = GoPoint.get(x, y); ++index; } } cmd.setResponse(GoPoint.toString(point)); if (point != null) m_alreadyPlayed[point.getX()][point.getY()] = true; } public void cmdInterrupt(GtpCommand cmd) throws GtpError { cmd.checkArgNone(); } public void cmdInvalid(GtpCommand cmd) throws GtpError { cmd.checkArgNone(); printInvalidResponse("This is an invalid GTP response.\n" + "It does not start with a status character.\n"); } public void cmdLiveGfx(GtpCommand cmd) throws GtpError { cmd.checkArgNone(); System.err.println("gogui-gfx: TEXT Live Graphics Demo"); System.err.println("gogui-gfx: LABEL A4 test"); sleep(1000); System.err.println("gogui-gfx: COLOR green A5 A7 B9"); sleep(1000); System.err.println("gogui-gfx: COLOR #980098 B7 B8"); sleep(1000); System.err.println("gogui-gfx:\n" + "SQUARE B5 C9\n" + "MARK A6 B6\n" + "TRIANGLE A9\n"); sleep(1000); System.err.println("gogui-gfx: WHITE A1"); sleep(1000); System.err.println("gogui-gfx: BLACK B1"); sleep(1000); System.err.println("gogui-gfx: CIRCLE c8"); sleep(1000); System.err.println("gogui-gfx: INFLUENCE a7 -1 b7 -0.75 c7 " + "-0.5 d7 -0.25 e7 0 f7 0.25 g7 0.5 h7 0.75 " + "j7 1"); sleep(1000); System.err.println("gogui-gfx: VAR b c1 w c2 b c3 b c4 w pass " + "b c5"); sleep(1000); System.err.println("gogui-gfx: CLEAR"); } public void cmdLongResponse(GtpCommand cmd) throws GtpError { cmd.checkNuArg(1); int n = cmd.getIntArg(0, 1, Integer.MAX_VALUE); for (int i = 1; i <= n; ++i) { cmd.getResponse().append(i); cmd.getResponse().append("\n"); } } public void cmdNextFailure(GtpCommand cmd) throws GtpError { nextResponseFixed(cmd, false); } public void cmdNextSuccess(GtpCommand cmd) throws GtpError { nextResponseFixed(cmd, true); } public void cmdPlay(GtpCommand cmd) throws GtpError { cmd.checkNuArg(2); cmd.getColorArg(0); GoPoint point = cmd.getPointArg(1, m_size); if (point != null) m_alreadyPlayed[point.getX()][point.getY()] = true; } public void cmdSBoard(GtpCommand cmd) { cmd.getResponse().append('\n'); for (int x = 0; x < m_size; ++x) { for (int y = 0; y < m_size; ++y) { if (x == 1 && y == 1) cmd.getResponse().append("\"a b\""); else if (x == 1 && y == 2) cmd.getResponse().append("ab "); else if (x == 1 && y == 3) cmd.getResponse().append("abc "); else if (x == 2 && y == 1) cmd.getResponse().append("abcde"); else cmd.getResponse().append("\"\" "); if (y < m_size - 1) cmd.getResponse().append(' '); } cmd.getResponse().append('\n'); } } public void cmdSleep(GtpCommand cmd) throws GtpError { cmd.checkNuArgLessEqual(1); long millis = 20000; if (cmd.getNuArg() == 1) millis = (long)(cmd.getDoubleArg(0) * 1000.0); long showProgressInterval = Math.max(millis / 100, 1000); long steps = millis / showProgressInterval; long remaining = millis - steps * showProgressInterval; for (long i = 0; i < steps && ! isInterrupted(); ++i) { System.err.println("gogui-gfx: TEXT " + (100L * i / steps) + " %"); sleep(showProgressInterval); } sleep(remaining); } public void handleCommand(GtpCommand cmd) throws GtpError { if (m_nextResponseFixed) { m_nextResponseFixed = false; if (! m_nextStatus) throw new GtpError(m_nextResponse); cmd.setResponse(m_nextResponse); } else super.handleCommand(cmd); if (m_delay > 0) { try { Thread.sleep(1000L * m_delay); } catch (InterruptedException e) { } } } private boolean m_nextResponseFixed; private boolean m_nextStatus; /** Delay every command (seconds) */ private int m_delay; private int m_numberGenmove; private final int m_resign; private int m_size; private boolean[][] m_alreadyPlayed; private final Random m_random; private String m_nextResponse; /** Editable point list for gogui-dummy-eplist command. */ private PointList m_ePList = new PointList(); private void initSize(int size) { m_alreadyPlayed = new boolean[size][size]; m_size = size; m_numberGenmove = 0; } private void nextResponseFixed(GtpCommand cmd, boolean nextStatus) { m_nextResponseFixed = true; m_nextStatus = nextStatus; m_nextResponse = cmd.getArgLine(); } private void registerCommands() { register("boardsize", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdBoardsize(cmd); } }); register("clear_board", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdClearBoard(cmd); } }); register("gogui-dummy-bwboard", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdBWBoard(cmd); } }); register("gogui-dummy-crash", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdCrash(cmd); } }); register("gogui-dummy-delay", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdDelay(cmd); } }); register("gogui-dummy-eplist", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdEPList(cmd); } }); register("gogui-dummy-file_open", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdFileOpen(cmd); } }); register("gogui-dummy-file_save", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdFileSave(cmd); } }); register("gogui-dummy-gfx", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdGfx(cmd); } }); register("gogui-dummy-invalid", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdInvalid(cmd); } }); register("gogui-dummy-live_gfx", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdLiveGfx(cmd); } }); register("gogui-dummy-long_response", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdLongResponse(cmd); } }); register("gogui-dummy-next_failure", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdNextFailure(cmd); } }); register("gogui-dummy-next_success", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdNextSuccess(cmd); } }); register("gogui-dummy-sboard", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdSBoard(cmd); } }); register("gogui-dummy-sleep", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdSleep(cmd); } }); register("echo", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdEcho(cmd); } }); register("echo_err", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdEchoErr(cmd); } }); register("genmove", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdGenmove(cmd); } }); register("gogui-analyze_commands", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdGoGuiAnalyzeCommands(cmd); } }); register("gogui-interrupt", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdInterrupt(cmd); } }); register("play", new GtpCallback() { public void run(GtpCommand cmd) throws GtpError { cmdPlay(cmd); } }); } private void sleep(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { } } }