Modified colors for compatibility with Tektronix 4107 terminal in ANSI mode.
[sgk-go] / interface / main.c
CommitLineData
7eeb782e
AT
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
3 * http://www.gnu.org/software/gnugo/ for more information. *
4 * *
5 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
6 * 2008 and 2009 by the Free Software Foundation. *
7 * *
8 * This program is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License as *
10 * published by the Free Software Foundation - version 3 or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License in file COPYING for more details. *
17 * *
18 * You should have received a copy of the GNU General Public *
19 * License along with this program; if not, write to the Free *
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
21 * Boston, MA 02111, USA. *
22\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23
24#include "gnugo.h"
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
30
31#ifdef HAVE_UNISTD_H
32/* For isatty(). */
33#include <unistd.h>
34#else
35#include <io.h>
36#endif
37
38#if TIME_WITH_SYS_TIME
39# include <sys/time.h>
40# include <time.h>
41#else
42# if HAVE_SYS_TIME_H
43# include <sys/time.h>
44# else
45# include <time.h>
46# endif
47#endif
48
49#include "liberty.h"
50
51#include "gg-getopt.h"
52#include "gg_utils.h"
53#include "winsocket.h"
54
55#include "interface.h"
56#include "sgftree.h"
57#include "random.h"
58
59static void show_copyright(void);
60static void show_version(void);
61static void show_help(void);
62static void show_debug_help(void);
63static void show_debug_flags(void);
64
65static void socket_connect_to(const char *host_name, unsigned int port,
66 FILE **input_file, FILE **output_file);
67static void socket_listen_at(const char *host_name, unsigned int port,
68 FILE **input_file, FILE **output_file);
69static void socket_close_connection(FILE *input_file, FILE *output_file);
70static void socket_stop_listening(FILE *input_file, FILE *output_file);
71
72
73/* long options which have no short form */
74enum {OPT_BOARDSIZE = 127,
75 OPT_HANDICAPSTONES,
76 OPT_COLOR,
77 OPT_KOMI,
78 OPT_CLOCK_TIME,
79 OPT_CLOCK_BYO_TIME,
80 OPT_CLOCK_BYO_PERIOD,
81 OPT_AUTOLEVEL,
82 OPT_MODE,
83 OPT_INFILE,
84 OPT_OUTFILE,
85 OPT_QUIET,
86 OPT_GTP_INPUT,
87 OPT_GTP_CONNECT,
88 OPT_GTP_LISTEN,
89 OPT_GTP_DUMP_COMMANDS,
90 OPT_GTP_INITIAL_ORIENTATION,
91 OPT_GTP_VERSION,
92 OPT_SHOWCOPYRIGHT,
93 OPT_REPLAY_GAME,
94 OPT_DECIDE_STRING,
95 OPT_DECIDE_CONNECTION,
96 OPT_DECIDE_OWL,
97 OPT_DECIDE_DRAGON_DATA,
98 OPT_DECIDE_SEMEAI,
99 OPT_DECIDE_SURROUNDED,
100 OPT_DECIDE_TACTICAL_SEMEAI,
101 OPT_DECIDE_ORACLE,
102 OPT_EXPERIMENTAL_SEMEAI,
103 OPT_EXPERIMENTAL_OWL_EXT,
104 OPT_SEMEAI_NODE_LIMIT,
105 OPT_EXPERIMENTAL_CONNECTIONS,
106 OPT_ALTERNATE_CONNECTIONS,
107 OPT_WITH_BREAK_IN,
108 OPT_WITHOUT_BREAK_IN,
109 OPT_COSMIC_GNUGO,
110 OPT_NO_COSMIC_GNUGO,
111 OPT_LARGE_SCALE,
112 OPT_NO_LARGE_SCALE,
113 OPT_OPTIONS,
114 OPT_STANDARD_SEMEAI,
115 OPT_STANDARD_CONNECTIONS,
116 OPT_PRINT_LEVELS,
117 OPT_DECIDE_POSITION,
118 OPT_DECIDE_EYE,
119 OPT_DECIDE_COMBINATION,
120 OPT_BRANCH_DEPTH,
121 OPT_BACKFILL2_DEPTH,
122 OPT_BREAK_CHAIN_DEPTH,
123 OPT_SUPERSTRING_DEPTH,
124 OPT_AA_DEPTH,
125 OPT_DEBUG_FLAGS,
126 OPT_OWL_DISTRUST,
127 OPT_OWL_BRANCH,
128 OPT_OWL_READING,
129 OPT_OWL_NODE_LIMIT,
130 OPT_NOFUSEKIDB,
131 OPT_NOFUSEKI,
132 OPT_NOJOSEKIDB,
133 OPT_LEVEL,
134 OPT_MIN_LEVEL,
135 OPT_MAX_LEVEL,
136 OPT_LIMIT_SEARCH,
137 OPT_SHOWTIME,
138 OPT_SHOWSCORE,
139 OPT_DEBUG_INFLUENCE,
140 OPT_SCORE,
141 OPT_PRINTSGF,
142 OPT_PROFILE_PATTERNS,
143 OPT_CHINESE_RULES,
144 OPT_OWL_THREATS,
145 OPT_NO_OWL_THREATS,
146 OPT_JAPANESE_RULES,
147 OPT_FORBID_SUICIDE,
148 OPT_ALLOW_SUICIDE,
149 OPT_ALLOW_ALL_SUICIDE,
150 OPT_SIMPLE_KO,
151 OPT_NO_KO,
152 OPT_POSITIONAL_SUPERKO,
153 OPT_SITUATIONAL_SUPERKO,
154 OPT_CAPTURE_ALL_DEAD,
155 OPT_PLAY_OUT_AFTERMATH,
156 OPT_MIRROR,
157 OPT_MIRROR_LIMIT,
158 OPT_METAMACHINE,
159 OPT_RESIGN_ALLOWED,
160 OPT_NEVER_RESIGN,
161 OPT_MONTE_CARLO,
162 OPT_MC_GAMES_PER_LEVEL,
163 OPT_MC_PATTERNS,
164 OPT_MC_LIST_PATTERNS,
165 OPT_MC_LOAD_PATTERNS
166};
167
168/* names of playing modes */
169
170enum mode {
171 MODE_UNKNOWN = 0,
172 MODE_ASCII,
173 MODE_GTP,
174 MODE_GMP,
175 MODE_SGMP,
176 MODE_SGF,
177 MODE_LOAD_AND_ANALYZE,
178 MODE_LOAD_AND_SCORE,
179 MODE_LOAD_AND_PRINT,
180 MODE_SOLO,
181 MODE_REPLAY,
182 MODE_DECIDE_STRING,
183 MODE_DECIDE_CONNECTION,
184 MODE_DECIDE_OWL,
185 MODE_DECIDE_DRAGON_DATA,
186 MODE_DECIDE_SEMEAI,
187 MODE_DECIDE_TACTICAL_SEMEAI,
188 MODE_DECIDE_POSITION,
189 MODE_DECIDE_EYE,
190 MODE_DECIDE_COMBINATION,
191 MODE_DECIDE_SURROUNDED,
192 MODE_DECIDE_ORACLE
193};
194
195
196/* Definitions of the --long options. Final column is
197 * either an OPT_ as defined in the enum above, or it
198 * is the equivalent single-letter option.
199 * It is useful to keep them in the same order as the
200 * help string, for maintenance purposes only.
201 */
202
203static struct gg_option const long_options[] =
204{
205 {"mode", required_argument, 0, OPT_MODE},
206 {"replay", required_argument, 0, OPT_REPLAY_GAME},
207 {"quiet", no_argument, 0, OPT_QUIET},
208 {"silent", no_argument, 0, OPT_QUIET},
209 {"gtp-input", required_argument, 0, OPT_GTP_INPUT},
210 {"gtp-connect", required_argument, 0, OPT_GTP_CONNECT},
211 {"gtp-listen", required_argument, 0, OPT_GTP_LISTEN},
212 {"gtp-dump-commands", required_argument, 0, OPT_GTP_DUMP_COMMANDS},
213 {"orientation", required_argument, 0, OPT_GTP_INITIAL_ORIENTATION},
214 {"gtp-initial-orientation",
215 required_argument, 0, OPT_GTP_INITIAL_ORIENTATION},
216 {"gtp-version", required_argument, 0, OPT_GTP_VERSION},
217 {"infile", required_argument, 0, 'l'},
218 {"until", required_argument, 0, 'L'},
219 {"outfile", required_argument, 0, 'o'},
220 {"output-flags", required_argument, 0, 'O'},
221 {"boardsize", required_argument, 0, OPT_BOARDSIZE},
222 {"color", required_argument, 0, OPT_COLOR},
223 {"handicap", required_argument, 0, OPT_HANDICAPSTONES},
224 {"komi", required_argument, 0, OPT_KOMI},
225 {"help", optional_argument, 0, 'h'},
226 {"copyright", no_argument, 0, OPT_SHOWCOPYRIGHT},
227 {"version", no_argument, 0, 'v'},
228 {"allpats", no_argument, 0, 'a'},
229 {"printboard", no_argument, 0, 'T'},
230 {"printeyes", no_argument, 0, 'E'},
231 {"debug", required_argument, 0, 'd'},
232 {"debug-flags", no_argument, 0, OPT_DEBUG_FLAGS},
233 {"depth", required_argument, 0, 'D'},
234 {"backfill-depth", required_argument, 0, 'B'},
235 {"branch-depth", required_argument, 0, OPT_BRANCH_DEPTH},
236 {"backfill2-depth", required_argument, 0, OPT_BACKFILL2_DEPTH},
237 {"break-chain-depth", required_argument, 0, OPT_BREAK_CHAIN_DEPTH},
238 {"superstring-depth", required_argument, 0, OPT_SUPERSTRING_DEPTH},
239 {"fourlib-depth", required_argument, 0, 'F'},
240 {"ko-depth", required_argument, 0, 'K'},
241 {"aa-depth", required_argument, 0, OPT_AA_DEPTH},
242 {"owl-distrust", required_argument, 0, OPT_OWL_DISTRUST},
243 {"owl-branch", required_argument, 0, OPT_OWL_BRANCH},
244 {"owl-reading", required_argument, 0, OPT_OWL_READING},
245 {"owl-node-limit", required_argument, 0, OPT_OWL_NODE_LIMIT},
246 {"print-levels", no_argument, 0, OPT_PRINT_LEVELS},
247 {"level", required_argument, 0, OPT_LEVEL},
248 {"min-level", required_argument, 0, OPT_MIN_LEVEL},
249 {"max-level", required_argument, 0, OPT_MAX_LEVEL},
250 {"limit-search", required_argument, 0, OPT_LIMIT_SEARCH},
251 {"clock", required_argument, 0, OPT_CLOCK_TIME},
252 {"byo-time", required_argument, 0, OPT_CLOCK_BYO_TIME},
253 {"byo-period", required_argument, 0, OPT_CLOCK_BYO_PERIOD},
254 {"autolevel", no_argument, 0, OPT_AUTOLEVEL},
255 {"chinese-rules", no_argument, 0, OPT_CHINESE_RULES},
256 {"japanese-rules", no_argument, 0, OPT_JAPANESE_RULES},
257 {"experimental-semeai", no_argument, 0, OPT_EXPERIMENTAL_SEMEAI},
258 {"experimental-owl-ext", no_argument, 0, OPT_EXPERIMENTAL_OWL_EXT},
259 {"semeai-node-limit", required_argument, 0, OPT_SEMEAI_NODE_LIMIT},
260 {"experimental-connections", no_argument, 0, OPT_EXPERIMENTAL_CONNECTIONS},
261 {"standard-connections", no_argument, 0, OPT_STANDARD_CONNECTIONS},
262 {"standard-semeai", no_argument, 0, OPT_STANDARD_SEMEAI},
263 {"alternate-connections", no_argument, 0, OPT_ALTERNATE_CONNECTIONS},
264 {"with-break-in", no_argument, 0, OPT_WITH_BREAK_IN},
265 {"without-break-in", no_argument, 0, OPT_WITHOUT_BREAK_IN},
266 {"cosmic-gnugo", no_argument, 0, OPT_COSMIC_GNUGO},
267 {"no-cosmic-gnugo", no_argument, 0, OPT_NO_COSMIC_GNUGO},
268 {"large-scale", no_argument, 0, OPT_LARGE_SCALE},
269 {"no-large-scale", no_argument, 0, OPT_NO_LARGE_SCALE},
270 {"options", no_argument, 0, OPT_OPTIONS},
271 {"forbid-suicide", no_argument, 0, OPT_FORBID_SUICIDE},
272 {"allow-suicide", no_argument, 0, OPT_ALLOW_SUICIDE},
273 {"allow-all-suicide", no_argument, 0, OPT_ALLOW_ALL_SUICIDE},
274 {"simple-ko", no_argument, 0, OPT_SIMPLE_KO},
275 {"no-ko", no_argument, 0, OPT_NO_KO},
276 {"positional-superko", no_argument, 0, OPT_POSITIONAL_SUPERKO},
277 {"situational-superko", no_argument, 0, OPT_SITUATIONAL_SUPERKO},
278 {"capture-all-dead", no_argument, 0, OPT_CAPTURE_ALL_DEAD},
279 {"play-out-aftermath", no_argument, 0, OPT_PLAY_OUT_AFTERMATH},
280 {"cache-size", required_argument, 0, 'M'},
281 {"worms", no_argument, 0, 'w'},
282 {"moyo", required_argument, 0, 'm'},
283 {"benchmark", required_argument, 0, 'b'},
284 {"statistics", no_argument, 0, 'S'},
285 {"trace", no_argument, 0, 't'},
286 {"seed", required_argument, 0, 'r'},
287 {"decide-string", required_argument, 0, OPT_DECIDE_STRING},
288 {"decide-connection", required_argument, 0, OPT_DECIDE_CONNECTION},
289 {"decide-dragon", required_argument, 0, OPT_DECIDE_OWL},
290 {"decide-owl", required_argument, 0, OPT_DECIDE_OWL},
291 {"decide-dragon-data", required_argument, 0, OPT_DECIDE_DRAGON_DATA},
292 {"decide-semeai", required_argument, 0, OPT_DECIDE_SEMEAI},
293 {"decide-tactical-semeai", required_argument, 0, OPT_DECIDE_TACTICAL_SEMEAI},
294 {"decide-position", no_argument, 0, OPT_DECIDE_POSITION},
295 {"decide-surrounded", required_argument, 0, OPT_DECIDE_SURROUNDED},
296 {"decide-eye", required_argument, 0, OPT_DECIDE_EYE},
297 {"decide-combination", no_argument, 0, OPT_DECIDE_COMBINATION},
298 {"decide-oracle", no_argument, 0, OPT_DECIDE_ORACLE},
299 {"nofusekidb", no_argument, 0, OPT_NOFUSEKIDB},
300 {"nofuseki", no_argument, 0, OPT_NOFUSEKI},
301 {"nojosekidb", no_argument, 0, OPT_NOJOSEKIDB},
302 {"debug-influence", required_argument, 0, OPT_DEBUG_INFLUENCE},
303 {"showtime", no_argument, 0, OPT_SHOWTIME},
304 {"showscore", no_argument, 0, OPT_SHOWSCORE},
305 {"score", required_argument, 0, OPT_SCORE},
306 {"printsgf", required_argument, 0, OPT_PRINTSGF},
307 {"profile-patterns", no_argument, 0, OPT_PROFILE_PATTERNS},
308 {"mirror", no_argument, 0, OPT_MIRROR},
309 {"mirror-limit", required_argument, 0, OPT_MIRROR_LIMIT},
310 {"metamachine", no_argument, 0, OPT_METAMACHINE},
311 {"resign-allowed", no_argument, 0, OPT_RESIGN_ALLOWED},
312 {"never-resign", no_argument, 0, OPT_NEVER_RESIGN},
313 {"monte-carlo", no_argument, 0, OPT_MONTE_CARLO},
314 {"mc-games-per-level", required_argument, 0, OPT_MC_GAMES_PER_LEVEL},
315 {"mc-patterns", required_argument, 0, OPT_MC_PATTERNS},
316 {"mc-list-patterns", no_argument, 0, OPT_MC_LIST_PATTERNS},
317 {"mc-load-patterns", required_argument, 0, OPT_MC_LOAD_PATTERNS},
318 {NULL, 0, NULL, 0}
319};
320
321
322int
323main(int argc, char *argv[])
324{
325 Gameinfo gameinfo;
326 SGFTree sgftree;
327
328 int i;
329 int mandated_color = EMPTY;
330 enum mode playmode = MODE_UNKNOWN;
331 int replay_color = EMPTY;
332
333 char *infilename = NULL;
334 char *untilstring = NULL;
335 char *scoringmode = NULL;
336 char *outfile = NULL;
337 char *outflags = NULL;
338 char *gtpfile = NULL;
339 char *gtp_dump_commands_file = NULL;
340 int gtp_tcp_ip_mode = 0;
341 char *gtp_tcp_ip_address = NULL;
342
343 char *printsgffile = NULL;
344
345 char decide_this[8];
346 char *decide_that = NULL;
347 char debuginfluence_move[4] = "\0";
348
349 int benchmark = 0; /* benchmarking mode (-b) */
350 FILE *output_check;
351 int orientation = 0;
352
353 char mc_pattern_name[40] = "";
354 char mc_pattern_filename[320] = "";
355
356 float memory = (float) DEFAULT_MEMORY; /* Megabytes used for hash table. */
357
358 /* If seed is zero, GNU Go will play a different game each time. If
359 * it is set using -r, GNU Go will play the same game each time.
360 * (Change seed to get a different game).
361 */
362 int seed = 0;
363 int seed_specified = 0;
364
365 int requested_boardsize = -1;
366
367 sgftree_clear(&sgftree);
368 gameinfo_clear(&gameinfo);
369
370 /* Weed through all of the command line options. */
371 while ((i = gg_getopt_long(argc, argv,
372 "-ab:B:d:D:EF:gh::K:l:L:M:m:o:O:p:r:fsStTvw",
373 long_options, NULL)) != EOF)
374 {
375 switch (i) {
376 case 'T': printboard++; break;
377 case 't': ++verbose; break;
378 case 'a': allpats = 1; break;
379
380 case 1 :
381 case 'l': infilename = gg_optarg;
382 break;
383
384 case 'b': benchmark = atoi(gg_optarg); playmode = MODE_SOLO; break;
385 case 'r': seed = atoi(gg_optarg); seed_specified = 1; break;
386 case 'S': showstatistics = 1; break;
387 case 'w': printworms = 1; break;
388 case 'm': printmoyo = strtol(gg_optarg, NULL, 0); /* allows 0x... */
389 break;
390 case 'd': debug ^= strtol(gg_optarg, NULL, 0); /* allows 0x... */ break;
391 case 'D': mandated_depth = atoi(gg_optarg); break;
392 case 'M': memory = atof(gg_optarg); break; /* floating point number */
393 case 'E': printboard = 2; break;
394 case 'B': mandated_backfill_depth = atoi(gg_optarg); break;
395 case 'F': mandated_fourlib_depth = atoi(gg_optarg); break;
396 case 'K': mandated_ko_depth = atoi(gg_optarg); break;
397
398 case 'L':
399 untilstring = gg_optarg;
400 break;
401
402 case 'o':
403 if (strlen(gg_optarg) >= sizeof(outfilename)) {
404 fprintf(stderr, "Too long filename given as value to -o option.\n");
405 exit(EXIT_FAILURE);
406 }
407 outfile = gg_optarg;
408 strcpy(outfilename, gg_optarg);
409 break;
410
411 case 'O':
412 outflags = gg_optarg;
413 output_flags = 0;
414 if (outflags)
415 while (*outflags) {
416 switch (*outflags) {
417 case 'd':
418 output_flags |= OUTPUT_MARKDRAGONS;
419 break;
420 case 'v':
421 output_flags |= OUTPUT_MOVEVALUES;
422 break;
423 }
424 outflags++;
425 }
426 break;
427
428 case OPT_QUIET:
429 quiet = 1;
430 break;
431
432 case OPT_GTP_INPUT:
433 case OPT_GTP_CONNECT:
434 case OPT_GTP_LISTEN:
435 if (gtp_tcp_ip_mode != 0 || gtpfile != NULL) {
436 fprintf(stderr, ("Options `--gtp-input', `--gtp-connect' and `--gtp-listen' "
437 "are mutually-exclusive\n"));
438 exit(EXIT_FAILURE);
439 }
440
441 if (i == OPT_GTP_INPUT)
442 gtpfile = gg_optarg;
443 else {
444 gtp_tcp_ip_mode = i;
445 gtp_tcp_ip_address = gg_optarg;
446 }
447
448 break;
449
450 case OPT_GTP_DUMP_COMMANDS:
451 gtp_dump_commands_file = gg_optarg;
452 break;
453
454 case OPT_GTP_INITIAL_ORIENTATION:
455 orientation = atoi(gg_optarg);
456 if (orientation < 0 || orientation > 7) {
457 fprintf(stderr, "Invalid orientation: %d.\n", orientation);
458 fprintf(stderr, "Try `gnugo --help' for more information.\n");
459 exit(EXIT_FAILURE);
460 }
461 break;
462
463 case OPT_GTP_VERSION:
464 gtp_version = atoi(gg_optarg);
465 break;
466
467 case OPT_OPTIONS:
468 if (USE_BREAK_IN)
469 fprintf(stdout,
470 "configure option enabled: experimental break-ins\n");
471 if (COSMIC_GNUGO)
472 fprintf(stdout,
473 "configure option enabled: cosmic GNU Go \n");
474 if (LARGE_SCALE)
475 fprintf(stdout,
476 "configure option enabled: large scale captures \n");
477 if (EXPERIMENTAL_CONNECTIONS)
478 fprintf(stdout,
479 "configure option enabled: experimental connections\n");
480 if (ALTERNATE_CONNECTIONS)
481 fprintf(stdout,
482 "configure option enabled: alternate connections\n");
483 if (EXPERIMENTAL_OWL_EXT)
484 fprintf(stdout,
485 "configure option enabled: experimental GAIN/LOSS codes\n");
486 if (OWL_THREATS)
487 fprintf(stdout,
488 "configure option enabled: owl threats\n");
489 if (RESIGNATION_ALLOWED)
490 fprintf(stdout,
491 "configure option enabled: resignation allowed\n");
492 if (ORACLE)
493 fprintf(stdout,
494 "configure option enabled: oracle\n");
495 fprintf(stdout,
496 "Owl node limit: %d\n", OWL_NODE_LIMIT);
497 fprintf(stdout,
498 "Semeai node limit: %d\n", SEMEAI_NODE_LIMIT);
499 if (DEFAULT_MEMORY == -1)
500 fprintf(stdout, "Cache size: %d MB (special default value)\n",
501 DEFAULT_MEMORY);
502 else
503 fprintf(stdout, "Cache size: %d MB\n", DEFAULT_MEMORY);
504
505 return EXIT_SUCCESS;
506 break;
507
508 case OPT_SHOWTIME:
509 showtime = 1;
510 break;
511
512 case OPT_SHOWSCORE:
513 showscore = 1;
514 break;
515
516 case OPT_HANDICAPSTONES:
517 {
518 int requested_handicap = atoi(gg_optarg);
519
520 if (requested_handicap < 0 || requested_handicap > MAX_HANDICAP) {
521 fprintf(stderr, "Unsupported handicap: %d.\n", requested_handicap);
522 fprintf(stderr, "Try `gnugo --help' for more information.\n");
523 exit(EXIT_FAILURE);
524 }
525 gameinfo.handicap = requested_handicap;
526 }
527 break;
528
529 case OPT_BOARDSIZE:
530 requested_boardsize = atoi(gg_optarg);
531 break;
532
533 case OPT_KOMI:
534 if (sscanf(gg_optarg, "%f", &komi) != 1) {
535 fprintf(stderr, "Invalid komi selection: %s\n", gg_optarg);
536 fprintf(stderr, "Try `gnugo --help' for more information.\n");
537 exit(EXIT_FAILURE);
538 }
539 break;
540
541 case OPT_CHINESE_RULES:
542 chinese_rules = 1;
543 break;
544
545 case OPT_OWL_THREATS:
546 owl_threats = 1;
547 break;
548
549 case OPT_NO_OWL_THREATS:
550 owl_threats = 0;
551 break;
552
553 case OPT_METAMACHINE:
554 metamachine = 1;
555 break;
556
557 case OPT_JAPANESE_RULES:
558 chinese_rules = 0;
559 break;
560
561 case OPT_EXPERIMENTAL_OWL_EXT:
562 experimental_owl_ext = 1;
563 break;
564
565 case OPT_SEMEAI_NODE_LIMIT:
566 mandated_semeai_node_limit = atoi(gg_optarg);
567 break;
568
569 case OPT_EXPERIMENTAL_CONNECTIONS:
570 experimental_connections = 1;
571 break;
572
573 case OPT_STANDARD_CONNECTIONS:
574 experimental_connections = 0;
575 break;
576
577 case OPT_ALTERNATE_CONNECTIONS:
578 alternate_connections = !alternate_connections;
579 break;
580
581 case OPT_WITH_BREAK_IN:
582 experimental_break_in = 1;
583 break;
584
585 case OPT_WITHOUT_BREAK_IN:
586 experimental_break_in = 0;
587 break;
588
589 case OPT_COSMIC_GNUGO:
590 cosmic_gnugo = 1;
591 break;
592
593 case OPT_NO_COSMIC_GNUGO:
594 cosmic_gnugo = 0;
595 break;
596
597 case OPT_LARGE_SCALE:
598 large_scale = 1;
599 break;
600
601 case OPT_NO_LARGE_SCALE:
602 large_scale = 0;
603 break;
604
605 case OPT_FORBID_SUICIDE:
606 suicide_rule = FORBIDDEN;
607 break;
608
609 case OPT_ALLOW_SUICIDE:
610 suicide_rule = ALLOWED;
611 break;
612
613 case OPT_ALLOW_ALL_SUICIDE:
614 suicide_rule = ALL_ALLOWED;
615 break;
616
617 case OPT_SIMPLE_KO:
618 ko_rule = SIMPLE;
619 break;
620
621 case OPT_NO_KO:
622 ko_rule = NONE;
623 break;
624
625 case OPT_POSITIONAL_SUPERKO:
626 ko_rule = PSK;
627 break;
628
629 case OPT_SITUATIONAL_SUPERKO:
630 ko_rule = SSK;
631 break;
632
633 case OPT_CAPTURE_ALL_DEAD:
634 capture_all_dead = 1;
635 break;
636
637 case OPT_PLAY_OUT_AFTERMATH:
638 play_out_aftermath = 1;
639 break;
640
641 case OPT_RESIGN_ALLOWED:
642 resign_allowed = 1;
643 break;
644
645 case OPT_NEVER_RESIGN:
646 resign_allowed = 0;
647 break;
648
649 case OPT_MONTE_CARLO:
650 use_monte_carlo_genmove = 1;
651 break;
652
653 case OPT_MC_GAMES_PER_LEVEL:
654 mc_games_per_level = atoi(gg_optarg);
655 break;
656
657 case OPT_MC_PATTERNS:
658 if (strlen(gg_optarg) >= sizeof(mc_pattern_name)) {
659 fprintf(stderr, "Too long name given as value to --mc-patterns option.\n");
660 exit(EXIT_FAILURE);
661 }
662 strcpy(mc_pattern_name, gg_optarg);
663 break;
664
665 case OPT_MC_LIST_PATTERNS:
666 list_mc_patterns();
667 return EXIT_SUCCESS;
668 break;
669
670 case OPT_MC_LOAD_PATTERNS:
671 if (strlen(gg_optarg) >= sizeof(mc_pattern_filename)) {
672 fprintf(stderr, "Too long name given as value to --mc-load-patterns option.\n");
673 exit(EXIT_FAILURE);
674 }
675 strcpy(mc_pattern_filename, gg_optarg);
676 break;
677
678 case OPT_MODE:
679 if (strcmp(gg_optarg, "ascii") == 0)
680 playmode = MODE_ASCII;
681 else if (strcmp(gg_optarg, "gtp") == 0)
682 playmode = MODE_GTP;
683 else if (strcmp(gg_optarg, "gmp") == 0)
684 playmode = MODE_GMP;
685 else if (strcmp(gg_optarg, "sgmp") == 0)
686 playmode = MODE_SGMP;
687 else {
688 fprintf(stderr, "Invalid mode selection: %s\n", gg_optarg);
689 fprintf(stderr, "Try `gnugo --help' for more information.\n");
690
691 exit(EXIT_FAILURE);
692 }
693 break;
694
695 case OPT_DECIDE_STRING:
696 if (strlen(gg_optarg) > 3) {
697 fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg);
698 exit(EXIT_FAILURE);
699 }
700 strcpy(decide_this, gg_optarg);
701 playmode = MODE_DECIDE_STRING;
702 break;
703
704 case OPT_DECIDE_CONNECTION:
705 if (strlen(gg_optarg) > 7) {
706 fprintf(stderr,
707 "usage: --decide-connection [first string]/[second string]\n");
708 return EXIT_FAILURE;
709 }
710 strcpy(decide_this, gg_optarg);
711 strtok(decide_this, "/");
712 decide_that = strtok(NULL, "/");
713 if (!decide_that) {
714 fprintf(stderr,
715 "usage: --decide-connection [first string]/[second string]\n");
716 return EXIT_FAILURE;
717 }
718
719 playmode = MODE_DECIDE_CONNECTION;
720 break;
721
722 case OPT_DECIDE_OWL:
723 if (strlen(gg_optarg) > 3) {
724 fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg);
725 exit(EXIT_FAILURE);
726 }
727 strcpy(decide_this, gg_optarg);
728 playmode = MODE_DECIDE_OWL;
729 break;
730
731 case OPT_DECIDE_DRAGON_DATA:
732 if (strlen(gg_optarg) > 3) {
733 fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg);
734 exit(EXIT_FAILURE);
735 }
736 strcpy(decide_this, gg_optarg);
737 playmode = MODE_DECIDE_DRAGON_DATA;
738 break;
739
740 case OPT_DECIDE_SEMEAI:
741 if (strlen(gg_optarg) > 7) {
742 fprintf(stderr,
743 "usage: --decide-semeai [first dragon]/[second dragon]\n");
744 return EXIT_FAILURE;
745 }
746 strcpy(decide_this, gg_optarg);
747 strtok(decide_this, "/");
748 decide_that = strtok(NULL, "/");
749 if (!decide_that) {
750 fprintf(stderr,
751 "usage: --decide-semeai [first dragon]/[second dragon]\n");
752 return EXIT_FAILURE;
753 }
754
755 playmode = MODE_DECIDE_SEMEAI;
756 break;
757
758 case OPT_DECIDE_TACTICAL_SEMEAI:
759 if (strlen(gg_optarg) > 7) {
760 fprintf(stderr,
761 "usage: --decide-tactical-semeai [first dragon]/[second dragon]\n");
762 return EXIT_FAILURE;
763 }
764 strcpy(decide_this, gg_optarg);
765 strtok(decide_this, "/");
766 decide_that = strtok(NULL, "/");
767 if (!decide_that) {
768 fprintf(stderr,
769 "usage: --decide-tactical-semeai [first dragon]/[second dragon]\n");
770 return EXIT_FAILURE;
771 }
772 playmode = MODE_DECIDE_TACTICAL_SEMEAI;
773 break;
774
775 case OPT_DECIDE_POSITION:
776 playmode = MODE_DECIDE_POSITION;
777 break;
778
779 case OPT_DECIDE_EYE:
780 if (strlen(gg_optarg) > 3) {
781 fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg);
782 exit(EXIT_FAILURE);
783 }
784 strcpy(decide_this, gg_optarg);
785 playmode = MODE_DECIDE_EYE;
786 break;
787
788 case OPT_DECIDE_COMBINATION:
789 playmode = MODE_DECIDE_COMBINATION;
790 break;
791
792 case OPT_DECIDE_SURROUNDED:
793 if (strlen(gg_optarg) > 3) {
794 fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg);
795 exit(EXIT_FAILURE);
796 }
797 strcpy(decide_this, gg_optarg);
798 playmode = MODE_DECIDE_SURROUNDED;
799 break;
800
801 case OPT_DECIDE_ORACLE:
802 playmode = MODE_DECIDE_ORACLE;
803 break;
804
805 case OPT_BRANCH_DEPTH:
806 mandated_branch_depth = atoi(gg_optarg);
807 break;
808
809 case OPT_BACKFILL2_DEPTH:
810 mandated_backfill2_depth = atoi(gg_optarg);
811 break;
812
813 case OPT_BREAK_CHAIN_DEPTH:
814 mandated_break_chain_depth = atoi(gg_optarg);
815 break;
816
817 case OPT_SUPERSTRING_DEPTH:
818 mandated_superstring_depth = atoi(gg_optarg);
819 break;
820
821 case OPT_AA_DEPTH:
822 mandated_aa_depth = atoi(gg_optarg);
823 break;
824
825 case OPT_OWL_DISTRUST:
826 mandated_owl_distrust_depth = atoi(gg_optarg);
827 break;
828
829 case OPT_OWL_BRANCH:
830 mandated_owl_branch_depth = atoi(gg_optarg);
831 break;
832
833 case OPT_OWL_READING:
834 mandated_owl_reading_depth = atoi(gg_optarg);
835 break;
836
837 case OPT_OWL_NODE_LIMIT:
838 mandated_owl_node_limit = atoi(gg_optarg);
839 break;
840
841 case OPT_NOFUSEKIDB:
842 fusekidb = 0;
843 break;
844
845 case OPT_NOFUSEKI:
846 disable_fuseki = 1;
847 break;
848
849 case OPT_NOJOSEKIDB:
850 josekidb = 0;
851 break;
852
853 case OPT_LEVEL:
854 set_level(atoi(gg_optarg));
855 break;
856
857 case OPT_MIN_LEVEL:
858 set_min_level(atoi(gg_optarg));
859 break;
860
861 case OPT_MAX_LEVEL:
862 set_max_level(atoi(gg_optarg));
863 break;
864
865 case OPT_LIMIT_SEARCH:
866 {
867 int pos = string_to_location(board_size, gg_optarg);
868 if (pos == NO_MOVE) {
869 fprintf(stderr, "gnugo: use --limit-search <pos>\n");
870 return EXIT_FAILURE;
871 }
872 set_search_diamond(pos);
873 }
874 break;
875
876 case OPT_CLOCK_TIME:
877 clock_settings(atoi(gg_optarg), -1, -1);
878 break;
879
880 case OPT_CLOCK_BYO_TIME:
881 clock_settings(-1, atoi(gg_optarg), -1);
882 break;
883
884 case OPT_CLOCK_BYO_PERIOD:
885 clock_settings(-1, -1, atoi(gg_optarg));
886 break;
887
888 case OPT_AUTOLEVEL:
889 autolevel_on = 1;
890 break;
891
892 case OPT_DEBUG_INFLUENCE:
893 if (strlen(gg_optarg) > 3) {
894 fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg);
895 exit(EXIT_FAILURE);
896 }
897 strcpy(debuginfluence_move, gg_optarg);
898 break;
899
900 case OPT_REPLAY_GAME:
901 playmode = MODE_REPLAY;
902 if (strcmp(gg_optarg, "white") == 0)
903 replay_color = WHITE;
904 else if (strcmp(gg_optarg, "black") == 0)
905 replay_color = BLACK;
906 else if (strcmp(gg_optarg, "both") == 0)
907 replay_color = GRAY;
908 else {
909 fprintf(stderr, "Invalid replay color: %s\n", gg_optarg);
910 fprintf(stderr, "Try `gnugo --help' for more information.\n");
911 exit(EXIT_FAILURE);
912 }
913 break;
914
915 case OPT_SCORE:
916 scoringmode = gg_optarg;
917 if (playmode == MODE_UNKNOWN)
918 playmode = MODE_LOAD_AND_SCORE;
919 break;
920
921 case OPT_PRINTSGF:
922 playmode = MODE_LOAD_AND_PRINT;
923 printsgffile = gg_optarg;
924 break;
925
926 case OPT_PROFILE_PATTERNS:
927 profile_patterns = 1;
928 prepare_pattern_profiling();
929 break;
930
931 case OPT_COLOR:
932 if (strcmp(gg_optarg, "white") == 0)
933 mandated_color = WHITE;
934 else if (strcmp(gg_optarg, "black") == 0)
935 mandated_color = BLACK;
936 else {
937 fprintf(stderr, "Invalid color selection: %s\n", gg_optarg);
938 fprintf(stderr, "Try `gnugo --help' for more information.\n");
939 exit(EXIT_FAILURE);
940 }
941 break;
942
943 case OPT_SHOWCOPYRIGHT:
944 show_copyright();
945 return EXIT_SUCCESS;
946 break;
947
948 case OPT_MIRROR:
949 play_mirror_go = 1;
950 break;
951
952 case OPT_MIRROR_LIMIT:
953 mirror_stones_limit = atoi(gg_optarg);
954 break;
955
956 case 'v':
957 show_version();
958 show_copyright();
959 return EXIT_SUCCESS;
960 break;
961
962 case 'h':
963 show_version();
964 if (gg_optarg) {
965 /* In the default behavior of getopt_long with optional args
966 * you need to type "-hdebug"
967 * I can't get long options "--helpdebug" to work at all
968 */
969 if (strncmp(gg_optarg, "debug", 5) == 0)
970 show_debug_help();
971 }
972 else {
973 /* This is the trick to get "--help debug" and "-h debug" to work*/
974 if (gg_optind < argc) {
975 if (strncmp(argv[gg_optind], "debug", 5) == 0)
976 show_debug_help();
977 }
978 else
979 show_help();
980 }
981 return EXIT_SUCCESS;
982 break;
983
984 case OPT_DEBUG_FLAGS:
985 show_debug_flags();
986 return EXIT_SUCCESS;
987 break;
988
989 case OPT_PRINT_LEVELS:
990 {
991 int lev;
992 for (lev = 12; lev >= 0; lev--)
993 set_depth_values(lev, 1);
994 }
995 return EXIT_SUCCESS;
996 break;
997
998 /* NOTE: getopt returns '?' if an illegal option is supplied. */
999
1000 case '?':
1001 default:
1002 fprintf(stderr, "Try `gnugo --help' for more information.\n");
1003 exit(EXIT_FAILURE);
1004 }
1005 }
1006
1007 if (requested_boardsize != -1) {
1008 if (!check_boardsize(requested_boardsize, stderr))
1009 exit(EXIT_FAILURE);
1010 gnugo_clear_board(requested_boardsize);
1011 }
1012
1013 /* Start random number seed. */
1014 if (!seed_specified)
1015 seed = time(0);
1016
1017 /* Initialize the GNU Go engine. */
1018 init_gnugo(memory, seed);
1019
1020 /* Load Monte Carlo patterns if one has been specified. Either
1021 * choose one of the compiled in ones or load directly from a
1022 * database file.
1023 */
1024 if (strlen(mc_pattern_filename) > 0) {
1025 if (!mc_load_patterns_from_db(mc_pattern_filename, NULL))
1026 return EXIT_FAILURE;
1027 }
1028 else if (strlen(mc_pattern_name) > 0) {
1029 if (!choose_mc_patterns(mc_pattern_name)) {
1030 fprintf(stderr, "Unknown Monte Carlo pattern database name %s.\n",
1031 mc_pattern_name);
1032 fprintf(stderr, "Use \"--mc-list-patterns\" to list the available databases.\n");
1033 return EXIT_FAILURE;
1034 }
1035 }
1036
1037 /* Read the infile if there is one. Also play up the position. */
1038 if (infilename) {
1039 if (!sgftree_readfile(&sgftree, infilename)) {
1040 fprintf(stderr, "Cannot open or parse '%s'\n", infilename);
1041 exit(EXIT_FAILURE);
1042 }
1043
1044 if (gameinfo_play_sgftree_rot(&gameinfo, &sgftree, untilstring,
1045 orientation) == EMPTY) {
1046 fprintf(stderr, "Cannot load '%s'\n", infilename);
1047 exit(EXIT_FAILURE);
1048 }
1049 }
1050 else
1051 /* Initialize and empty sgf tree if there was no infile. */
1052 sgftreeCreateHeaderNode(&sgftree, board_size, komi, handicap);
1053
1054 /* Set the game_record to be identical to the loaded one or the
1055 * newly created empty sgf tree.
1056 */
1057 gameinfo.game_record = sgftree;
1058
1059 /* Notice that we need to know the board size before we can do this.
1060 */
1061 if (debuginfluence_move[0]) {
1062 int pos = string_to_location(board_size, debuginfluence_move);
1063 debug_influence_move(pos);
1064 }
1065
1066 /* Figure out a default mode if there was no explicit one. */
1067 if (playmode == MODE_UNKNOWN) {
1068 if (infilename)
1069 playmode = MODE_LOAD_AND_ANALYZE;
1070 else
1071 playmode = (isatty(0)) ? MODE_ASCII : MODE_GMP;
1072 }
1073
1074 if (outfile && playmode != MODE_LOAD_AND_PRINT) {
1075 output_check = fopen(outfile, "w");
1076 if (!output_check) {
1077 fprintf(stderr, "Error: could not open '%s' for writing\n", outfile);
1078 exit(EXIT_FAILURE);
1079 }
1080 fclose(output_check);
1081 }
1082
1083 switch (playmode) {
1084 case MODE_GMP:
1085 case MODE_SGMP:
1086
1087 /* not supported by the protocol */
1088 resign_allowed = 0;
1089
1090#if ORACLE
1091 if (metamachine)
1092 summon_oracle();
1093#endif
1094
1095 /* EMPTY is valid for play_gmp.c. */
1096 gameinfo.computer_player = mandated_color;
1097 play_gmp(&gameinfo, playmode == MODE_SGMP);
1098
1099#if ORACLE
1100 if (metamachine)
1101 dismiss_oracle();
1102#endif
1103
1104 break;
1105
1106 case MODE_SOLO:
1107 play_solo(&gameinfo, benchmark);
1108 break;
1109
1110 case MODE_REPLAY:
1111 if (!infilename) {
1112 fprintf(stderr, "You must use -l infile with replay mode.\n");
1113 exit(EXIT_FAILURE);
1114 }
1115 play_replay(&sgftree, replay_color);
1116 break;
1117
1118 case MODE_LOAD_AND_ANALYZE:
1119 if (mandated_color != EMPTY)
1120 gameinfo.to_move = mandated_color;
1121
1122 if (!infilename) {
1123 fprintf(stderr, "You must use -l infile with load and analyze mode.\n");
1124 exit(EXIT_FAILURE);
1125 }
1126
1127#if ORACLE
1128 if (metamachine) {
1129 summon_oracle();
1130 oracle_loadsgf(infilename, untilstring);
1131 }
1132#endif
1133
1134 load_and_analyze_sgf_file(&gameinfo);
1135
1136#if ORACLE
1137 dismiss_oracle();
1138#endif
1139
1140 break;
1141
1142 case MODE_LOAD_AND_SCORE:
1143 if (mandated_color != EMPTY)
1144 gameinfo.to_move = mandated_color;
1145
1146 if (!infilename) {
1147 fprintf(stderr, "gnugo: --score must be used with -l\n");
1148 exit(EXIT_FAILURE);
1149 }
1150 load_and_score_sgf_file(&sgftree, &gameinfo, scoringmode);
1151 break;
1152
1153 case MODE_LOAD_AND_PRINT:
1154 if (!infilename) {
1155 fprintf(stderr, "gnugo: --printsgf must be used with -l\n");
1156 exit(EXIT_FAILURE);
1157 }
1158
1159 else {
1160 if (mandated_color != EMPTY)
1161 gameinfo.to_move = mandated_color;
1162
1163 sgffile_printsgf(gameinfo.to_move, printsgffile);
1164 }
1165 break;
1166
1167 case MODE_DECIDE_STRING:
1168 {
1169 int str;
1170
1171 if (!infilename) {
1172 fprintf(stderr, "gnugo: --decide-string must be used with -l\n");
1173 return EXIT_FAILURE;
1174 }
1175
1176 str = string_to_location(board_size, decide_this);
1177 if (str == NO_MOVE) {
1178 fprintf(stderr, "gnugo: --decide-string: strange coordinate \n");
1179 return EXIT_FAILURE;
1180 }
1181
1182 decide_string(str);
1183 }
1184 break;
1185
1186 case MODE_DECIDE_CONNECTION:
1187 {
1188 int str1, str2;
1189
1190 if (!infilename) {
1191 fprintf(stderr, "gnugo: --decide-connection must be used with -l\n");
1192 return EXIT_FAILURE;
1193 }
1194
1195 str1 = string_to_location(board_size, decide_this);
1196 if (str1 == NO_MOVE) {
1197 fprintf(stderr,
1198 "usage: --decide-connection [first string]/[second string]\n");
1199 return EXIT_FAILURE;
1200 }
1201
1202 str2 = string_to_location(board_size, decide_that);
1203 if (str2 == NO_MOVE) {
1204 fprintf(stderr,
1205 "usage: --decide-connection [first string]/[second string]\n");
1206 return EXIT_FAILURE;
1207 }
1208
1209 decide_connection(str1, str2);
1210 }
1211 break;
1212
1213 case MODE_DECIDE_OWL:
1214 {
1215 int pos;
1216
1217 if (!infilename) {
1218 fprintf(stderr, "gnugo: --decide-dragon must be used with -l\n");
1219 return EXIT_FAILURE;
1220 }
1221
1222 pos = string_to_location(board_size, decide_this);
1223 if (pos == NO_MOVE) {
1224 fprintf(stderr, "gnugo: --decide-dragon: strange coordinate \n");
1225 return EXIT_FAILURE;
1226 }
1227
1228 decide_owl(pos);
1229 }
1230 break;
1231
1232 case MODE_DECIDE_DRAGON_DATA:
1233 {
1234 int pos;
1235
1236 if (!infilename) {
1237 fprintf(stderr, "gnugo: --decide-dragon-data must be used with -l\n");
1238 return EXIT_FAILURE;
1239 }
1240
1241 pos = string_to_location(board_size, decide_this);
1242 if (pos == NO_MOVE) {
1243 fprintf(stderr, "gnugo: --decide-dragon-data: strange coordinate \n");
1244 return EXIT_FAILURE;
1245 }
1246
1247 decide_dragon_data(pos);
1248 }
1249 break;
1250
1251 case MODE_DECIDE_SEMEAI:
1252 {
1253 int pos1, pos2;
1254
1255 if (!infilename) {
1256 fprintf(stderr, "gnugo: --decide-semeai must be used with -l\n");
1257 return EXIT_FAILURE;
1258 }
1259
1260 pos1 = string_to_location(board_size, decide_this);
1261 if (pos1 == NO_MOVE) {
1262 fprintf(stderr,
1263 "usage: --decide-semeai [first dragon]/[second dragon]\n");
1264 return EXIT_FAILURE;
1265 }
1266
1267 pos2 = string_to_location(board_size, decide_that);
1268 if (pos2 == NO_MOVE) {
1269 fprintf(stderr,
1270 "usage: --decide-semeai [first dragon]/[second dragon]\n");
1271 return EXIT_FAILURE;
1272 }
1273
1274 decide_semeai(pos1, pos2);
1275 }
1276 break;
1277
1278
1279 case MODE_DECIDE_TACTICAL_SEMEAI:
1280 {
1281 int pos1, pos2;
1282
1283 if (!infilename) {
1284 fprintf(stderr, "gnugo: --decide-tactical-semeai must be used with -l\n");
1285 return EXIT_FAILURE;
1286 }
1287
1288 pos1 = string_to_location(board_size, decide_this);
1289 if (pos1 == NO_MOVE) {
1290 fprintf(stderr,
1291 "usage: --decide-tactical-semeai [first dragon]/[second dragon]\n");
1292 return EXIT_FAILURE;
1293 }
1294
1295 pos2 = string_to_location(board_size, decide_that);
1296 if (pos2 == NO_MOVE) {
1297 fprintf(stderr,
1298 "usage: --decide-tactical-semeai [first dragon]/[second dragon]\n");
1299 return EXIT_FAILURE;
1300 }
1301
1302 decide_tactical_semeai(pos1, pos2);
1303 }
1304 break;
1305
1306
1307 case MODE_DECIDE_POSITION:
1308 {
1309 if (!infilename) {
1310 fprintf(stderr, "gnugo: --decide-position must be used with -l\n");
1311 return EXIT_FAILURE;
1312 }
1313 decide_position();
1314 }
1315 break;
1316
1317 case MODE_DECIDE_EYE:
1318 {
1319 int pos;
1320
1321 if (!infilename) {
1322 fprintf(stderr, "gnugo: --decide-eye must be used with -l\n");
1323 return EXIT_FAILURE;
1324 }
1325
1326 pos = string_to_location(board_size, decide_this);
1327 if (pos == NO_MOVE) {
1328 fprintf(stderr, "gnugo: --decide-eye: strange coordinate \n");
1329 return EXIT_FAILURE;
1330 }
1331
1332 decide_eye(pos);
1333 }
1334 break;
1335
1336 case MODE_DECIDE_COMBINATION:
1337 {
1338 int color;
1339 if (!infilename) {
1340 fprintf(stderr, "gnugo: --decide-combination must be used with -l\n");
1341 return EXIT_FAILURE;
1342 }
1343 color = gameinfo.to_move;
1344 if (mandated_color != EMPTY)
1345 color = mandated_color;
1346 decide_combination(color);
1347 }
1348 break;
1349
1350 case MODE_DECIDE_SURROUNDED:
1351 {
1352 int pos = string_to_location(board_size, decide_this);
1353
1354 if (pos == NO_MOVE) {
1355 fprintf(stderr,
1356 "usage: --decide-surrounded [pos]\n");
1357 return EXIT_FAILURE;
1358 }
1359
1360 decide_surrounded(pos);
1361 break;
1362 }
1363
1364#if ORACLE
1365 case MODE_DECIDE_ORACLE:
1366 {
1367 if (mandated_color != EMPTY)
1368 gameinfo.to_move = mandated_color;
1369
1370 if (!infilename) {
1371 fprintf(stderr, "You must use -l infile with load and analyze mode.\n");
1372 exit(EXIT_FAILURE);
1373 }
1374
1375 decide_oracle(&gameinfo, infilename, untilstring);
1376 break;
1377 }
1378#endif
1379
1380 case MODE_GTP:
1381 {
1382 FILE *gtp_input_FILE = stdin;
1383 FILE *gtp_output_FILE = stdout;
1384 FILE *gtp_dump_commands_FILE = NULL;
1385
1386 if (gtpfile != NULL) {
1387 gtp_input_FILE = fopen(gtpfile, "r");
1388 if (gtp_input_FILE == NULL) {
1389 fprintf(stderr, "gnugo: Cannot open file %s\n", gtpfile);
1390 return EXIT_FAILURE;
1391 }
1392 }
1393 else if (gtp_tcp_ip_mode != 0) {
1394 unsigned int port = 65536;
1395 char *port_string = strchr(gtp_tcp_ip_address, ':');
1396 const char *host_name = NULL;
1397
1398 if (port_string) {
1399 host_name = gtp_tcp_ip_address;
1400
1401 *port_string++ = 0;
1402 sscanf(port_string, "%u", &port);
1403 }
1404 else
1405 sscanf(gtp_tcp_ip_address, "%u", &port);
1406
1407 if (port > 65535) {
1408 fprintf(stderr, "A valid TCP/IP port number expected\n");
1409 exit(EXIT_FAILURE);
1410 }
1411
1412 if (gtp_tcp_ip_mode == OPT_GTP_CONNECT) {
1413 socket_connect_to(host_name, port,
1414 &gtp_input_FILE, &gtp_output_FILE);
1415 }
1416 else {
1417 socket_listen_at(host_name, port,
1418 &gtp_input_FILE, &gtp_output_FILE);
1419 }
1420 }
1421
1422 if (gtp_dump_commands_file != NULL) {
1423 gtp_dump_commands_FILE = fopen(gtp_dump_commands_file, "w");
1424 if (gtp_dump_commands_FILE == NULL) {
1425 fprintf(stderr, "gnugo: Cannot open file %s\n",
1426 gtp_dump_commands_file);
1427 return EXIT_FAILURE;
1428 }
1429 }
1430
1431 play_gtp(gtp_input_FILE, gtp_output_FILE, gtp_dump_commands_FILE,
1432 orientation);
1433
1434 if (gtp_dump_commands_FILE)
1435 fclose(gtp_dump_commands_FILE);
1436
1437 if (gtp_tcp_ip_mode == OPT_GTP_CONNECT)
1438 socket_close_connection(gtp_input_FILE, gtp_output_FILE);
1439 else if (gtp_tcp_ip_mode == OPT_GTP_LISTEN)
1440 socket_stop_listening(gtp_input_FILE, gtp_output_FILE);
1441 }
1442
1443 break;
1444
1445 case MODE_ASCII:
1446 default:
1447 if (mandated_color != EMPTY)
1448 gameinfo.computer_player = OTHER_COLOR(mandated_color);
1449
1450 /* Display copyright message in ASCII mode unless --quiet option used. */
1451 if (!quiet) {
1452 show_version();
1453 show_copyright();
1454 }
1455
1456#if ORACLE
1457 if (metamachine) {
1458 summon_oracle();
1459 oracle_loadsgf(infilename, untilstring);
1460 }
1461#endif
1462
1463 play_ascii(&sgftree, &gameinfo, infilename, untilstring);
1464 break;
1465 }
1466
1467 if (profile_patterns)
1468 report_pattern_profiling();
1469
1470 sgfFreeNode(sgftree.root);
1471
1472 return 0;
1473} /* end main */
1474
1475
1476
1477static void
1478show_version(void)
1479{
1480 printf("GNU Go %s\n", VERSION);
1481}
1482
1483
1484/* Set the parameters which determine the depth to which
1485 * the reading and owl code carries its calculations.
1486 */
1487
1488
1489
1490/*
1491 * This string is modelled after the GNU tar --help output.
1492 * Since the maximum string length is 2048 bytes in VC++ we
1493 * split the help string.
1494 */
1495
1496
1497#define USAGE "\n\
1498Usage: gnugo [-opts]\n\
1499\n\
1500Examples:\n\
1501 gnugo --mode gtp --level 5\n\
1502 To play against gnugo in level 5 from a GTP client\n\
1503 gnugo --mode ascii -l game.sgf -L 123\n\
1504 Resume game at move 123 in ASCII mode\n\
1505 gnugo --score estimate -l game.sgf\n\
1506 Give a rough score estimate of the end position in game.sgf\n\
1507\n\
1508Main Options:\n\
1509 --mode <mode> Force the playing mode ('ascii', 'gmp', 'sgmp',\n\
1510 or 'gtp'). Default is ASCII.\n\
1511 If no terminal is detected GMP (Go Modem Protocol)\n\
1512 will be assumed.\n\
1513 --quiet --silent Don't print copyright and informational messages\n\
1514 --level <amount> strength (default %d)\n\
1515 --never-resign Forbid GNU Go to resign\n\
1516 --resign-allowed Allow resignation (default)\n\
1517 -l, --infile <file> Load name sgf file\n\
1518 -L, --until <move> Stop loading just before move is played. <move>\n\
1519 can be the move number or location (eg L10).\n\
1520 -o, --outfile <file> Write sgf output to file\n\
1521 --printsgf <file> Write position as a diagram to file (use with -l)\n\
1522\n\
1523Scoring:\n\
1524 --score estimate estimate score at loaded position\n\
1525 --score finish generate moves to finish game, then score\n\
1526 --score aftermath generate moves to finish, use best algorithm\n\
1527\n\
1528"
1529
1530#define USAGE1 "\
1531Game Options:\n\
1532Used with --mode ascii (or other modes for non-interactive settings)\n\
1533 --boardsize num Set the board size to use (%d--%d)\n\
1534 --color <color> Choose your color ('black' or 'white')\n\
1535 --handicap <num> Set the number of handicap stones (0--%d)\n\
1536 --komi <num> Set the komi\n\
1537 --clock <sec> Initialize the timer.\n\
1538 --byo-time <sec> Initialize the byo-yomi timer.\n\
1539 --byo-period <stones> Initialize the byo-yomi period.\n\
1540\n\
1541 --japanese-rules (default)\n\
1542 --chinese-rules\n\
1543 --forbid-suicide Forbid suicide. (default)\n\
1544 --allow-suicide Allow suicide except single-stone suicide.\n\
1545 --allow-all-suicide Allow all suicide moves.\n\
1546 --simple-ko Forbid simple ko recapture. (default)\n\
1547 --no-ko Allow any ko recapture.\n\
1548 --positional-superko Positional superko restrictions.\n\
1549 --situational-superko Situational superko restrictions.\n\
1550\n\
1551 --play-out-aftermath\n\
1552 --capture-all-dead\n\
1553\n\
1554 --min-level <amount> minimum level for adjustment schemes\n\
1555 --max-level <amount> maximum level for adjustment schemes\n\
1556 --autolevel adapt gnugo level during game to respect\n\
1557 the time specified by --clock <sec>.\n\
1558\n\
1559Connection options\n\
1560 --gtp-input <file>Read gtp commands from file instead of stdin\n\
1561 --gtp-connect [HOST:]PORT\n\
1562 Connect to given host (127.0.0.1 if omitted) and port\n\
1563 and receive GTP commands on the established connection\n\
1564 --gtp-listen [HOST:]PORT\n\
1565 Wait for the first TCP/IP connection on the given port\n\
1566 (if HOST is specified, only to that host)\n\
1567 --gtp-version\n\
1568\n\
1569"
1570
1571#define USAGE2 "\
1572Experimental options:\n\
1573 --with-break-in use the break-in code (on at level 10 by default)\n\
1574 --without-break-in do not use the break-in code\n\
1575 --cosmic-gnugo use center oriented influence\n\
1576 --no-cosmic-gnugo don't use center oriented influence (default)\n\
1577 --large-scale look for large scale captures\n\
1578 --no-large-scale don't seek large scale captures (default)\n\
1579 --nofusekidb turn off fuseki database\n\
1580 --nofuseki turn off fuseki moves entirely\n\
1581 --nojosekidb turn off joseki database\n\
1582 --mirror try to play mirror go\n\
1583 --mirror-limit <n> stop mirroring when n stones on board\n\n\
1584 --monte-carlo enable Monte Carlo move generation (9x9 or smaller)\n\
1585 --mc-games-per-level <n> number of Monte Carlo simulations per level\n\
1586 --mc-list-patterns list names of builtin Monte Carlo patterns\n\
1587 --mc-patterns <name> choose a built in Monte Carlo pattern database\n\
1588 --mc-load-patterns <filename> read Monte Carlo patterns from file\n\
1589 --alternate-connections\n\
1590 --experimental-connections\n\
1591 --experimental-owl-ext\n\
1592 --experimental-semeai\n\
1593 --standard-connections\n\
1594 --standard-semeai\n\
1595 --oracle Read the documentation\n\
1596\n\
1597Cache size (higher=more memory usage, faster unless swapping occurs):\n\
1598 -M, --cache-size <megabytes> RAM cache for read results (default %4.1f Mb)\n\
1599\n\
1600Informative Output:\n\
1601 -v, --version Display the version and copyright of GNU Go\n\
1602 --options Display configure options\n\
1603 -h, --help Display this help message\n\
1604 --help debug Display help about debugging options\n\
1605 --copyright Display copyright notice\n\
1606\n\
1607"
1608
1609#define COPYRIGHT \
1610"Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007\n\
16112008 and 2009 by the Free Software Foundation, Inc.\n\
1612See http://www.gnu.org/software/gnugo/ or contact\n\
1613gnugo@gnu.org for information about GNU Go. GNU Go comes with NO WARRANTY to\n\
1614the extent permitted by law. This program is free software; you can\n\
1615redistribute it and/or modify it under the terms of the GNU General Public\n\
1616License as published by the Free Software Foundation - version 3 or\n\
1617(at your option) any later version. For more\n\
1618information about these matters, see the files named COPYING.\n"
1619
1620/* USAGE_DEBUG Split in half because of VC limit on constant string
1621 * length of 2048 characters!*/
1622#define USAGE_DEBUG "\n\
1623Debugging Options:\n\
1624\n\
1625 --replay <color> replay the moves in a game for color.\n\
1626 (requires -l)\n\
1627 white: replay only white moves\n\
1628 black: replay only black moves\n\
1629 both: replay all moves\n\
1630 -a, --allpats test all patterns\n\
1631 -T, --printboard colored display of dragons\n\
1632 -E, --printeyes colored display of eye spaces\n\
1633 -d, --debug <flags> debugging output (see next item for bits)\n\
1634 --debug-flags print the debug flags for previous item\n\
1635 -w, --worms print worm and dragon data and move reasons\n\
1636 -m, --moyo <level> moyo debugging, show moyo board\n\
1637 --debug-influence <move> print influence map after making a move\n\
1638 -b, --benchmark num benchmarking mode - can be used with -l\n\
1639 -S, --statistics print statistics (for debugging purposes)\n\n\
1640 --profile-patterns print statistics for pattern usage\n\
1641 --showtime print timing diagnostic\n\
1642 -t, --trace verbose tracing\n\
1643 -O, --output-flags <flags> optional output (use with -o)\n\
1644 d: mark dead and critical dragons\n\
1645 v: show values of considered moves\n\
1646 specify either 'd', 'v' or 'dv' (nothing by default)\n\
1647 --showscore print estimated score\n\
1648 -r, --seed number set random number seed\n\
1649 --gtp-dump-commands <file>dump commands received in GTP mode\n\
1650 --gtp-initial-orientation\n\
1651 --orientation\n\
1652\n\
1653"
1654
1655#define USAGE_DEBUG2 "\
1656Options affecting depth settings and playing strength:\n\
1657 --print-levels shows all this values for levels 12 to 0\n\
1658\n\
1659 Default values for the default level (%d):\n\
1660 -D, --depth <depth> deep reading cutoff (default %d)\n\
1661 -B, --backfill-depth <depth> deep reading cutoff (default %d)\n\
1662 -F, --fourlib-depth <depth> deep reading cutoff (default %d)\n\
1663 -K, --ko-depth <depth> deep reading cutoff (default %d)\n\
1664 --branch-depth <depth> deep reading cutoff (default %d)\n\
1665 --backfill2-depth <depth> deep reading cutoff (default %d)\n\
1666 --break_chain-depth <depth> deep reading cutoff (default %d)\n\
1667 --superstring-depth <depth> deep reading cutoff (default %d)\n\
1668 --aa-depth <depth> deep reading cutoff (default %d)\n\
1669 --owl-distrust <depth> owl distrust depth (default %d)\n\
1670 --owl-branch <depth> owl branching depth (default %d)\n\
1671 --owl-reading <depth> owl reading depth (default %d)\n\
1672 --owl-node-limit <limit> max nodes for owl reading (default %d)\n\
1673 --semeai-node-limit <limit> max nodes for semeai reading (default %d)\n\
1674\n\
1675Options providing detailed reading results etc.:\n\
1676 --decide-string <string> can this string live? (try with -o)\n\
1677 --decide-connection <str/str> can these strings connect? (try with -o)\n\
1678 --decide-dragon <dragon> can this dragon live? (try with -o or -t)\n\
1679 --decide-dragon-data\n\
1680 --decide-owl\n\
1681 --decide-position evaluate all dragons (try with -o or -t)\n\
1682 --decide-eye <string> evaluate the eye\n\
1683 --decide-combination search for combination attack (try with -o)\n\
1684 --decide-oracle\n\
1685 --decide-semeai\n\
1686 --decide-tactical-semeai\n\
1687 --decide-surrounded\n\
1688 --limit-search\n\
1689\n\
1690"
1691
1692
1693/*
1694 * Since the maximum string length is 2048 bytes in VC++ we
1695 * split the help string.
1696 */
1697static void
1698show_help(void)
1699{
1700 printf(USAGE, DEFAULT_LEVEL);
1701 printf(USAGE1, MIN_BOARD, MAX_BOARD, MAX_HANDICAP);
1702 printf(USAGE2, DEFAULT_MEMORY <= 0 ? reading_cache_default_size() :
1703 (float) DEFAULT_MEMORY);
1704}
1705
1706
1707static void
1708show_debug_help(void)
1709{
1710 set_depth_values(DEFAULT_LEVEL,0);
1711 printf(USAGE_DEBUG USAGE_DEBUG2,
1712 DEFAULT_LEVEL, depth, backfill_depth, fourlib_depth, ko_depth, branch_depth,
1713 backfill2_depth, break_chain_depth, superstring_depth, aa_depth,
1714 owl_distrust_depth, owl_branch_depth,
1715 owl_reading_depth, owl_node_limit, semeai_node_limit);
1716}
1717
1718static void
1719show_debug_flags(void)
1720{
1721 printf(DEBUG_FLAGS);
1722}
1723
1724static void
1725show_copyright(void)
1726{
1727 printf(COPYRIGHT);
1728}
1729
1730
1731#ifdef ENABLE_SOCKET_SUPPORT
1732
1733
1734#if !defined(_WIN32) && !defined(_WIN32_WCE)
1735
1736#include <sys/socket.h>
1737#include <netinet/in.h>
1738#include <arpa/inet.h>
1739#include <netdb.h>
1740
1741#define closesocket close
1742#define init_sockets()
1743
1744#else /* on Windows */
1745
1746
1747#include <winsocket.h>
1748
1749
1750static void
1751init_sockets(void)
1752{
1753 WSADATA data;
1754 WORD version = MAKEWORD(1, 1);
1755
1756 if (WSAStartup(version, &data) != NO_ERROR) {
1757 fprintf(stderr, "WSAStartup() failed with error %d\n", WSAGetLastError());
1758 exit(EXIT_FAILURE);
1759 }
1760}
1761
1762
1763#endif /* on Windows */
1764
1765
1766static void
1767socket_connect_to(const char *host_name, unsigned int port,
1768 FILE **input_file, FILE **output_file)
1769{
1770 struct sockaddr_in address;
1771 int connection_socket;
1772 struct hostent *host_data;
1773 char **address_pointer;
1774
1775 init_sockets();
1776
1777 if (!host_name)
1778 host_name = "127.0.0.1";
1779
1780 host_data = gethostbyname(host_name);
1781 if (!host_data
1782 || host_data->h_addrtype != AF_INET
1783 || host_data->h_length != sizeof address.sin_addr) {
1784 fprintf(stderr, "Failed to resolve host name `%s'\n", host_name);
1785 exit(EXIT_FAILURE);
1786 }
1787
1788 connection_socket = socket(PF_INET, SOCK_STREAM, 0);
1789 if (connection_socket == -1) {
1790 fprintf(stderr, "Unexpected error: failed to create a socket\n");
1791 exit(EXIT_FAILURE);
1792 }
1793
1794 address.sin_family = AF_INET;
1795 address.sin_port = htons((unsigned short) port);
1796
1797 for (address_pointer = host_data->h_addr_list; *address_pointer;
1798 address_pointer++) {
1799 memcpy(&address.sin_addr, *address_pointer, sizeof address.sin_addr);
1800 if (connect(connection_socket, (struct sockaddr *) &address,
1801 sizeof address) != -1)
1802 break;
1803 }
1804
1805 if (! *address_pointer) {
1806 fprintf(stderr, "Failed to connect to %s:%u\n", host_data->h_name, port);
1807 closesocket(connection_socket);
1808 exit(EXIT_FAILURE);
1809 }
1810
1811#if !USE_WINDOWS_SOCKET_CLUDGE
1812
1813 *input_file = fdopen(connection_socket, "r");
1814 *output_file = fdopen(dup(connection_socket), "w");
1815
1816#else /* USE_WINDOWS_SOCKET_CLUDGE */
1817
1818 winsocket_activate(connection_socket);
1819
1820 *input_file = NULL;
1821 *output_file = NULL;
1822
1823#endif /* USE_WINDOWS_SOCKET_CLUDGE */
1824}
1825
1826
1827static void
1828socket_listen_at(const char *host_name, unsigned int port,
1829 FILE **input_file, FILE **output_file)
1830{
1831 struct sockaddr_in address;
1832 int listening_socket;
1833 int connection_socket;
1834
1835 init_sockets();
1836
1837 if (host_name) {
1838 struct hostent *host_data;
1839
1840 host_data = gethostbyname(host_name);
1841 if (!host_data
1842 || host_data->h_addrtype != AF_INET
1843 || host_data->h_length != sizeof address.sin_addr) {
1844 fprintf(stderr, "Failed to resolve host name `%s'\n", host_name);
1845 exit(EXIT_FAILURE);
1846 }
1847
1848 host_name = host_data->h_name;
1849 memcpy(&address.sin_addr, host_data->h_addr_list[0],
1850 sizeof address.sin_addr);
1851 }
1852 else
1853 address.sin_addr.s_addr = htonl(INADDR_ANY);
1854
1855 listening_socket = socket(PF_INET, SOCK_STREAM, 0);
1856 if (listening_socket == -1) {
1857 fprintf(stderr, "Unexpected error: failed to create a socket\n");
1858 exit(EXIT_FAILURE);
1859 }
1860
1861 address.sin_family = AF_INET;
1862 address.sin_port = htons((unsigned short) port);
1863
1864 if (verbose) {
1865 if (host_name) {
1866 fprintf(stderr, "Waiting for a connection on %s:%u...\n",
1867 host_name, port);
1868 }
1869 else
1870 fprintf(stderr, "Waiting for a connection on port %u...\n", port);
1871 }
1872
1873 if (bind(listening_socket,
1874 (struct sockaddr *) &address, sizeof address) == -1
1875 || listen(listening_socket, 0) == -1
1876 || (connection_socket = accept(listening_socket, NULL, NULL)) == -1) {
1877 if (host_name)
1878 fprintf(stderr, "Failed to listen on %s:%u\n", host_name, port);
1879 else
1880 fprintf(stderr, "Failed to listen on port %u\n", port);
1881
1882 closesocket(listening_socket);
1883 exit(EXIT_FAILURE);
1884 }
1885
1886 closesocket(listening_socket);
1887
1888#if !USE_WINDOWS_SOCKET_CLUDGE
1889
1890 *input_file = fdopen(connection_socket, "r");
1891 *output_file = fdopen(dup(connection_socket), "w");
1892
1893#else /* USE_WINDOWS_SOCKET_CLUDGE */
1894
1895 winsocket_activate(connection_socket);
1896
1897 *input_file = NULL;
1898 *output_file = NULL;
1899
1900#endif /* USE_WINDOWS_SOCKET_CLUDGE */
1901}
1902
1903
1904static void
1905socket_close_connection(FILE *input_file, FILE *output_file)
1906{
1907 /* When connecting, we close the socket first. */
1908 fclose(input_file);
1909 fclose(output_file);
1910}
1911
1912
1913static void
1914socket_stop_listening(FILE *input_file, FILE *output_file)
1915{
1916 int buffer[0x1000];
1917
1918 if (verbose)
1919 fprintf(stderr, "Waiting for the client to disconnect...\n");
1920
1921 /* When listening, we wait for the client to disconnect first.
1922 * Otherwise, socket doesn't get released properly.
1923 */
1924 do
1925 fread(buffer, sizeof buffer, 1, input_file);
1926 while (!feof(input_file));
1927
1928 fclose(input_file);
1929 fclose(output_file);
1930}
1931
1932
1933#else /* not ENABLE_SOCKET_SUPPORT */
1934
1935
1936static void
1937socket_connect_to(const char *host_name, unsigned int port,
1938 FILE **input_file, FILE **output_file)
1939{
1940 UNUSED(host_name);
1941 UNUSED(port);
1942 UNUSED(input_file);
1943 UNUSED(output_file);
1944
1945 fprintf(stderr, "GNU Go was compiled without socket support, unable to connect\n");
1946 exit(EXIT_FAILURE);
1947}
1948
1949
1950static void
1951socket_listen_at(const char *host_name, unsigned int port,
1952 FILE **input_file, FILE **output_file)
1953{
1954 UNUSED(host_name);
1955 UNUSED(port);
1956 UNUSED(input_file);
1957 UNUSED(output_file);
1958
1959 fprintf(stderr, "GNU Go was compiled without socket support, unable to listen\n");
1960 exit(EXIT_FAILURE);
1961}
1962
1963
1964static void
1965socket_close_connection(FILE *input_file, FILE *output_file)
1966{
1967 UNUSED(input_file);
1968 UNUSED(output_file);
1969}
1970
1971
1972static void
1973socket_stop_listening(FILE *input_file, FILE *output_file)
1974{
1975 UNUSED(input_file);
1976 UNUSED(output_file);
1977}
1978
1979
1980#endif /* not ENABLE_SOCKET_SUPPORT */
1981
1982
1983/*
1984 * Local Variables:
1985 * tab-width: 8
1986 * c-basic-offset: 2
1987 * End:
1988 */