/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see * * http://www.gnu.org/software/gnugo/ for more information. * * * * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008 and 2009 by the Free Software Foundation. * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation - version 3 or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License in file COPYING for more details. * * * * You should have received a copy of the GNU General Public * * License along with this program; if not, write to the Free * * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02111, USA. * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "gnugo.h" #include #include #include #include #ifdef HAVE_UNISTD_H /* For isatty(). */ #include #else #include #endif #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #include "liberty.h" #include "gg-getopt.h" #include "gg_utils.h" #include "winsocket.h" #include "interface.h" #include "sgftree.h" #include "random.h" static void show_copyright(void); static void show_version(void); static void show_help(void); static void show_debug_help(void); static void show_debug_flags(void); static void socket_connect_to(const char *host_name, unsigned int port, FILE **input_file, FILE **output_file); static void socket_listen_at(const char *host_name, unsigned int port, FILE **input_file, FILE **output_file); static void socket_close_connection(FILE *input_file, FILE *output_file); static void socket_stop_listening(FILE *input_file, FILE *output_file); /* long options which have no short form */ enum {OPT_BOARDSIZE = 127, OPT_HANDICAPSTONES, OPT_COLOR, OPT_KOMI, OPT_CLOCK_TIME, OPT_CLOCK_BYO_TIME, OPT_CLOCK_BYO_PERIOD, OPT_AUTOLEVEL, OPT_MODE, OPT_INFILE, OPT_OUTFILE, OPT_QUIET, OPT_GTP_INPUT, OPT_GTP_CONNECT, OPT_GTP_LISTEN, OPT_GTP_DUMP_COMMANDS, OPT_GTP_INITIAL_ORIENTATION, OPT_GTP_VERSION, OPT_SHOWCOPYRIGHT, OPT_REPLAY_GAME, OPT_DECIDE_STRING, OPT_DECIDE_CONNECTION, OPT_DECIDE_OWL, OPT_DECIDE_DRAGON_DATA, OPT_DECIDE_SEMEAI, OPT_DECIDE_SURROUNDED, OPT_DECIDE_TACTICAL_SEMEAI, OPT_DECIDE_ORACLE, OPT_EXPERIMENTAL_SEMEAI, OPT_EXPERIMENTAL_OWL_EXT, OPT_SEMEAI_NODE_LIMIT, OPT_EXPERIMENTAL_CONNECTIONS, OPT_ALTERNATE_CONNECTIONS, OPT_WITH_BREAK_IN, OPT_WITHOUT_BREAK_IN, OPT_COSMIC_GNUGO, OPT_NO_COSMIC_GNUGO, OPT_LARGE_SCALE, OPT_NO_LARGE_SCALE, OPT_OPTIONS, OPT_STANDARD_SEMEAI, OPT_STANDARD_CONNECTIONS, OPT_PRINT_LEVELS, OPT_DECIDE_POSITION, OPT_DECIDE_EYE, OPT_DECIDE_COMBINATION, OPT_BRANCH_DEPTH, OPT_BACKFILL2_DEPTH, OPT_BREAK_CHAIN_DEPTH, OPT_SUPERSTRING_DEPTH, OPT_AA_DEPTH, OPT_DEBUG_FLAGS, OPT_OWL_DISTRUST, OPT_OWL_BRANCH, OPT_OWL_READING, OPT_OWL_NODE_LIMIT, OPT_NOFUSEKIDB, OPT_NOFUSEKI, OPT_NOJOSEKIDB, OPT_LEVEL, OPT_MIN_LEVEL, OPT_MAX_LEVEL, OPT_LIMIT_SEARCH, OPT_SHOWTIME, OPT_SHOWSCORE, OPT_DEBUG_INFLUENCE, OPT_SCORE, OPT_PRINTSGF, OPT_PROFILE_PATTERNS, OPT_CHINESE_RULES, OPT_OWL_THREATS, OPT_NO_OWL_THREATS, OPT_JAPANESE_RULES, OPT_FORBID_SUICIDE, OPT_ALLOW_SUICIDE, OPT_ALLOW_ALL_SUICIDE, OPT_SIMPLE_KO, OPT_NO_KO, OPT_POSITIONAL_SUPERKO, OPT_SITUATIONAL_SUPERKO, OPT_CAPTURE_ALL_DEAD, OPT_PLAY_OUT_AFTERMATH, OPT_MIRROR, OPT_MIRROR_LIMIT, OPT_METAMACHINE, OPT_RESIGN_ALLOWED, OPT_NEVER_RESIGN, OPT_MONTE_CARLO, OPT_MC_GAMES_PER_LEVEL, OPT_MC_PATTERNS, OPT_MC_LIST_PATTERNS, OPT_MC_LOAD_PATTERNS }; /* names of playing modes */ enum mode { MODE_UNKNOWN = 0, MODE_ASCII, MODE_GTP, MODE_GMP, MODE_SGMP, MODE_SGF, MODE_LOAD_AND_ANALYZE, MODE_LOAD_AND_SCORE, MODE_LOAD_AND_PRINT, MODE_SOLO, MODE_REPLAY, MODE_DECIDE_STRING, MODE_DECIDE_CONNECTION, MODE_DECIDE_OWL, MODE_DECIDE_DRAGON_DATA, MODE_DECIDE_SEMEAI, MODE_DECIDE_TACTICAL_SEMEAI, MODE_DECIDE_POSITION, MODE_DECIDE_EYE, MODE_DECIDE_COMBINATION, MODE_DECIDE_SURROUNDED, MODE_DECIDE_ORACLE }; /* Definitions of the --long options. Final column is * either an OPT_ as defined in the enum above, or it * is the equivalent single-letter option. * It is useful to keep them in the same order as the * help string, for maintenance purposes only. */ static struct gg_option const long_options[] = { {"mode", required_argument, 0, OPT_MODE}, {"replay", required_argument, 0, OPT_REPLAY_GAME}, {"quiet", no_argument, 0, OPT_QUIET}, {"silent", no_argument, 0, OPT_QUIET}, {"gtp-input", required_argument, 0, OPT_GTP_INPUT}, {"gtp-connect", required_argument, 0, OPT_GTP_CONNECT}, {"gtp-listen", required_argument, 0, OPT_GTP_LISTEN}, {"gtp-dump-commands", required_argument, 0, OPT_GTP_DUMP_COMMANDS}, {"orientation", required_argument, 0, OPT_GTP_INITIAL_ORIENTATION}, {"gtp-initial-orientation", required_argument, 0, OPT_GTP_INITIAL_ORIENTATION}, {"gtp-version", required_argument, 0, OPT_GTP_VERSION}, {"infile", required_argument, 0, 'l'}, {"until", required_argument, 0, 'L'}, {"outfile", required_argument, 0, 'o'}, {"output-flags", required_argument, 0, 'O'}, {"boardsize", required_argument, 0, OPT_BOARDSIZE}, {"color", required_argument, 0, OPT_COLOR}, {"handicap", required_argument, 0, OPT_HANDICAPSTONES}, {"komi", required_argument, 0, OPT_KOMI}, {"help", optional_argument, 0, 'h'}, {"copyright", no_argument, 0, OPT_SHOWCOPYRIGHT}, {"version", no_argument, 0, 'v'}, {"allpats", no_argument, 0, 'a'}, {"printboard", no_argument, 0, 'T'}, {"printeyes", no_argument, 0, 'E'}, {"debug", required_argument, 0, 'd'}, {"debug-flags", no_argument, 0, OPT_DEBUG_FLAGS}, {"depth", required_argument, 0, 'D'}, {"backfill-depth", required_argument, 0, 'B'}, {"branch-depth", required_argument, 0, OPT_BRANCH_DEPTH}, {"backfill2-depth", required_argument, 0, OPT_BACKFILL2_DEPTH}, {"break-chain-depth", required_argument, 0, OPT_BREAK_CHAIN_DEPTH}, {"superstring-depth", required_argument, 0, OPT_SUPERSTRING_DEPTH}, {"fourlib-depth", required_argument, 0, 'F'}, {"ko-depth", required_argument, 0, 'K'}, {"aa-depth", required_argument, 0, OPT_AA_DEPTH}, {"owl-distrust", required_argument, 0, OPT_OWL_DISTRUST}, {"owl-branch", required_argument, 0, OPT_OWL_BRANCH}, {"owl-reading", required_argument, 0, OPT_OWL_READING}, {"owl-node-limit", required_argument, 0, OPT_OWL_NODE_LIMIT}, {"print-levels", no_argument, 0, OPT_PRINT_LEVELS}, {"level", required_argument, 0, OPT_LEVEL}, {"min-level", required_argument, 0, OPT_MIN_LEVEL}, {"max-level", required_argument, 0, OPT_MAX_LEVEL}, {"limit-search", required_argument, 0, OPT_LIMIT_SEARCH}, {"clock", required_argument, 0, OPT_CLOCK_TIME}, {"byo-time", required_argument, 0, OPT_CLOCK_BYO_TIME}, {"byo-period", required_argument, 0, OPT_CLOCK_BYO_PERIOD}, {"autolevel", no_argument, 0, OPT_AUTOLEVEL}, {"chinese-rules", no_argument, 0, OPT_CHINESE_RULES}, {"japanese-rules", no_argument, 0, OPT_JAPANESE_RULES}, {"experimental-semeai", no_argument, 0, OPT_EXPERIMENTAL_SEMEAI}, {"experimental-owl-ext", no_argument, 0, OPT_EXPERIMENTAL_OWL_EXT}, {"semeai-node-limit", required_argument, 0, OPT_SEMEAI_NODE_LIMIT}, {"experimental-connections", no_argument, 0, OPT_EXPERIMENTAL_CONNECTIONS}, {"standard-connections", no_argument, 0, OPT_STANDARD_CONNECTIONS}, {"standard-semeai", no_argument, 0, OPT_STANDARD_SEMEAI}, {"alternate-connections", no_argument, 0, OPT_ALTERNATE_CONNECTIONS}, {"with-break-in", no_argument, 0, OPT_WITH_BREAK_IN}, {"without-break-in", no_argument, 0, OPT_WITHOUT_BREAK_IN}, {"cosmic-gnugo", no_argument, 0, OPT_COSMIC_GNUGO}, {"no-cosmic-gnugo", no_argument, 0, OPT_NO_COSMIC_GNUGO}, {"large-scale", no_argument, 0, OPT_LARGE_SCALE}, {"no-large-scale", no_argument, 0, OPT_NO_LARGE_SCALE}, {"options", no_argument, 0, OPT_OPTIONS}, {"forbid-suicide", no_argument, 0, OPT_FORBID_SUICIDE}, {"allow-suicide", no_argument, 0, OPT_ALLOW_SUICIDE}, {"allow-all-suicide", no_argument, 0, OPT_ALLOW_ALL_SUICIDE}, {"simple-ko", no_argument, 0, OPT_SIMPLE_KO}, {"no-ko", no_argument, 0, OPT_NO_KO}, {"positional-superko", no_argument, 0, OPT_POSITIONAL_SUPERKO}, {"situational-superko", no_argument, 0, OPT_SITUATIONAL_SUPERKO}, {"capture-all-dead", no_argument, 0, OPT_CAPTURE_ALL_DEAD}, {"play-out-aftermath", no_argument, 0, OPT_PLAY_OUT_AFTERMATH}, {"cache-size", required_argument, 0, 'M'}, {"worms", no_argument, 0, 'w'}, {"moyo", required_argument, 0, 'm'}, {"benchmark", required_argument, 0, 'b'}, {"statistics", no_argument, 0, 'S'}, {"trace", no_argument, 0, 't'}, {"seed", required_argument, 0, 'r'}, {"decide-string", required_argument, 0, OPT_DECIDE_STRING}, {"decide-connection", required_argument, 0, OPT_DECIDE_CONNECTION}, {"decide-dragon", required_argument, 0, OPT_DECIDE_OWL}, {"decide-owl", required_argument, 0, OPT_DECIDE_OWL}, {"decide-dragon-data", required_argument, 0, OPT_DECIDE_DRAGON_DATA}, {"decide-semeai", required_argument, 0, OPT_DECIDE_SEMEAI}, {"decide-tactical-semeai", required_argument, 0, OPT_DECIDE_TACTICAL_SEMEAI}, {"decide-position", no_argument, 0, OPT_DECIDE_POSITION}, {"decide-surrounded", required_argument, 0, OPT_DECIDE_SURROUNDED}, {"decide-eye", required_argument, 0, OPT_DECIDE_EYE}, {"decide-combination", no_argument, 0, OPT_DECIDE_COMBINATION}, {"decide-oracle", no_argument, 0, OPT_DECIDE_ORACLE}, {"nofusekidb", no_argument, 0, OPT_NOFUSEKIDB}, {"nofuseki", no_argument, 0, OPT_NOFUSEKI}, {"nojosekidb", no_argument, 0, OPT_NOJOSEKIDB}, {"debug-influence", required_argument, 0, OPT_DEBUG_INFLUENCE}, {"showtime", no_argument, 0, OPT_SHOWTIME}, {"showscore", no_argument, 0, OPT_SHOWSCORE}, {"score", required_argument, 0, OPT_SCORE}, {"printsgf", required_argument, 0, OPT_PRINTSGF}, {"profile-patterns", no_argument, 0, OPT_PROFILE_PATTERNS}, {"mirror", no_argument, 0, OPT_MIRROR}, {"mirror-limit", required_argument, 0, OPT_MIRROR_LIMIT}, {"metamachine", no_argument, 0, OPT_METAMACHINE}, {"resign-allowed", no_argument, 0, OPT_RESIGN_ALLOWED}, {"never-resign", no_argument, 0, OPT_NEVER_RESIGN}, {"monte-carlo", no_argument, 0, OPT_MONTE_CARLO}, {"mc-games-per-level", required_argument, 0, OPT_MC_GAMES_PER_LEVEL}, {"mc-patterns", required_argument, 0, OPT_MC_PATTERNS}, {"mc-list-patterns", no_argument, 0, OPT_MC_LIST_PATTERNS}, {"mc-load-patterns", required_argument, 0, OPT_MC_LOAD_PATTERNS}, {NULL, 0, NULL, 0} }; int main(int argc, char *argv[]) { Gameinfo gameinfo; SGFTree sgftree; int i; int mandated_color = EMPTY; enum mode playmode = MODE_UNKNOWN; int replay_color = EMPTY; char *infilename = NULL; char *untilstring = NULL; char *scoringmode = NULL; char *outfile = NULL; char *outflags = NULL; char *gtpfile = NULL; char *gtp_dump_commands_file = NULL; int gtp_tcp_ip_mode = 0; char *gtp_tcp_ip_address = NULL; char *printsgffile = NULL; char decide_this[8]; char *decide_that = NULL; char debuginfluence_move[4] = "\0"; int benchmark = 0; /* benchmarking mode (-b) */ FILE *output_check; int orientation = 0; char mc_pattern_name[40] = ""; char mc_pattern_filename[320] = ""; float memory = (float) DEFAULT_MEMORY; /* Megabytes used for hash table. */ /* If seed is zero, GNU Go will play a different game each time. If * it is set using -r, GNU Go will play the same game each time. * (Change seed to get a different game). */ int seed = 0; int seed_specified = 0; int requested_boardsize = -1; sgftree_clear(&sgftree); gameinfo_clear(&gameinfo); /* Weed through all of the command line options. */ while ((i = gg_getopt_long(argc, argv, "-ab:B:d:D:EF:gh::K:l:L:M:m:o:O:p:r:fsStTvw", long_options, NULL)) != EOF) { switch (i) { case 'T': printboard++; break; case 't': ++verbose; break; case 'a': allpats = 1; break; case 1 : case 'l': infilename = gg_optarg; break; case 'b': benchmark = atoi(gg_optarg); playmode = MODE_SOLO; break; case 'r': seed = atoi(gg_optarg); seed_specified = 1; break; case 'S': showstatistics = 1; break; case 'w': printworms = 1; break; case 'm': printmoyo = strtol(gg_optarg, NULL, 0); /* allows 0x... */ break; case 'd': debug ^= strtol(gg_optarg, NULL, 0); /* allows 0x... */ break; case 'D': mandated_depth = atoi(gg_optarg); break; case 'M': memory = atof(gg_optarg); break; /* floating point number */ case 'E': printboard = 2; break; case 'B': mandated_backfill_depth = atoi(gg_optarg); break; case 'F': mandated_fourlib_depth = atoi(gg_optarg); break; case 'K': mandated_ko_depth = atoi(gg_optarg); break; case 'L': untilstring = gg_optarg; break; case 'o': if (strlen(gg_optarg) >= sizeof(outfilename)) { fprintf(stderr, "Too long filename given as value to -o option.\n"); exit(EXIT_FAILURE); } outfile = gg_optarg; strcpy(outfilename, gg_optarg); break; case 'O': outflags = gg_optarg; output_flags = 0; if (outflags) while (*outflags) { switch (*outflags) { case 'd': output_flags |= OUTPUT_MARKDRAGONS; break; case 'v': output_flags |= OUTPUT_MOVEVALUES; break; } outflags++; } break; case OPT_QUIET: quiet = 1; break; case OPT_GTP_INPUT: case OPT_GTP_CONNECT: case OPT_GTP_LISTEN: if (gtp_tcp_ip_mode != 0 || gtpfile != NULL) { fprintf(stderr, ("Options `--gtp-input', `--gtp-connect' and `--gtp-listen' " "are mutually-exclusive\n")); exit(EXIT_FAILURE); } if (i == OPT_GTP_INPUT) gtpfile = gg_optarg; else { gtp_tcp_ip_mode = i; gtp_tcp_ip_address = gg_optarg; } break; case OPT_GTP_DUMP_COMMANDS: gtp_dump_commands_file = gg_optarg; break; case OPT_GTP_INITIAL_ORIENTATION: orientation = atoi(gg_optarg); if (orientation < 0 || orientation > 7) { fprintf(stderr, "Invalid orientation: %d.\n", orientation); fprintf(stderr, "Try `gnugo --help' for more information.\n"); exit(EXIT_FAILURE); } break; case OPT_GTP_VERSION: gtp_version = atoi(gg_optarg); break; case OPT_OPTIONS: if (USE_BREAK_IN) fprintf(stdout, "configure option enabled: experimental break-ins\n"); if (COSMIC_GNUGO) fprintf(stdout, "configure option enabled: cosmic GNU Go \n"); if (LARGE_SCALE) fprintf(stdout, "configure option enabled: large scale captures \n"); if (EXPERIMENTAL_CONNECTIONS) fprintf(stdout, "configure option enabled: experimental connections\n"); if (ALTERNATE_CONNECTIONS) fprintf(stdout, "configure option enabled: alternate connections\n"); if (EXPERIMENTAL_OWL_EXT) fprintf(stdout, "configure option enabled: experimental GAIN/LOSS codes\n"); if (OWL_THREATS) fprintf(stdout, "configure option enabled: owl threats\n"); if (RESIGNATION_ALLOWED) fprintf(stdout, "configure option enabled: resignation allowed\n"); if (ORACLE) fprintf(stdout, "configure option enabled: oracle\n"); fprintf(stdout, "Owl node limit: %d\n", OWL_NODE_LIMIT); fprintf(stdout, "Semeai node limit: %d\n", SEMEAI_NODE_LIMIT); if (DEFAULT_MEMORY == -1) fprintf(stdout, "Cache size: %d MB (special default value)\n", DEFAULT_MEMORY); else fprintf(stdout, "Cache size: %d MB\n", DEFAULT_MEMORY); return EXIT_SUCCESS; break; case OPT_SHOWTIME: showtime = 1; break; case OPT_SHOWSCORE: showscore = 1; break; case OPT_HANDICAPSTONES: { int requested_handicap = atoi(gg_optarg); if (requested_handicap < 0 || requested_handicap > MAX_HANDICAP) { fprintf(stderr, "Unsupported handicap: %d.\n", requested_handicap); fprintf(stderr, "Try `gnugo --help' for more information.\n"); exit(EXIT_FAILURE); } gameinfo.handicap = requested_handicap; } break; case OPT_BOARDSIZE: requested_boardsize = atoi(gg_optarg); break; case OPT_KOMI: if (sscanf(gg_optarg, "%f", &komi) != 1) { fprintf(stderr, "Invalid komi selection: %s\n", gg_optarg); fprintf(stderr, "Try `gnugo --help' for more information.\n"); exit(EXIT_FAILURE); } break; case OPT_CHINESE_RULES: chinese_rules = 1; break; case OPT_OWL_THREATS: owl_threats = 1; break; case OPT_NO_OWL_THREATS: owl_threats = 0; break; case OPT_METAMACHINE: metamachine = 1; break; case OPT_JAPANESE_RULES: chinese_rules = 0; break; case OPT_EXPERIMENTAL_OWL_EXT: experimental_owl_ext = 1; break; case OPT_SEMEAI_NODE_LIMIT: mandated_semeai_node_limit = atoi(gg_optarg); break; case OPT_EXPERIMENTAL_CONNECTIONS: experimental_connections = 1; break; case OPT_STANDARD_CONNECTIONS: experimental_connections = 0; break; case OPT_ALTERNATE_CONNECTIONS: alternate_connections = !alternate_connections; break; case OPT_WITH_BREAK_IN: experimental_break_in = 1; break; case OPT_WITHOUT_BREAK_IN: experimental_break_in = 0; break; case OPT_COSMIC_GNUGO: cosmic_gnugo = 1; break; case OPT_NO_COSMIC_GNUGO: cosmic_gnugo = 0; break; case OPT_LARGE_SCALE: large_scale = 1; break; case OPT_NO_LARGE_SCALE: large_scale = 0; break; case OPT_FORBID_SUICIDE: suicide_rule = FORBIDDEN; break; case OPT_ALLOW_SUICIDE: suicide_rule = ALLOWED; break; case OPT_ALLOW_ALL_SUICIDE: suicide_rule = ALL_ALLOWED; break; case OPT_SIMPLE_KO: ko_rule = SIMPLE; break; case OPT_NO_KO: ko_rule = NONE; break; case OPT_POSITIONAL_SUPERKO: ko_rule = PSK; break; case OPT_SITUATIONAL_SUPERKO: ko_rule = SSK; break; case OPT_CAPTURE_ALL_DEAD: capture_all_dead = 1; break; case OPT_PLAY_OUT_AFTERMATH: play_out_aftermath = 1; break; case OPT_RESIGN_ALLOWED: resign_allowed = 1; break; case OPT_NEVER_RESIGN: resign_allowed = 0; break; case OPT_MONTE_CARLO: use_monte_carlo_genmove = 1; break; case OPT_MC_GAMES_PER_LEVEL: mc_games_per_level = atoi(gg_optarg); break; case OPT_MC_PATTERNS: if (strlen(gg_optarg) >= sizeof(mc_pattern_name)) { fprintf(stderr, "Too long name given as value to --mc-patterns option.\n"); exit(EXIT_FAILURE); } strcpy(mc_pattern_name, gg_optarg); break; case OPT_MC_LIST_PATTERNS: list_mc_patterns(); return EXIT_SUCCESS; break; case OPT_MC_LOAD_PATTERNS: if (strlen(gg_optarg) >= sizeof(mc_pattern_filename)) { fprintf(stderr, "Too long name given as value to --mc-load-patterns option.\n"); exit(EXIT_FAILURE); } strcpy(mc_pattern_filename, gg_optarg); break; case OPT_MODE: if (strcmp(gg_optarg, "ascii") == 0) playmode = MODE_ASCII; else if (strcmp(gg_optarg, "gtp") == 0) playmode = MODE_GTP; else if (strcmp(gg_optarg, "gmp") == 0) playmode = MODE_GMP; else if (strcmp(gg_optarg, "sgmp") == 0) playmode = MODE_SGMP; else { fprintf(stderr, "Invalid mode selection: %s\n", gg_optarg); fprintf(stderr, "Try `gnugo --help' for more information.\n"); exit(EXIT_FAILURE); } break; case OPT_DECIDE_STRING: if (strlen(gg_optarg) > 3) { fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg); exit(EXIT_FAILURE); } strcpy(decide_this, gg_optarg); playmode = MODE_DECIDE_STRING; break; case OPT_DECIDE_CONNECTION: if (strlen(gg_optarg) > 7) { fprintf(stderr, "usage: --decide-connection [first string]/[second string]\n"); return EXIT_FAILURE; } strcpy(decide_this, gg_optarg); strtok(decide_this, "/"); decide_that = strtok(NULL, "/"); if (!decide_that) { fprintf(stderr, "usage: --decide-connection [first string]/[second string]\n"); return EXIT_FAILURE; } playmode = MODE_DECIDE_CONNECTION; break; case OPT_DECIDE_OWL: if (strlen(gg_optarg) > 3) { fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg); exit(EXIT_FAILURE); } strcpy(decide_this, gg_optarg); playmode = MODE_DECIDE_OWL; break; case OPT_DECIDE_DRAGON_DATA: if (strlen(gg_optarg) > 3) { fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg); exit(EXIT_FAILURE); } strcpy(decide_this, gg_optarg); playmode = MODE_DECIDE_DRAGON_DATA; break; case OPT_DECIDE_SEMEAI: if (strlen(gg_optarg) > 7) { fprintf(stderr, "usage: --decide-semeai [first dragon]/[second dragon]\n"); return EXIT_FAILURE; } strcpy(decide_this, gg_optarg); strtok(decide_this, "/"); decide_that = strtok(NULL, "/"); if (!decide_that) { fprintf(stderr, "usage: --decide-semeai [first dragon]/[second dragon]\n"); return EXIT_FAILURE; } playmode = MODE_DECIDE_SEMEAI; break; case OPT_DECIDE_TACTICAL_SEMEAI: if (strlen(gg_optarg) > 7) { fprintf(stderr, "usage: --decide-tactical-semeai [first dragon]/[second dragon]\n"); return EXIT_FAILURE; } strcpy(decide_this, gg_optarg); strtok(decide_this, "/"); decide_that = strtok(NULL, "/"); if (!decide_that) { fprintf(stderr, "usage: --decide-tactical-semeai [first dragon]/[second dragon]\n"); return EXIT_FAILURE; } playmode = MODE_DECIDE_TACTICAL_SEMEAI; break; case OPT_DECIDE_POSITION: playmode = MODE_DECIDE_POSITION; break; case OPT_DECIDE_EYE: if (strlen(gg_optarg) > 3) { fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg); exit(EXIT_FAILURE); } strcpy(decide_this, gg_optarg); playmode = MODE_DECIDE_EYE; break; case OPT_DECIDE_COMBINATION: playmode = MODE_DECIDE_COMBINATION; break; case OPT_DECIDE_SURROUNDED: if (strlen(gg_optarg) > 3) { fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg); exit(EXIT_FAILURE); } strcpy(decide_this, gg_optarg); playmode = MODE_DECIDE_SURROUNDED; break; case OPT_DECIDE_ORACLE: playmode = MODE_DECIDE_ORACLE; break; case OPT_BRANCH_DEPTH: mandated_branch_depth = atoi(gg_optarg); break; case OPT_BACKFILL2_DEPTH: mandated_backfill2_depth = atoi(gg_optarg); break; case OPT_BREAK_CHAIN_DEPTH: mandated_break_chain_depth = atoi(gg_optarg); break; case OPT_SUPERSTRING_DEPTH: mandated_superstring_depth = atoi(gg_optarg); break; case OPT_AA_DEPTH: mandated_aa_depth = atoi(gg_optarg); break; case OPT_OWL_DISTRUST: mandated_owl_distrust_depth = atoi(gg_optarg); break; case OPT_OWL_BRANCH: mandated_owl_branch_depth = atoi(gg_optarg); break; case OPT_OWL_READING: mandated_owl_reading_depth = atoi(gg_optarg); break; case OPT_OWL_NODE_LIMIT: mandated_owl_node_limit = atoi(gg_optarg); break; case OPT_NOFUSEKIDB: fusekidb = 0; break; case OPT_NOFUSEKI: disable_fuseki = 1; break; case OPT_NOJOSEKIDB: josekidb = 0; break; case OPT_LEVEL: set_level(atoi(gg_optarg)); break; case OPT_MIN_LEVEL: set_min_level(atoi(gg_optarg)); break; case OPT_MAX_LEVEL: set_max_level(atoi(gg_optarg)); break; case OPT_LIMIT_SEARCH: { int pos = string_to_location(board_size, gg_optarg); if (pos == NO_MOVE) { fprintf(stderr, "gnugo: use --limit-search \n"); return EXIT_FAILURE; } set_search_diamond(pos); } break; case OPT_CLOCK_TIME: clock_settings(atoi(gg_optarg), -1, -1); break; case OPT_CLOCK_BYO_TIME: clock_settings(-1, atoi(gg_optarg), -1); break; case OPT_CLOCK_BYO_PERIOD: clock_settings(-1, -1, atoi(gg_optarg)); break; case OPT_AUTOLEVEL: autolevel_on = 1; break; case OPT_DEBUG_INFLUENCE: if (strlen(gg_optarg) > 3) { fprintf(stderr, "Invalid board coordinate: %s\n", gg_optarg); exit(EXIT_FAILURE); } strcpy(debuginfluence_move, gg_optarg); break; case OPT_REPLAY_GAME: playmode = MODE_REPLAY; if (strcmp(gg_optarg, "white") == 0) replay_color = WHITE; else if (strcmp(gg_optarg, "black") == 0) replay_color = BLACK; else if (strcmp(gg_optarg, "both") == 0) replay_color = GRAY; else { fprintf(stderr, "Invalid replay color: %s\n", gg_optarg); fprintf(stderr, "Try `gnugo --help' for more information.\n"); exit(EXIT_FAILURE); } break; case OPT_SCORE: scoringmode = gg_optarg; if (playmode == MODE_UNKNOWN) playmode = MODE_LOAD_AND_SCORE; break; case OPT_PRINTSGF: playmode = MODE_LOAD_AND_PRINT; printsgffile = gg_optarg; break; case OPT_PROFILE_PATTERNS: profile_patterns = 1; prepare_pattern_profiling(); break; case OPT_COLOR: if (strcmp(gg_optarg, "white") == 0) mandated_color = WHITE; else if (strcmp(gg_optarg, "black") == 0) mandated_color = BLACK; else { fprintf(stderr, "Invalid color selection: %s\n", gg_optarg); fprintf(stderr, "Try `gnugo --help' for more information.\n"); exit(EXIT_FAILURE); } break; case OPT_SHOWCOPYRIGHT: show_copyright(); return EXIT_SUCCESS; break; case OPT_MIRROR: play_mirror_go = 1; break; case OPT_MIRROR_LIMIT: mirror_stones_limit = atoi(gg_optarg); break; case 'v': show_version(); show_copyright(); return EXIT_SUCCESS; break; case 'h': show_version(); if (gg_optarg) { /* In the default behavior of getopt_long with optional args * you need to type "-hdebug" * I can't get long options "--helpdebug" to work at all */ if (strncmp(gg_optarg, "debug", 5) == 0) show_debug_help(); } else { /* This is the trick to get "--help debug" and "-h debug" to work*/ if (gg_optind < argc) { if (strncmp(argv[gg_optind], "debug", 5) == 0) show_debug_help(); } else show_help(); } return EXIT_SUCCESS; break; case OPT_DEBUG_FLAGS: show_debug_flags(); return EXIT_SUCCESS; break; case OPT_PRINT_LEVELS: { int lev; for (lev = 12; lev >= 0; lev--) set_depth_values(lev, 1); } return EXIT_SUCCESS; break; /* NOTE: getopt returns '?' if an illegal option is supplied. */ case '?': default: fprintf(stderr, "Try `gnugo --help' for more information.\n"); exit(EXIT_FAILURE); } } if (requested_boardsize != -1) { if (!check_boardsize(requested_boardsize, stderr)) exit(EXIT_FAILURE); gnugo_clear_board(requested_boardsize); } /* Start random number seed. */ if (!seed_specified) seed = time(0); /* Initialize the GNU Go engine. */ init_gnugo(memory, seed); /* Load Monte Carlo patterns if one has been specified. Either * choose one of the compiled in ones or load directly from a * database file. */ if (strlen(mc_pattern_filename) > 0) { if (!mc_load_patterns_from_db(mc_pattern_filename, NULL)) return EXIT_FAILURE; } else if (strlen(mc_pattern_name) > 0) { if (!choose_mc_patterns(mc_pattern_name)) { fprintf(stderr, "Unknown Monte Carlo pattern database name %s.\n", mc_pattern_name); fprintf(stderr, "Use \"--mc-list-patterns\" to list the available databases.\n"); return EXIT_FAILURE; } } /* Read the infile if there is one. Also play up the position. */ if (infilename) { if (!sgftree_readfile(&sgftree, infilename)) { fprintf(stderr, "Cannot open or parse '%s'\n", infilename); exit(EXIT_FAILURE); } if (gameinfo_play_sgftree_rot(&gameinfo, &sgftree, untilstring, orientation) == EMPTY) { fprintf(stderr, "Cannot load '%s'\n", infilename); exit(EXIT_FAILURE); } } else /* Initialize and empty sgf tree if there was no infile. */ sgftreeCreateHeaderNode(&sgftree, board_size, komi, handicap); /* Set the game_record to be identical to the loaded one or the * newly created empty sgf tree. */ gameinfo.game_record = sgftree; /* Notice that we need to know the board size before we can do this. */ if (debuginfluence_move[0]) { int pos = string_to_location(board_size, debuginfluence_move); debug_influence_move(pos); } /* Figure out a default mode if there was no explicit one. */ if (playmode == MODE_UNKNOWN) { if (infilename) playmode = MODE_LOAD_AND_ANALYZE; else playmode = (isatty(0)) ? MODE_ASCII : MODE_GMP; } if (outfile && playmode != MODE_LOAD_AND_PRINT) { output_check = fopen(outfile, "w"); if (!output_check) { fprintf(stderr, "Error: could not open '%s' for writing\n", outfile); exit(EXIT_FAILURE); } fclose(output_check); } switch (playmode) { case MODE_GMP: case MODE_SGMP: /* not supported by the protocol */ resign_allowed = 0; #if ORACLE if (metamachine) summon_oracle(); #endif /* EMPTY is valid for play_gmp.c. */ gameinfo.computer_player = mandated_color; play_gmp(&gameinfo, playmode == MODE_SGMP); #if ORACLE if (metamachine) dismiss_oracle(); #endif break; case MODE_SOLO: play_solo(&gameinfo, benchmark); break; case MODE_REPLAY: if (!infilename) { fprintf(stderr, "You must use -l infile with replay mode.\n"); exit(EXIT_FAILURE); } play_replay(&sgftree, replay_color); break; case MODE_LOAD_AND_ANALYZE: if (mandated_color != EMPTY) gameinfo.to_move = mandated_color; if (!infilename) { fprintf(stderr, "You must use -l infile with load and analyze mode.\n"); exit(EXIT_FAILURE); } #if ORACLE if (metamachine) { summon_oracle(); oracle_loadsgf(infilename, untilstring); } #endif load_and_analyze_sgf_file(&gameinfo); #if ORACLE dismiss_oracle(); #endif break; case MODE_LOAD_AND_SCORE: if (mandated_color != EMPTY) gameinfo.to_move = mandated_color; if (!infilename) { fprintf(stderr, "gnugo: --score must be used with -l\n"); exit(EXIT_FAILURE); } load_and_score_sgf_file(&sgftree, &gameinfo, scoringmode); break; case MODE_LOAD_AND_PRINT: if (!infilename) { fprintf(stderr, "gnugo: --printsgf must be used with -l\n"); exit(EXIT_FAILURE); } else { if (mandated_color != EMPTY) gameinfo.to_move = mandated_color; sgffile_printsgf(gameinfo.to_move, printsgffile); } break; case MODE_DECIDE_STRING: { int str; if (!infilename) { fprintf(stderr, "gnugo: --decide-string must be used with -l\n"); return EXIT_FAILURE; } str = string_to_location(board_size, decide_this); if (str == NO_MOVE) { fprintf(stderr, "gnugo: --decide-string: strange coordinate \n"); return EXIT_FAILURE; } decide_string(str); } break; case MODE_DECIDE_CONNECTION: { int str1, str2; if (!infilename) { fprintf(stderr, "gnugo: --decide-connection must be used with -l\n"); return EXIT_FAILURE; } str1 = string_to_location(board_size, decide_this); if (str1 == NO_MOVE) { fprintf(stderr, "usage: --decide-connection [first string]/[second string]\n"); return EXIT_FAILURE; } str2 = string_to_location(board_size, decide_that); if (str2 == NO_MOVE) { fprintf(stderr, "usage: --decide-connection [first string]/[second string]\n"); return EXIT_FAILURE; } decide_connection(str1, str2); } break; case MODE_DECIDE_OWL: { int pos; if (!infilename) { fprintf(stderr, "gnugo: --decide-dragon must be used with -l\n"); return EXIT_FAILURE; } pos = string_to_location(board_size, decide_this); if (pos == NO_MOVE) { fprintf(stderr, "gnugo: --decide-dragon: strange coordinate \n"); return EXIT_FAILURE; } decide_owl(pos); } break; case MODE_DECIDE_DRAGON_DATA: { int pos; if (!infilename) { fprintf(stderr, "gnugo: --decide-dragon-data must be used with -l\n"); return EXIT_FAILURE; } pos = string_to_location(board_size, decide_this); if (pos == NO_MOVE) { fprintf(stderr, "gnugo: --decide-dragon-data: strange coordinate \n"); return EXIT_FAILURE; } decide_dragon_data(pos); } break; case MODE_DECIDE_SEMEAI: { int pos1, pos2; if (!infilename) { fprintf(stderr, "gnugo: --decide-semeai must be used with -l\n"); return EXIT_FAILURE; } pos1 = string_to_location(board_size, decide_this); if (pos1 == NO_MOVE) { fprintf(stderr, "usage: --decide-semeai [first dragon]/[second dragon]\n"); return EXIT_FAILURE; } pos2 = string_to_location(board_size, decide_that); if (pos2 == NO_MOVE) { fprintf(stderr, "usage: --decide-semeai [first dragon]/[second dragon]\n"); return EXIT_FAILURE; } decide_semeai(pos1, pos2); } break; case MODE_DECIDE_TACTICAL_SEMEAI: { int pos1, pos2; if (!infilename) { fprintf(stderr, "gnugo: --decide-tactical-semeai must be used with -l\n"); return EXIT_FAILURE; } pos1 = string_to_location(board_size, decide_this); if (pos1 == NO_MOVE) { fprintf(stderr, "usage: --decide-tactical-semeai [first dragon]/[second dragon]\n"); return EXIT_FAILURE; } pos2 = string_to_location(board_size, decide_that); if (pos2 == NO_MOVE) { fprintf(stderr, "usage: --decide-tactical-semeai [first dragon]/[second dragon]\n"); return EXIT_FAILURE; } decide_tactical_semeai(pos1, pos2); } break; case MODE_DECIDE_POSITION: { if (!infilename) { fprintf(stderr, "gnugo: --decide-position must be used with -l\n"); return EXIT_FAILURE; } decide_position(); } break; case MODE_DECIDE_EYE: { int pos; if (!infilename) { fprintf(stderr, "gnugo: --decide-eye must be used with -l\n"); return EXIT_FAILURE; } pos = string_to_location(board_size, decide_this); if (pos == NO_MOVE) { fprintf(stderr, "gnugo: --decide-eye: strange coordinate \n"); return EXIT_FAILURE; } decide_eye(pos); } break; case MODE_DECIDE_COMBINATION: { int color; if (!infilename) { fprintf(stderr, "gnugo: --decide-combination must be used with -l\n"); return EXIT_FAILURE; } color = gameinfo.to_move; if (mandated_color != EMPTY) color = mandated_color; decide_combination(color); } break; case MODE_DECIDE_SURROUNDED: { int pos = string_to_location(board_size, decide_this); if (pos == NO_MOVE) { fprintf(stderr, "usage: --decide-surrounded [pos]\n"); return EXIT_FAILURE; } decide_surrounded(pos); break; } #if ORACLE case MODE_DECIDE_ORACLE: { if (mandated_color != EMPTY) gameinfo.to_move = mandated_color; if (!infilename) { fprintf(stderr, "You must use -l infile with load and analyze mode.\n"); exit(EXIT_FAILURE); } decide_oracle(&gameinfo, infilename, untilstring); break; } #endif case MODE_GTP: { FILE *gtp_input_FILE = stdin; FILE *gtp_output_FILE = stdout; FILE *gtp_dump_commands_FILE = NULL; if (gtpfile != NULL) { gtp_input_FILE = fopen(gtpfile, "r"); if (gtp_input_FILE == NULL) { fprintf(stderr, "gnugo: Cannot open file %s\n", gtpfile); return EXIT_FAILURE; } } else if (gtp_tcp_ip_mode != 0) { unsigned int port = 65536; char *port_string = strchr(gtp_tcp_ip_address, ':'); const char *host_name = NULL; if (port_string) { host_name = gtp_tcp_ip_address; *port_string++ = 0; sscanf(port_string, "%u", &port); } else sscanf(gtp_tcp_ip_address, "%u", &port); if (port > 65535) { fprintf(stderr, "A valid TCP/IP port number expected\n"); exit(EXIT_FAILURE); } if (gtp_tcp_ip_mode == OPT_GTP_CONNECT) { socket_connect_to(host_name, port, >p_input_FILE, >p_output_FILE); } else { socket_listen_at(host_name, port, >p_input_FILE, >p_output_FILE); } } if (gtp_dump_commands_file != NULL) { gtp_dump_commands_FILE = fopen(gtp_dump_commands_file, "w"); if (gtp_dump_commands_FILE == NULL) { fprintf(stderr, "gnugo: Cannot open file %s\n", gtp_dump_commands_file); return EXIT_FAILURE; } } play_gtp(gtp_input_FILE, gtp_output_FILE, gtp_dump_commands_FILE, orientation); if (gtp_dump_commands_FILE) fclose(gtp_dump_commands_FILE); if (gtp_tcp_ip_mode == OPT_GTP_CONNECT) socket_close_connection(gtp_input_FILE, gtp_output_FILE); else if (gtp_tcp_ip_mode == OPT_GTP_LISTEN) socket_stop_listening(gtp_input_FILE, gtp_output_FILE); } break; case MODE_ASCII: default: if (mandated_color != EMPTY) gameinfo.computer_player = OTHER_COLOR(mandated_color); /* Display copyright message in ASCII mode unless --quiet option used. */ if (!quiet) { show_version(); show_copyright(); } #if ORACLE if (metamachine) { summon_oracle(); oracle_loadsgf(infilename, untilstring); } #endif play_ascii(&sgftree, &gameinfo, infilename, untilstring); break; } if (profile_patterns) report_pattern_profiling(); sgfFreeNode(sgftree.root); return 0; } /* end main */ static void show_version(void) { printf("GNU Go %s\n", VERSION); } /* Set the parameters which determine the depth to which * the reading and owl code carries its calculations. */ /* * This string is modelled after the GNU tar --help output. * Since the maximum string length is 2048 bytes in VC++ we * split the help string. */ #define USAGE "\n\ Usage: gnugo [-opts]\n\ \n\ Examples:\n\ gnugo --mode gtp --level 5\n\ To play against gnugo in level 5 from a GTP client\n\ gnugo --mode ascii -l game.sgf -L 123\n\ Resume game at move 123 in ASCII mode\n\ gnugo --score estimate -l game.sgf\n\ Give a rough score estimate of the end position in game.sgf\n\ \n\ Main Options:\n\ --mode Force the playing mode ('ascii', 'gmp', 'sgmp',\n\ or 'gtp'). Default is ASCII.\n\ If no terminal is detected GMP (Go Modem Protocol)\n\ will be assumed.\n\ --quiet --silent Don't print copyright and informational messages\n\ --level strength (default %d)\n\ --never-resign Forbid GNU Go to resign\n\ --resign-allowed Allow resignation (default)\n\ -l, --infile Load name sgf file\n\ -L, --until Stop loading just before move is played. \n\ can be the move number or location (eg L10).\n\ -o, --outfile Write sgf output to file\n\ --printsgf Write position as a diagram to file (use with -l)\n\ \n\ Scoring:\n\ --score estimate estimate score at loaded position\n\ --score finish generate moves to finish game, then score\n\ --score aftermath generate moves to finish, use best algorithm\n\ \n\ " #define USAGE1 "\ Game Options:\n\ Used with --mode ascii (or other modes for non-interactive settings)\n\ --boardsize num Set the board size to use (%d--%d)\n\ --color Choose your color ('black' or 'white')\n\ --handicap Set the number of handicap stones (0--%d)\n\ --komi Set the komi\n\ --clock Initialize the timer.\n\ --byo-time Initialize the byo-yomi timer.\n\ --byo-period Initialize the byo-yomi period.\n\ \n\ --japanese-rules (default)\n\ --chinese-rules\n\ --forbid-suicide Forbid suicide. (default)\n\ --allow-suicide Allow suicide except single-stone suicide.\n\ --allow-all-suicide Allow all suicide moves.\n\ --simple-ko Forbid simple ko recapture. (default)\n\ --no-ko Allow any ko recapture.\n\ --positional-superko Positional superko restrictions.\n\ --situational-superko Situational superko restrictions.\n\ \n\ --play-out-aftermath\n\ --capture-all-dead\n\ \n\ --min-level minimum level for adjustment schemes\n\ --max-level maximum level for adjustment schemes\n\ --autolevel adapt gnugo level during game to respect\n\ the time specified by --clock .\n\ \n\ Connection options\n\ --gtp-input Read gtp commands from file instead of stdin\n\ --gtp-connect [HOST:]PORT\n\ Connect to given host (127.0.0.1 if omitted) and port\n\ and receive GTP commands on the established connection\n\ --gtp-listen [HOST:]PORT\n\ Wait for the first TCP/IP connection on the given port\n\ (if HOST is specified, only to that host)\n\ --gtp-version\n\ \n\ " #define USAGE2 "\ Experimental options:\n\ --with-break-in use the break-in code (on at level 10 by default)\n\ --without-break-in do not use the break-in code\n\ --cosmic-gnugo use center oriented influence\n\ --no-cosmic-gnugo don't use center oriented influence (default)\n\ --large-scale look for large scale captures\n\ --no-large-scale don't seek large scale captures (default)\n\ --nofusekidb turn off fuseki database\n\ --nofuseki turn off fuseki moves entirely\n\ --nojosekidb turn off joseki database\n\ --mirror try to play mirror go\n\ --mirror-limit stop mirroring when n stones on board\n\n\ --monte-carlo enable Monte Carlo move generation (9x9 or smaller)\n\ --mc-games-per-level number of Monte Carlo simulations per level\n\ --mc-list-patterns list names of builtin Monte Carlo patterns\n\ --mc-patterns choose a built in Monte Carlo pattern database\n\ --mc-load-patterns read Monte Carlo patterns from file\n\ --alternate-connections\n\ --experimental-connections\n\ --experimental-owl-ext\n\ --experimental-semeai\n\ --standard-connections\n\ --standard-semeai\n\ --oracle Read the documentation\n\ \n\ Cache size (higher=more memory usage, faster unless swapping occurs):\n\ -M, --cache-size RAM cache for read results (default %4.1f Mb)\n\ \n\ Informative Output:\n\ -v, --version Display the version and copyright of GNU Go\n\ --options Display configure options\n\ -h, --help Display this help message\n\ --help debug Display help about debugging options\n\ --copyright Display copyright notice\n\ \n\ " #define COPYRIGHT \ "Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007\n\ 2008 and 2009 by the Free Software Foundation, Inc.\n\ See http://www.gnu.org/software/gnugo/ or contact\n\ gnugo@gnu.org for information about GNU Go. GNU Go comes with NO WARRANTY to\n\ the extent permitted by law. This program is free software; you can\n\ redistribute it and/or modify it under the terms of the GNU General Public\n\ License as published by the Free Software Foundation - version 3 or\n\ (at your option) any later version. For more\n\ information about these matters, see the files named COPYING.\n" /* USAGE_DEBUG Split in half because of VC limit on constant string * length of 2048 characters!*/ #define USAGE_DEBUG "\n\ Debugging Options:\n\ \n\ --replay replay the moves in a game for color.\n\ (requires -l)\n\ white: replay only white moves\n\ black: replay only black moves\n\ both: replay all moves\n\ -a, --allpats test all patterns\n\ -T, --printboard colored display of dragons\n\ -E, --printeyes colored display of eye spaces\n\ -d, --debug debugging output (see next item for bits)\n\ --debug-flags print the debug flags for previous item\n\ -w, --worms print worm and dragon data and move reasons\n\ -m, --moyo moyo debugging, show moyo board\n\ --debug-influence print influence map after making a move\n\ -b, --benchmark num benchmarking mode - can be used with -l\n\ -S, --statistics print statistics (for debugging purposes)\n\n\ --profile-patterns print statistics for pattern usage\n\ --showtime print timing diagnostic\n\ -t, --trace verbose tracing\n\ -O, --output-flags optional output (use with -o)\n\ d: mark dead and critical dragons\n\ v: show values of considered moves\n\ specify either 'd', 'v' or 'dv' (nothing by default)\n\ --showscore print estimated score\n\ -r, --seed number set random number seed\n\ --gtp-dump-commands dump commands received in GTP mode\n\ --gtp-initial-orientation\n\ --orientation\n\ \n\ " #define USAGE_DEBUG2 "\ Options affecting depth settings and playing strength:\n\ --print-levels shows all this values for levels 12 to 0\n\ \n\ Default values for the default level (%d):\n\ -D, --depth deep reading cutoff (default %d)\n\ -B, --backfill-depth deep reading cutoff (default %d)\n\ -F, --fourlib-depth deep reading cutoff (default %d)\n\ -K, --ko-depth deep reading cutoff (default %d)\n\ --branch-depth deep reading cutoff (default %d)\n\ --backfill2-depth deep reading cutoff (default %d)\n\ --break_chain-depth deep reading cutoff (default %d)\n\ --superstring-depth deep reading cutoff (default %d)\n\ --aa-depth deep reading cutoff (default %d)\n\ --owl-distrust owl distrust depth (default %d)\n\ --owl-branch owl branching depth (default %d)\n\ --owl-reading owl reading depth (default %d)\n\ --owl-node-limit max nodes for owl reading (default %d)\n\ --semeai-node-limit max nodes for semeai reading (default %d)\n\ \n\ Options providing detailed reading results etc.:\n\ --decide-string can this string live? (try with -o)\n\ --decide-connection can these strings connect? (try with -o)\n\ --decide-dragon can this dragon live? (try with -o or -t)\n\ --decide-dragon-data\n\ --decide-owl\n\ --decide-position evaluate all dragons (try with -o or -t)\n\ --decide-eye evaluate the eye\n\ --decide-combination search for combination attack (try with -o)\n\ --decide-oracle\n\ --decide-semeai\n\ --decide-tactical-semeai\n\ --decide-surrounded\n\ --limit-search\n\ \n\ " /* * Since the maximum string length is 2048 bytes in VC++ we * split the help string. */ static void show_help(void) { printf(USAGE, DEFAULT_LEVEL); printf(USAGE1, MIN_BOARD, MAX_BOARD, MAX_HANDICAP); printf(USAGE2, DEFAULT_MEMORY <= 0 ? reading_cache_default_size() : (float) DEFAULT_MEMORY); } static void show_debug_help(void) { set_depth_values(DEFAULT_LEVEL,0); printf(USAGE_DEBUG USAGE_DEBUG2, DEFAULT_LEVEL, depth, backfill_depth, fourlib_depth, ko_depth, branch_depth, backfill2_depth, break_chain_depth, superstring_depth, aa_depth, owl_distrust_depth, owl_branch_depth, owl_reading_depth, owl_node_limit, semeai_node_limit); } static void show_debug_flags(void) { printf(DEBUG_FLAGS); } static void show_copyright(void) { printf(COPYRIGHT); } #ifdef ENABLE_SOCKET_SUPPORT #if !defined(_WIN32) && !defined(_WIN32_WCE) #include #include #include #include #define closesocket close #define init_sockets() #else /* on Windows */ #include static void init_sockets(void) { WSADATA data; WORD version = MAKEWORD(1, 1); if (WSAStartup(version, &data) != NO_ERROR) { fprintf(stderr, "WSAStartup() failed with error %d\n", WSAGetLastError()); exit(EXIT_FAILURE); } } #endif /* on Windows */ static void socket_connect_to(const char *host_name, unsigned int port, FILE **input_file, FILE **output_file) { struct sockaddr_in address; int connection_socket; struct hostent *host_data; char **address_pointer; init_sockets(); if (!host_name) host_name = "127.0.0.1"; host_data = gethostbyname(host_name); if (!host_data || host_data->h_addrtype != AF_INET || host_data->h_length != sizeof address.sin_addr) { fprintf(stderr, "Failed to resolve host name `%s'\n", host_name); exit(EXIT_FAILURE); } connection_socket = socket(PF_INET, SOCK_STREAM, 0); if (connection_socket == -1) { fprintf(stderr, "Unexpected error: failed to create a socket\n"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_port = htons((unsigned short) port); for (address_pointer = host_data->h_addr_list; *address_pointer; address_pointer++) { memcpy(&address.sin_addr, *address_pointer, sizeof address.sin_addr); if (connect(connection_socket, (struct sockaddr *) &address, sizeof address) != -1) break; } if (! *address_pointer) { fprintf(stderr, "Failed to connect to %s:%u\n", host_data->h_name, port); closesocket(connection_socket); exit(EXIT_FAILURE); } #if !USE_WINDOWS_SOCKET_CLUDGE *input_file = fdopen(connection_socket, "r"); *output_file = fdopen(dup(connection_socket), "w"); #else /* USE_WINDOWS_SOCKET_CLUDGE */ winsocket_activate(connection_socket); *input_file = NULL; *output_file = NULL; #endif /* USE_WINDOWS_SOCKET_CLUDGE */ } static void socket_listen_at(const char *host_name, unsigned int port, FILE **input_file, FILE **output_file) { struct sockaddr_in address; int listening_socket; int connection_socket; init_sockets(); if (host_name) { struct hostent *host_data; host_data = gethostbyname(host_name); if (!host_data || host_data->h_addrtype != AF_INET || host_data->h_length != sizeof address.sin_addr) { fprintf(stderr, "Failed to resolve host name `%s'\n", host_name); exit(EXIT_FAILURE); } host_name = host_data->h_name; memcpy(&address.sin_addr, host_data->h_addr_list[0], sizeof address.sin_addr); } else address.sin_addr.s_addr = htonl(INADDR_ANY); listening_socket = socket(PF_INET, SOCK_STREAM, 0); if (listening_socket == -1) { fprintf(stderr, "Unexpected error: failed to create a socket\n"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_port = htons((unsigned short) port); if (verbose) { if (host_name) { fprintf(stderr, "Waiting for a connection on %s:%u...\n", host_name, port); } else fprintf(stderr, "Waiting for a connection on port %u...\n", port); } if (bind(listening_socket, (struct sockaddr *) &address, sizeof address) == -1 || listen(listening_socket, 0) == -1 || (connection_socket = accept(listening_socket, NULL, NULL)) == -1) { if (host_name) fprintf(stderr, "Failed to listen on %s:%u\n", host_name, port); else fprintf(stderr, "Failed to listen on port %u\n", port); closesocket(listening_socket); exit(EXIT_FAILURE); } closesocket(listening_socket); #if !USE_WINDOWS_SOCKET_CLUDGE *input_file = fdopen(connection_socket, "r"); *output_file = fdopen(dup(connection_socket), "w"); #else /* USE_WINDOWS_SOCKET_CLUDGE */ winsocket_activate(connection_socket); *input_file = NULL; *output_file = NULL; #endif /* USE_WINDOWS_SOCKET_CLUDGE */ } static void socket_close_connection(FILE *input_file, FILE *output_file) { /* When connecting, we close the socket first. */ fclose(input_file); fclose(output_file); } static void socket_stop_listening(FILE *input_file, FILE *output_file) { int buffer[0x1000]; if (verbose) fprintf(stderr, "Waiting for the client to disconnect...\n"); /* When listening, we wait for the client to disconnect first. * Otherwise, socket doesn't get released properly. */ do fread(buffer, sizeof buffer, 1, input_file); while (!feof(input_file)); fclose(input_file); fclose(output_file); } #else /* not ENABLE_SOCKET_SUPPORT */ static void socket_connect_to(const char *host_name, unsigned int port, FILE **input_file, FILE **output_file) { UNUSED(host_name); UNUSED(port); UNUSED(input_file); UNUSED(output_file); fprintf(stderr, "GNU Go was compiled without socket support, unable to connect\n"); exit(EXIT_FAILURE); } static void socket_listen_at(const char *host_name, unsigned int port, FILE **input_file, FILE **output_file) { UNUSED(host_name); UNUSED(port); UNUSED(input_file); UNUSED(output_file); fprintf(stderr, "GNU Go was compiled without socket support, unable to listen\n"); exit(EXIT_FAILURE); } static void socket_close_connection(FILE *input_file, FILE *output_file) { UNUSED(input_file); UNUSED(output_file); } static void socket_stop_listening(FILE *input_file, FILE *output_file) { UNUSED(input_file); UNUSED(output_file); } #endif /* not ENABLE_SOCKET_SUPPORT */ /* * Local Variables: * tab-width: 8 * c-basic-offset: 2 * End: */