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