1 // Dummy.java 2 3 package net.sf.gogui.tools.dummy; 4 5 import java.io.File; 6 import java.io.IOException; 7 import java.io.PrintStream; 8 import java.util.Random; 9 import net.sf.gogui.go.GoPoint; 10 import net.sf.gogui.go.PointList; 11 import net.sf.gogui.gtp.GtpCallback; 12 import net.sf.gogui.gtp.GtpCommand; 13 import net.sf.gogui.gtp.GtpEngine; 14 import net.sf.gogui.gtp.GtpError; 15 import net.sf.gogui.version.Version; 16 17 /** Dummy Go program for testing GTP controlling programs. 18 See the gogui-dummy documentation for information about the extension 19 commands. */ 20 public class Dummy 21 extends GtpEngine 22 { Dummy(PrintStream log, boolean useRandomSeed, long randomSeed, int resign)23 public Dummy(PrintStream log, boolean useRandomSeed, long randomSeed, 24 int resign) 25 throws Exception 26 { 27 super(log); 28 registerCommands(); 29 setName("gogui-dummy"); 30 setVersion(Version.get()); 31 m_random = new Random(); 32 m_resign = resign; 33 if (useRandomSeed) 34 m_random.setSeed(randomSeed); 35 initSize(GoPoint.DEFAULT_SIZE); 36 } 37 cmdBWBoard(GtpCommand cmd)38 public void cmdBWBoard(GtpCommand cmd) 39 { 40 cmd.getResponse().append('\n'); 41 for (int x = 0; x < m_size; ++x) 42 { 43 for (int y = 0; y < m_size; ++y) 44 { 45 cmd.getResponse().append(m_random.nextBoolean() ? 'B' : 'W'); 46 if (y < m_size - 1) 47 cmd.getResponse().append(' '); 48 } 49 cmd.getResponse().append('\n'); 50 } 51 } 52 cmdBoardsize(GtpCommand cmd)53 public void cmdBoardsize(GtpCommand cmd) throws GtpError 54 { 55 cmd.checkNuArg(1); 56 int size = cmd.getIntArg(0, 1, GoPoint.MAX_SIZE); 57 initSize(size); 58 } 59 cmdCrash(GtpCommand cmd)60 public void cmdCrash(GtpCommand cmd) 61 { 62 System.err.println("Aborting gogui-dummy"); 63 System.exit(1); 64 } 65 cmdClearBoard(GtpCommand cmd)66 public void cmdClearBoard(GtpCommand cmd) throws GtpError 67 { 68 initSize(m_size); 69 } 70 cmdEcho(GtpCommand cmd)71 public void cmdEcho(GtpCommand cmd) 72 { 73 cmd.setResponse(cmd.getArgLine()); 74 } 75 cmdEchoErr(GtpCommand cmd)76 public void cmdEchoErr(GtpCommand cmd) 77 { 78 System.err.println(cmd.getArgLine()); 79 } 80 cmdDelay(GtpCommand cmd)81 public void cmdDelay(GtpCommand cmd) throws GtpError 82 { 83 cmd.checkNuArgLessEqual(1); 84 if (cmd.getNuArg() == 1) 85 m_delay = cmd.getIntArg(0, 0, Integer.MAX_VALUE); 86 else 87 cmd.getResponse().append(m_delay); 88 } 89 cmdFileOpen(GtpCommand cmd)90 public void cmdFileOpen(GtpCommand cmd) throws GtpError 91 { 92 try 93 { 94 File f = new File(cmd.getArg()); 95 cmd.setResponse("CanonicalPath: " + f.getCanonicalPath() + "\n" + 96 "Exists: " + f.exists() + "\n" + 97 "CanRead: " + f.canRead() + "\n" + 98 "CanWrite: " + f.canWrite() + "\n"); 99 } 100 catch (IOException e) 101 { 102 throw new GtpError(e.getMessage()); 103 } 104 } 105 cmdFileSave(GtpCommand cmd)106 public void cmdFileSave(GtpCommand cmd) throws GtpError 107 { 108 File file = new File(cmd.getArg()); 109 try 110 { 111 PrintStream out = new PrintStream(file); 112 out.println("Hello world!"); 113 out.close(); 114 } 115 catch (IOException e) 116 { 117 throw new GtpError(e.getMessage()); 118 } 119 } 120 cmdEPList(GtpCommand cmd)121 public void cmdEPList(GtpCommand cmd) throws GtpError 122 { 123 if (cmd.getNuArg() == 1 && cmd.getArg(0).equals("show")) 124 cmd.setResponse(GoPoint.toString(m_ePList)); 125 else 126 m_ePList = cmd.getPointListArg(m_size); 127 } 128 cmdGfx(GtpCommand cmd)129 public void cmdGfx(GtpCommand cmd) 130 { 131 cmd.setResponse("LABEL A4 test\n" + 132 "COLOR green A5 A7 B9\n" + 133 "COLOR #980098 B7 B8\n" + 134 "SQUARE B5 C9\n" + 135 "MARK A6 B6\n" + 136 "TRIANGLE A9\n" + 137 "WHITE A1\n" + 138 "BLACK B1\n" + 139 "CIRCLE c8\n" + 140 "INFLUENCE a7 -1 b7 -0.75 c7 -0.5 d7 -0.25 e7 0" 141 + " f7 0.25 g7 0.5 h7 0.75 j7 1\n" + 142 "VAR b c1 w c2 b c3 b c4 w pass b c5\n" + 143 "TEXT Graphics Demo\n"); 144 } 145 cmdGoGuiAnalyzeCommands(GtpCommand cmd)146 public void cmdGoGuiAnalyzeCommands(GtpCommand cmd) throws GtpError 147 { 148 cmd.checkArgNone(); 149 String response = 150 "bwboard/BWBoard/gogui-dummy-bwboard\n" + 151 "none/Crash/gogui-dummy-crash\n" + 152 "none/Delay/gogui-dummy-delay %o\n" + 153 "eplist/EPList/gogui-dummy-eplist\n" + 154 "string/File Open/gogui-dummy-file_open %r\n" + 155 "none/File Save/gogui-dummy-file_save %w\n" + 156 "gfx/Gfx/gogui-dummy-gfx\n" + 157 "none/Invalid/gogui-dummy-invalid\n" + 158 "none/Live Gfx/gogui-dummy-live_gfx\n" + 159 "string/Long Response/gogui-dummy-long_response %s\n" + 160 "none/Next Failure/gogui-dummy-next_failure %s\n" + 161 "none/Next Success/gogui-dummy-next_success %s\n" + 162 "sboard/SBoard/gogui-dummy-sboard\n" + 163 "none/Sleep/gogui-dummy-sleep %s\n" + 164 "none/Sleep 20s/gogui-dummy-sleep\n"; 165 cmd.setResponse(response); 166 } 167 cmdGenmove(GtpCommand cmd)168 public void cmdGenmove(GtpCommand cmd) 169 { 170 ++m_numberGenmove; 171 if (m_numberGenmove == m_resign) 172 { 173 cmd.setResponse("resign"); 174 return; 175 } 176 int numberPossibleMoves = 0; 177 for (int x = 0; x < m_size; ++x) 178 for (int y = 0; y < m_size; ++y) 179 if (! m_alreadyPlayed[x][y]) 180 ++numberPossibleMoves; 181 GoPoint point = null; 182 if (numberPossibleMoves > 0) 183 { 184 int rand = m_random.nextInt(numberPossibleMoves); 185 int index = 0; 186 for (int x = 0; x < m_size && point == null; ++x) 187 for (int y = 0; y < m_size && point == null; ++y) 188 if (! m_alreadyPlayed[x][y]) 189 { 190 if (index == rand) 191 point = GoPoint.get(x, y); 192 ++index; 193 } 194 } 195 cmd.setResponse(GoPoint.toString(point)); 196 if (point != null) 197 m_alreadyPlayed[point.getX()][point.getY()] = true; 198 } 199 cmdInterrupt(GtpCommand cmd)200 public void cmdInterrupt(GtpCommand cmd) throws GtpError 201 { 202 cmd.checkArgNone(); 203 } 204 cmdInvalid(GtpCommand cmd)205 public void cmdInvalid(GtpCommand cmd) throws GtpError 206 { 207 cmd.checkArgNone(); 208 printInvalidResponse("This is an invalid GTP response.\n" + 209 "It does not start with a status character.\n"); 210 } 211 cmdLiveGfx(GtpCommand cmd)212 public void cmdLiveGfx(GtpCommand cmd) throws GtpError 213 { 214 cmd.checkArgNone(); 215 System.err.println("gogui-gfx: TEXT Live Graphics Demo"); 216 System.err.println("gogui-gfx: LABEL A4 test"); 217 sleep(1000); 218 System.err.println("gogui-gfx: COLOR green A5 A7 B9"); 219 sleep(1000); 220 System.err.println("gogui-gfx: COLOR #980098 B7 B8"); 221 sleep(1000); 222 System.err.println("gogui-gfx:\n" + 223 "SQUARE B5 C9\n" + 224 "MARK A6 B6\n" + 225 "TRIANGLE A9\n"); 226 sleep(1000); 227 System.err.println("gogui-gfx: WHITE A1"); 228 sleep(1000); 229 System.err.println("gogui-gfx: BLACK B1"); 230 sleep(1000); 231 System.err.println("gogui-gfx: CIRCLE c8"); 232 sleep(1000); 233 System.err.println("gogui-gfx: INFLUENCE a7 -1 b7 -0.75 c7 " 234 + "-0.5 d7 -0.25 e7 0 f7 0.25 g7 0.5 h7 0.75 " 235 + "j7 1"); 236 sleep(1000); 237 System.err.println("gogui-gfx: VAR b c1 w c2 b c3 b c4 w pass " 238 + "b c5"); 239 sleep(1000); 240 System.err.println("gogui-gfx: CLEAR"); 241 } 242 cmdLongResponse(GtpCommand cmd)243 public void cmdLongResponse(GtpCommand cmd) throws GtpError 244 { 245 cmd.checkNuArg(1); 246 int n = cmd.getIntArg(0, 1, Integer.MAX_VALUE); 247 for (int i = 1; i <= n; ++i) 248 { 249 cmd.getResponse().append(i); 250 cmd.getResponse().append("\n"); 251 } 252 } 253 cmdNextFailure(GtpCommand cmd)254 public void cmdNextFailure(GtpCommand cmd) throws GtpError 255 { 256 nextResponseFixed(cmd, false); 257 } 258 cmdNextSuccess(GtpCommand cmd)259 public void cmdNextSuccess(GtpCommand cmd) throws GtpError 260 { 261 nextResponseFixed(cmd, true); 262 } 263 cmdPlay(GtpCommand cmd)264 public void cmdPlay(GtpCommand cmd) throws GtpError 265 { 266 cmd.checkNuArg(2); 267 cmd.getColorArg(0); 268 GoPoint point = cmd.getPointArg(1, m_size); 269 if (point != null) 270 m_alreadyPlayed[point.getX()][point.getY()] = true; 271 } 272 cmdSBoard(GtpCommand cmd)273 public void cmdSBoard(GtpCommand cmd) 274 { 275 cmd.getResponse().append('\n'); 276 for (int x = 0; x < m_size; ++x) 277 { 278 for (int y = 0; y < m_size; ++y) 279 { 280 if (x == 1 && y == 1) 281 cmd.getResponse().append("\"a b\""); 282 else if (x == 1 && y == 2) 283 cmd.getResponse().append("ab "); 284 else if (x == 1 && y == 3) 285 cmd.getResponse().append("abc "); 286 else if (x == 2 && y == 1) 287 cmd.getResponse().append("abcde"); 288 else 289 cmd.getResponse().append("\"\" "); 290 if (y < m_size - 1) 291 cmd.getResponse().append(' '); 292 } 293 cmd.getResponse().append('\n'); 294 } 295 } 296 cmdSleep(GtpCommand cmd)297 public void cmdSleep(GtpCommand cmd) throws GtpError 298 { 299 cmd.checkNuArgLessEqual(1); 300 long millis = 20000; 301 if (cmd.getNuArg() == 1) 302 millis = (long)(cmd.getDoubleArg(0) * 1000.0); 303 long showProgressInterval = Math.max(millis / 100, 1000); 304 long steps = millis / showProgressInterval; 305 long remaining = millis - steps * showProgressInterval; 306 for (long i = 0; i < steps && ! isInterrupted(); ++i) 307 { 308 System.err.println("gogui-gfx: TEXT " + (100L * i / steps) + " %"); 309 sleep(showProgressInterval); 310 } 311 sleep(remaining); 312 } 313 handleCommand(GtpCommand cmd)314 public void handleCommand(GtpCommand cmd) throws GtpError 315 { 316 if (m_nextResponseFixed) 317 { 318 m_nextResponseFixed = false; 319 if (! m_nextStatus) 320 throw new GtpError(m_nextResponse); 321 cmd.setResponse(m_nextResponse); 322 } 323 else 324 super.handleCommand(cmd); 325 if (m_delay > 0) 326 { 327 try 328 { 329 Thread.sleep(1000L * m_delay); 330 } 331 catch (InterruptedException e) 332 { 333 } 334 } 335 } 336 337 private boolean m_nextResponseFixed; 338 339 private boolean m_nextStatus; 340 341 /** Delay every command (seconds) */ 342 private int m_delay; 343 344 private int m_numberGenmove; 345 346 private final int m_resign; 347 348 private int m_size; 349 350 private boolean[][] m_alreadyPlayed; 351 352 private final Random m_random; 353 354 private String m_nextResponse; 355 356 /** Editable point list for gogui-dummy-eplist command. */ 357 private PointList m_ePList = new PointList(); 358 initSize(int size)359 private void initSize(int size) 360 { 361 m_alreadyPlayed = new boolean[size][size]; 362 m_size = size; 363 m_numberGenmove = 0; 364 } 365 nextResponseFixed(GtpCommand cmd, boolean nextStatus)366 private void nextResponseFixed(GtpCommand cmd, boolean nextStatus) 367 { 368 m_nextResponseFixed = true; 369 m_nextStatus = nextStatus; 370 m_nextResponse = cmd.getArgLine(); 371 } 372 registerCommands()373 private void registerCommands() 374 { 375 register("boardsize", new GtpCallback() { 376 public void run(GtpCommand cmd) throws GtpError { 377 cmdBoardsize(cmd); } }); 378 register("clear_board", new GtpCallback() { 379 public void run(GtpCommand cmd) throws GtpError { 380 cmdClearBoard(cmd); } }); 381 register("gogui-dummy-bwboard", new GtpCallback() { 382 public void run(GtpCommand cmd) throws GtpError { 383 cmdBWBoard(cmd); } }); 384 register("gogui-dummy-crash", new GtpCallback() { 385 public void run(GtpCommand cmd) throws GtpError { 386 cmdCrash(cmd); } }); 387 register("gogui-dummy-delay", new GtpCallback() { 388 public void run(GtpCommand cmd) throws GtpError { 389 cmdDelay(cmd); } }); 390 register("gogui-dummy-eplist", new GtpCallback() { 391 public void run(GtpCommand cmd) throws GtpError { 392 cmdEPList(cmd); } }); 393 register("gogui-dummy-file_open", new GtpCallback() { 394 public void run(GtpCommand cmd) throws GtpError { 395 cmdFileOpen(cmd); } }); 396 register("gogui-dummy-file_save", new GtpCallback() { 397 public void run(GtpCommand cmd) throws GtpError { 398 cmdFileSave(cmd); } }); 399 register("gogui-dummy-gfx", new GtpCallback() { 400 public void run(GtpCommand cmd) throws GtpError { 401 cmdGfx(cmd); } }); 402 register("gogui-dummy-invalid", new GtpCallback() { 403 public void run(GtpCommand cmd) throws GtpError { 404 cmdInvalid(cmd); } }); 405 register("gogui-dummy-live_gfx", new GtpCallback() { 406 public void run(GtpCommand cmd) throws GtpError { 407 cmdLiveGfx(cmd); } }); 408 register("gogui-dummy-long_response", new GtpCallback() { 409 public void run(GtpCommand cmd) throws GtpError { 410 cmdLongResponse(cmd); } }); 411 register("gogui-dummy-next_failure", new GtpCallback() { 412 public void run(GtpCommand cmd) throws GtpError { 413 cmdNextFailure(cmd); } }); 414 register("gogui-dummy-next_success", new GtpCallback() { 415 public void run(GtpCommand cmd) throws GtpError { 416 cmdNextSuccess(cmd); } }); 417 register("gogui-dummy-sboard", new GtpCallback() { 418 public void run(GtpCommand cmd) throws GtpError { 419 cmdSBoard(cmd); } }); 420 register("gogui-dummy-sleep", new GtpCallback() { 421 public void run(GtpCommand cmd) throws GtpError { 422 cmdSleep(cmd); } }); 423 register("echo", new GtpCallback() { 424 public void run(GtpCommand cmd) throws GtpError { 425 cmdEcho(cmd); } }); 426 register("echo_err", new GtpCallback() { 427 public void run(GtpCommand cmd) throws GtpError { 428 cmdEchoErr(cmd); } }); 429 register("genmove", new GtpCallback() { 430 public void run(GtpCommand cmd) throws GtpError { 431 cmdGenmove(cmd); } }); 432 register("gogui-analyze_commands", new GtpCallback() { 433 public void run(GtpCommand cmd) throws GtpError { 434 cmdGoGuiAnalyzeCommands(cmd); } }); 435 register("gogui-interrupt", new GtpCallback() { 436 public void run(GtpCommand cmd) throws GtpError { 437 cmdInterrupt(cmd); } }); 438 register("play", new GtpCallback() { 439 public void run(GtpCommand cmd) throws GtpError { 440 cmdPlay(cmd); } }); 441 } 442 sleep(long millis)443 private void sleep(long millis) 444 { 445 try 446 { 447 Thread.sleep(millis); 448 } 449 catch (InterruptedException e) 450 { 451 } 452 } 453 } 454