1 // Main.java 2 3 package net.sf.gogui.tools.twogtp; 4 5 import java.io.File; 6 import java.util.ArrayList; 7 import net.sf.gogui.game.TimeSettings; 8 import net.sf.gogui.go.GoPoint; 9 import net.sf.gogui.go.Komi; 10 import net.sf.gogui.util.ErrorMessage; 11 import net.sf.gogui.util.Options; 12 import net.sf.gogui.util.StringUtil; 13 import net.sf.gogui.version.Version; 14 15 /** TwoGtp main function. */ 16 public final class Main 17 { 18 /** TwoGtp main function. */ main(String[] args)19 public static void main(String[] args) 20 { 21 boolean exitError = false; 22 try 23 { 24 String options[] = { 25 "alternate", 26 "analyze:", 27 "auto", 28 "black:", 29 "compare", 30 "config:", 31 "debugtocomment", 32 "force", 33 "games:", 34 "help", 35 "handicap:", 36 "komi:", 37 "maxmoves:", 38 "observer:", 39 "openings:", 40 "referee:", 41 "sgffile:", 42 "size:", 43 "threads:", 44 "time:", 45 "verbose", 46 "version", 47 "white:", 48 "xml" 49 }; 50 Options opt = Options.parse(args, options); 51 opt.checkNoArguments(); 52 if (opt.contains("help")) 53 { 54 String helpText = 55 "Usage: gogui-twogtp [options]\n" + 56 "\n" + 57 "-alternate alternate colors\n" + 58 "-analyze file analyze result file\n" + 59 "-auto autoplay games\n" + 60 "-black command for black program\n" + 61 "-compare compare list of sgf files\n" + 62 "-config config file\n" + 63 "-debugtocomment save stderr of programs in SGF comments\n" + 64 "-force overwrite existing files\n" + 65 "-games number of games (0=unlimited)\n" + 66 "-help display this help and exit\n" + 67 "-komi komi\n" + 68 "-handicap handicap\n" + 69 "-maxmoves move limit\n" + 70 "-observer command for observer program\n" + 71 "-openings directory with opening sgf files\n" + 72 "-referee command for referee program\n" + 73 "-sgffile filename prefix\n" + 74 "-size board size for autoplay (default 19)\n" + 75 "-threads n number of threads\n" + 76 "-time spec set time limits (min[+min/moves])\n" + 77 "-verbose log GTP streams to stderr\n" + 78 "-version print version and exit\n" + 79 "-white command for white program\n" + 80 "-xml save games in XML format\n"; 81 System.out.print(helpText); 82 System.exit(0); 83 } 84 boolean compare = opt.contains("compare"); 85 if (compare) 86 { 87 Compare.compare(opt.getArguments()); 88 System.exit(0); 89 } 90 if (opt.contains("version")) 91 { 92 System.out.println("gogui-twogtp " + Version.get()); 93 System.exit(0); 94 } 95 boolean force = opt.contains("force"); 96 if (opt.contains("analyze")) 97 { 98 String filename = opt.get("analyze"); 99 new Analyze(filename, force); 100 return; 101 } 102 boolean alternate = opt.contains("alternate"); 103 boolean auto = opt.contains("auto"); 104 boolean debugToComment = opt.contains("debugtocomment"); 105 boolean verbose = opt.contains("verbose"); 106 String black = opt.get("black", ""); 107 if (black.equals("")) 108 throw new ErrorMessage("No black program set"); 109 String white = opt.get("white", ""); 110 if (white.equals("")) 111 throw new ErrorMessage("No white program set"); 112 String referee = opt.get("referee", ""); 113 String observer = opt.get("observer", ""); 114 int size = opt.getInteger("size", GoPoint.DEFAULT_SIZE, 1, 115 GoPoint.MAX_SIZE); 116 Komi komi = new Komi(6.5); 117 if (opt.contains("komi")) 118 komi = Komi.parseKomi(opt.get("komi")); 119 int handicap = opt.getInteger("handicap", 0, 0, 9); 120 int maxMoves = opt.getInteger("maxmoves", 1000, -1); 121 TimeSettings timeSettings = null; 122 if (opt.contains("time")) 123 timeSettings = TimeSettings.parse(opt.get("time")); 124 int defaultGames = (auto ? 1 : 0); 125 int numberGames = opt.getInteger("games", defaultGames, 0); 126 int numberThreads = opt.getInteger("threads", 1, 1); 127 if (numberThreads > 1 && ! auto) 128 throw new ErrorMessage("Option -threads needs option -auto"); 129 String sgfFile = opt.get("sgffile", ""); 130 if (opt.contains("games") && sgfFile.equals("")) 131 throw new ErrorMessage("Use option -sgffile with -games"); 132 Openings openings = null; 133 if (opt.contains("openings")) 134 openings = new Openings(new File(opt.get("openings"))); 135 boolean useXml = opt.contains("xml"); 136 if (auto) 137 System.in.close(); 138 139 TwoGtp twoGtp[] = new TwoGtp[numberThreads]; 140 TwoGtpThread thread[] = new TwoGtpThread[numberThreads]; 141 ResultFile resultFile = null; 142 for (int i = 0; i < numberThreads; ++i) 143 { 144 ArrayList<Program> allPrograms = new ArrayList<Program>(); 145 Program blackProgram = 146 new Program(black, "Black", "B", verbose); 147 allPrograms.add(blackProgram); 148 Program whiteProgram = 149 new Program(white, "White", "W", verbose); 150 allPrograms.add(whiteProgram); 151 Program refereeProgram; 152 if (referee.equals("")) 153 refereeProgram = null; 154 else 155 { 156 refereeProgram = 157 new Program(referee, "Referee", "R", verbose); 158 allPrograms.add(refereeProgram); 159 } 160 for (Program program : allPrograms) 161 program.setLabel(allPrograms); 162 if (! sgfFile.equals("") && resultFile == null) 163 resultFile = 164 new ResultFile(force, blackProgram, whiteProgram, 165 refereeProgram, numberGames, size, 166 komi, sgfFile, openings, alternate, 167 useXml, numberThreads); 168 if (i > 0) 169 verbose = false; 170 twoGtp[i] = new TwoGtp(blackProgram, whiteProgram, 171 refereeProgram, observer, size, komi, handicap, 172 numberGames, alternate, sgfFile, 173 verbose, openings, timeSettings, 174 resultFile); 175 twoGtp[i].setMaxMoves(maxMoves); 176 if (debugToComment) 177 twoGtp[i].setDebugToComment(true); 178 if (auto) 179 { 180 thread[i] = new TwoGtpThread(twoGtp[i]); 181 thread[i].start(); 182 } 183 } 184 if (auto) 185 { 186 for (int i = 0; i < numberThreads; ++i) 187 thread[i].join(); 188 for (int i = 0; i < numberThreads; ++i) 189 if (thread[i].getException() != null) 190 { 191 StringUtil.printException(thread[i].getException()); 192 exitError = true; 193 } 194 } 195 else 196 twoGtp[0].mainLoop(System.in, System.out); 197 if (resultFile != null) 198 resultFile.close(); 199 } 200 catch (Throwable t) 201 { 202 StringUtil.printException(t); 203 exitError = true; 204 } 205 if (exitError) 206 System.exit(1); 207 } 208 209 /** Make constructor unavailable; class is for namespace only. */ Main()210 private Main() 211 { 212 } 213 } 214 215 class TwoGtpThread 216 extends Thread 217 { TwoGtpThread(TwoGtp twoGtp)218 public TwoGtpThread(TwoGtp twoGtp) 219 { 220 m_twoGtp = twoGtp; 221 } 222 getException()223 public Exception getException() 224 { 225 return m_exception; 226 } 227 run()228 public void run() 229 { 230 try 231 { 232 m_twoGtp.autoPlay(); 233 } 234 catch (Exception e) 235 { 236 m_exception = e; 237 } 238 finally 239 { 240 m_twoGtp.close(); 241 } 242 } 243 244 private Exception m_exception; 245 246 private TwoGtp m_twoGtp; 247 } 248