From c150f57c2a3b22ee777104daa7243e2ede38c87e Mon Sep 17 00:00:00 2001 From: Aaron Taylor Date: Sun, 23 May 2021 23:37:11 -0700 Subject: [PATCH] Before starting to tinker, ran clang-format on files that seem like relevant starting points. For now, I'm simply using `--style=webkit`. --- interface/gtp.c | 576 +++-- interface/interface.h | 28 +- interface/main.c | 3038 ++++++++++++------------- interface/play_ascii.c | 2218 +++++++++--------- interface/play_gmp.c | 400 ++-- interface/play_gtp.c | 4904 +++++++++++++++++++--------------------- interface/play_solo.c | 442 ++-- interface/play_test.c | 295 ++- 8 files changed, 5857 insertions(+), 6044 deletions(-) diff --git a/interface/gtp.c b/interface/gtp.c index f4d58bc..27ca829 100644 --- a/interface/gtp.c +++ b/interface/gtp.c @@ -38,19 +38,19 @@ * without prior written authorization of the copyright holder. * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#include +#include #include #include -#include -#include #include "gtp.h" /* These are copied from gnugo.h. We don't include this file in order * to remain as independent as possible of GNU Go internals. */ -#define EMPTY 0 -#define WHITE 1 -#define BLACK 2 +#define EMPTY 0 +#define WHITE 1 +#define BLACK 2 /* We need to keep track of the board size in order to be able to * convert between coordinate descriptions. We could also have passed @@ -73,89 +73,86 @@ static int current_id; * of this file may want to use functions other than gtp_printf() etc. * Set by gtp_main_loop(). */ -FILE *gtp_output_file = NULL; - +FILE* gtp_output_file = NULL; /* Read filehandle gtp_input linewise and interpret as GTP commands. */ -void -gtp_main_loop(struct gtp_command commands[], - FILE *gtp_input, FILE *gtp_output, FILE *gtp_dump_commands) +void gtp_main_loop(struct gtp_command commands[], + FILE* gtp_input, FILE* gtp_output, FILE* gtp_dump_commands) { - char line[GTP_BUFSIZE]; - char command[GTP_BUFSIZE]; - char *p; - int i; - int n; - int status = GTP_OK; - - gtp_output_file = gtp_output; - - while (status == GTP_OK) { - /* Read a line from gtp_input. */ - if (!fgets(line, GTP_BUFSIZE, gtp_input)) - break; /* EOF or some error */ - - if (gtp_dump_commands) { - fputs(line, gtp_dump_commands); - fflush(gtp_dump_commands); - } - - /* Preprocess the line. */ - for (i = 0, p = line; line[i]; i++) { - char c = line[i]; - /* Convert HT (9) to SPACE (32). */ - if (c == 9) - *p++ = 32; - /* Remove CR (13) and all other control characters except LF (10). */ - else if ((c > 0 && c <= 9) - || (c >= 11 && c <= 31) - || c == 127) - continue; - /* Remove comments. */ - else if (c == '#') - break; - /* Keep ordinary text. */ - else - *p++ = c; - } - /* Terminate string. */ - *p = 0; - - p = line; - - /* Look for an identification number. */ - if (sscanf(p, "%d%n", ¤t_id, &n) == 1) - p += n; - else - current_id = -1; /* No identification number. */ - - /* Look for command name. */ - if (sscanf(p, " %s %n", command, &n) < 1) - continue; /* Whitespace only on this line, ignore. */ - p += n; - - /* Search the list of commands and call the corresponding function + char line[GTP_BUFSIZE]; + char command[GTP_BUFSIZE]; + char* p; + int i; + int n; + int status = GTP_OK; + + gtp_output_file = gtp_output; + + while (status == GTP_OK) { + /* Read a line from gtp_input. */ + if (!fgets(line, GTP_BUFSIZE, gtp_input)) + break; /* EOF or some error */ + + if (gtp_dump_commands) { + fputs(line, gtp_dump_commands); + fflush(gtp_dump_commands); + } + + /* Preprocess the line. */ + for (i = 0, p = line; line[i]; i++) { + char c = line[i]; + /* Convert HT (9) to SPACE (32). */ + if (c == 9) + *p++ = 32; + /* Remove CR (13) and all other control characters except LF (10). */ + else if ((c > 0 && c <= 9) + || (c >= 11 && c <= 31) + || c == 127) + continue; + /* Remove comments. */ + else if (c == '#') + break; + /* Keep ordinary text. */ + else + *p++ = c; + } + /* Terminate string. */ + *p = 0; + + p = line; + + /* Look for an identification number. */ + if (sscanf(p, "%d%n", ¤t_id, &n) == 1) + p += n; + else + current_id = -1; /* No identification number. */ + + /* Look for command name. */ + if (sscanf(p, " %s %n", command, &n) < 1) + continue; /* Whitespace only on this line, ignore. */ + p += n; + + /* Search the list of commands and call the corresponding function * if it's found. */ - for (i = 0; commands[i].name != NULL; i++) { - if (strcmp(command, commands[i].name) == 0) { - status = (*commands[i].function)(p); - break; - } + for (i = 0; commands[i].name != NULL; i++) { + if (strcmp(command, commands[i].name) == 0) { + status = (*commands[i].function)(p); + break; + } + } + if (commands[i].name == NULL) + gtp_failure("unknown command"); + + if (status == GTP_FATAL) + gtp_panic(); } - if (commands[i].name == NULL) - gtp_failure("unknown command"); - - if (status == GTP_FATAL) - gtp_panic(); - } } /* Set the board size used in coordinate conversions. */ -void -gtp_internal_set_boardsize(int size) +void gtp_internal_set_boardsize(int size) { - gtp_boardsize = size; + gtp_boardsize = size; } /* If you need to transform the coordinates on input or output, use @@ -163,11 +160,10 @@ gtp_internal_set_boardsize(int size) * coordinates are read or about to be written. In GNU Go this is used * to simulate rotated boards in regression tests. */ -void -gtp_set_vertex_transform_hooks(gtp_transform_ptr in, gtp_transform_ptr out) +void gtp_set_vertex_transform_hooks(gtp_transform_ptr in, gtp_transform_ptr out) { - vertex_transform_input_hook = in; - vertex_transform_output_hook = out; + vertex_transform_input_hook = in; + vertex_transform_output_hook = out; } /* @@ -176,240 +172,215 @@ gtp_set_vertex_transform_hooks(gtp_transform_ptr in, gtp_transform_ptr out) * But it also accepts %m, which takes two integers and writes a vertex, * and %C, which takes a color value and writes a color string. */ -void -gtp_mprintf(const char *fmt, ...) +void gtp_mprintf(const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - - for (; *fmt; ++fmt) { - if (*fmt == '%') { - switch (*++fmt) { - case 'c': - { - /* rules of promotion => passed as int, not char */ - int c = va_arg(ap, int); - putc(c, gtp_output_file); - break; - } - case 'd': - { - int d = va_arg(ap, int); - fprintf(gtp_output_file, "%d", d); - break; - } - case 'f': - { - double f = va_arg(ap, double); /* passed as double, not float */ - fprintf(gtp_output_file, "%f", f); - break; - } - case 's': - { - char *s = va_arg(ap, char *); - fputs(s, gtp_output_file); - break; - } - case 'm': - { - int m = va_arg(ap, int); - int n = va_arg(ap, int); - gtp_print_vertex(m, n); - break; - } - case 'C': - { - int color = va_arg(ap, int); - if (color == WHITE) - fputs("white", gtp_output_file); - else if (color == BLACK) - fputs("black", gtp_output_file); - else - fputs("empty", gtp_output_file); - break; - } - default: - /* FIXME: Should go to `stderr' instead? */ - fprintf(gtp_output_file, "\n\nUnknown format character '%c'\n", *fmt); - break; - } + va_list ap; + va_start(ap, fmt); + + for (; *fmt; ++fmt) { + if (*fmt == '%') { + switch (*++fmt) { + case 'c': { + /* rules of promotion => passed as int, not char */ + int c = va_arg(ap, int); + putc(c, gtp_output_file); + break; + } + case 'd': { + int d = va_arg(ap, int); + fprintf(gtp_output_file, "%d", d); + break; + } + case 'f': { + double f = va_arg(ap, double); /* passed as double, not float */ + fprintf(gtp_output_file, "%f", f); + break; + } + case 's': { + char* s = va_arg(ap, char*); + fputs(s, gtp_output_file); + break; + } + case 'm': { + int m = va_arg(ap, int); + int n = va_arg(ap, int); + gtp_print_vertex(m, n); + break; + } + case 'C': { + int color = va_arg(ap, int); + if (color == WHITE) + fputs("white", gtp_output_file); + else if (color == BLACK) + fputs("black", gtp_output_file); + else + fputs("empty", gtp_output_file); + break; + } + default: + /* FIXME: Should go to `stderr' instead? */ + fprintf(gtp_output_file, "\n\nUnknown format character '%c'\n", *fmt); + break; + } + } else + putc(*fmt, gtp_output_file); } - else - putc(*fmt, gtp_output_file); - } - va_end(ap); + va_end(ap); } - /* This currently works exactly like printf. */ -void -gtp_printf(const char *format, ...) +void gtp_printf(const char* format, ...) { - va_list ap; - va_start(ap, format); - vfprintf(gtp_output_file, format, ap); - va_end(ap); + va_list ap; + va_start(ap, format); + vfprintf(gtp_output_file, format, ap); + va_end(ap); } - /* Write success or failure indication plus identity number if one was * given. */ -void -gtp_start_response(int status) +void gtp_start_response(int status) { - if (status == GTP_SUCCESS) - gtp_printf("="); - else - gtp_printf("?"); - - if (current_id < 0) - gtp_printf(" "); - else - gtp_printf("%d ", current_id); -} + if (status == GTP_SUCCESS) + gtp_printf("="); + else + gtp_printf("?"); + if (current_id < 0) + gtp_printf(" "); + else + gtp_printf("%d ", current_id); +} /* Finish a GTP response by writing a double newline and returning GTP_OK. */ -int -gtp_finish_response() +int gtp_finish_response() { - gtp_printf("\n\n"); - return GTP_OK; + gtp_printf("\n\n"); + return GTP_OK; } - /* Write a full success response. Except for the id number, the call * is just like one to printf. */ -int -gtp_success(const char *format, ...) +int gtp_success(const char* format, ...) { - va_list ap; - gtp_start_response(GTP_SUCCESS); - va_start(ap, format); - vfprintf(gtp_output_file, format, ap); - va_end(ap); - return gtp_finish_response(); + va_list ap; + gtp_start_response(GTP_SUCCESS); + va_start(ap, format); + vfprintf(gtp_output_file, format, ap); + va_end(ap); + return gtp_finish_response(); } - /* Write a full failure response. The call is identical to gtp_success. */ -int -gtp_failure(const char *format, ...) +int gtp_failure(const char* format, ...) { - va_list ap; - gtp_start_response(GTP_FAILURE); - va_start(ap, format); - vfprintf(gtp_output_file, format, ap); - va_end(ap); - return gtp_finish_response(); + va_list ap; + gtp_start_response(GTP_FAILURE); + va_start(ap, format); + vfprintf(gtp_output_file, format, ap); + va_end(ap); + return gtp_finish_response(); } - /* Write a panic message. */ -void -gtp_panic() +void gtp_panic() { - gtp_printf("! panic\n\n"); + gtp_printf("! panic\n\n"); } - /* Convert a string describing a color, "b", "black", "w", or "white", * to GNU Go's integer representation of colors. Return the number of * characters read from the string s. */ -int -gtp_decode_color(char *s, int *color) +int gtp_decode_color(char* s, int* color) { - char color_string[7]; - int i; - int n; - - assert(gtp_boardsize > 0); - - if (sscanf(s, "%6s%n", color_string, &n) != 1) - return 0; - - for (i = 0; i < (int) strlen(color_string); i++) - color_string[i] = tolower((int) color_string[i]); - - if (strcmp(color_string, "b") == 0 - || strcmp(color_string, "black") == 0) - *color = BLACK; - else if (strcmp(color_string, "w") == 0 - || strcmp(color_string, "white") == 0) - *color = WHITE; - else - return 0; - - return n; -} + char color_string[7]; + int i; + int n; + + assert(gtp_boardsize > 0); + + if (sscanf(s, "%6s%n", color_string, &n) != 1) + return 0; + for (i = 0; i < (int)strlen(color_string); i++) + color_string[i] = tolower((int)color_string[i]); + + if (strcmp(color_string, "b") == 0 + || strcmp(color_string, "black") == 0) + *color = BLACK; + else if (strcmp(color_string, "w") == 0 + || strcmp(color_string, "white") == 0) + *color = WHITE; + else + return 0; + + return n; +} /* Convert an intersection given by a string to two coordinates * according to GNU Go's convention. Return the number of characters * read from the string s. */ -int -gtp_decode_coord(char *s, int *i, int *j) +int gtp_decode_coord(char* s, int* i, int* j) { - char column; - int row; - int n; + char column; + int row; + int n; - assert(gtp_boardsize > 0); + assert(gtp_boardsize > 0); - if (sscanf(s, " %c%d%n", &column, &row, &n) != 2) - return 0; - - if (tolower((int) column) == 'i') - return 0; - *j = tolower((int) column) - 'a'; - if (tolower((int) column) > 'i') - --*j; + if (sscanf(s, " %c%d%n", &column, &row, &n) != 2) + return 0; - *i = gtp_boardsize - row; + if (tolower((int)column) == 'i') + return 0; + *j = tolower((int)column) - 'a'; + if (tolower((int)column) > 'i') + --*j; - if (*i < 0 || *i >= gtp_boardsize || *j < 0 || *j >= gtp_boardsize) - return 0; + *i = gtp_boardsize - row; - if (vertex_transform_input_hook != NULL) - (*vertex_transform_input_hook)(*i, *j, i, j); + if (*i < 0 || *i >= gtp_boardsize || *j < 0 || *j >= gtp_boardsize) + return 0; - return n; + if (vertex_transform_input_hook != NULL) + (*vertex_transform_input_hook)(*i, *j, i, j); + + return n; } /* Convert a move, i.e. "b" or "w" followed by a vertex to a color and * coordinates. Return the number of characters read from the string * s. The vertex may be "pass" and then the coordinates are set to (-1, -1). */ -int -gtp_decode_move(char *s, int *color, int *i, int *j) +int gtp_decode_move(char* s, int* color, int* i, int* j) { - int n1, n2; - int k; - - assert(gtp_boardsize > 0); - - n1 = gtp_decode_color(s, color); - if (n1 == 0) - return 0; - - n2 = gtp_decode_coord(s + n1, i, j); - if (n2 == 0) { - char buf[6]; - if (sscanf(s + n1, "%5s%n", buf, &n2) != 1) - return 0; - for (k = 0; k < (int) strlen(buf); k++) - buf[k] = tolower((int) buf[k]); - if (strcmp(buf, "pass") != 0) - return 0; - *i = -1; - *j = -1; - } - - return n1 + n2; + int n1, n2; + int k; + + assert(gtp_boardsize > 0); + + n1 = gtp_decode_color(s, color); + if (n1 == 0) + return 0; + + n2 = gtp_decode_coord(s + n1, i, j); + if (n2 == 0) { + char buf[6]; + if (sscanf(s + n1, "%5s%n", buf, &n2) != 1) + return 0; + for (k = 0; k < (int)strlen(buf); k++) + buf[k] = tolower((int)buf[k]); + if (strcmp(buf, "pass") != 0) + return 0; + *i = -1; + *j = -1; + } + + return n1 + n2; } /* This a bubble sort. Given the expected size of the sets to @@ -419,66 +390,63 @@ gtp_decode_move(char *s, int *color, int *i, int *j) static void sort_moves(int n, int movei[], int movej[]) { - int b, a; - for (b = n-1; b > 0; b--) { - for (a = 0; a < b; a++) { - if (movei[a] > movei[b] - || (movei[a] == movei[b] && movej[a] > movej[b])) { - int tmp; - tmp = movei[b]; - movei[b] = movei[a]; - movei[a] = tmp; - tmp = movej[b]; - movej[b] = movej[a]; - movej[a] = tmp; - } + int b, a; + for (b = n - 1; b > 0; b--) { + for (a = 0; a < b; a++) { + if (movei[a] > movei[b] + || (movei[a] == movei[b] && movej[a] > movej[b])) { + int tmp; + tmp = movei[b]; + movei[b] = movei[a]; + movei[a] = tmp; + tmp = movej[b]; + movej[b] = movej[a]; + movej[a] = tmp; + } + } } - } } /* Write a number of space separated vertices. The moves are sorted * before being written. */ -void -gtp_print_vertices(int n, int movei[], int movej[]) +void gtp_print_vertices(int n, int movei[], int movej[]) { - int k; - int ri, rj; - - assert(gtp_boardsize > 0); - - sort_moves(n, movei, movej); - for (k = 0; k < n; k++) { - if (k > 0) - gtp_printf(" "); - if (movei[k] == -1 && movej[k] == -1) - gtp_printf("PASS"); - else if (movei[k] < 0 || movei[k] >= gtp_boardsize - || movej[k] < 0 || movej[k] >= gtp_boardsize) - gtp_printf("??"); - else { - if (vertex_transform_output_hook != NULL) - (*vertex_transform_output_hook)(movei[k], movej[k], &ri, &rj); - else { - ri = movei[k]; - rj = movej[k]; - } - gtp_printf("%c%d", 'A' + rj + (rj >= 8), gtp_boardsize - ri); + int k; + int ri, rj; + + assert(gtp_boardsize > 0); + + sort_moves(n, movei, movej); + for (k = 0; k < n; k++) { + if (k > 0) + gtp_printf(" "); + if (movei[k] == -1 && movej[k] == -1) + gtp_printf("PASS"); + else if (movei[k] < 0 || movei[k] >= gtp_boardsize + || movej[k] < 0 || movej[k] >= gtp_boardsize) + gtp_printf("??"); + else { + if (vertex_transform_output_hook != NULL) + (*vertex_transform_output_hook)(movei[k], movej[k], &ri, &rj); + else { + ri = movei[k]; + rj = movej[k]; + } + gtp_printf("%c%d", 'A' + rj + (rj >= 8), gtp_boardsize - ri); + } } - } } /* Write a single move. */ -void -gtp_print_vertex(int i, int j) +void gtp_print_vertex(int i, int j) { - gtp_print_vertices(1, &i, &j); + gtp_print_vertices(1, &i, &j); } - /* * Local Variables: - * tab-width: 8 - * c-basic-offset: 2 + * tab-width: 4 + * c-basic-offset: 4 * End: */ diff --git a/interface/interface.h b/interface/interface.h index 8412f24..cc25ae2 100644 --- a/interface/interface.h +++ b/interface/interface.h @@ -32,25 +32,23 @@ #include "gnugo.h" #include "sgftree.h" -void play_ascii(SGFTree *tree, Gameinfo *gameinfo, - char *filename, char *until); -void play_gtp(FILE *gtp_input, FILE *gtp_output, FILE *gtp_dump_commands, - int gtp_initial_orientation); -void play_gmp(Gameinfo *gameinfo, int simplified); -void play_solo(Gameinfo *gameinfo, int benchmark); -void play_replay(SGFTree *tree, int color_to_test); - -void load_and_analyze_sgf_file(Gameinfo *gameinfo); -void load_and_score_sgf_file(SGFTree *tree, Gameinfo *gameinfo, - const char *scoringmode); - +void play_ascii(SGFTree* tree, Gameinfo* gameinfo, + char* filename, char* until); +void play_gtp(FILE* gtp_input, FILE* gtp_output, FILE* gtp_dump_commands, + int gtp_initial_orientation); +void play_gmp(Gameinfo* gameinfo, int simplified); +void play_solo(Gameinfo* gameinfo, int benchmark); +void play_replay(SGFTree* tree, int color_to_test); + +void load_and_analyze_sgf_file(Gameinfo* gameinfo); +void load_and_score_sgf_file(SGFTree* tree, Gameinfo* gameinfo, + const char* scoringmode); #endif - /* * Local Variables: - * tab-width: 8 - * c-basic-offset: 2 + * tab-width: 4 + * c-basic-offset: 4 * End: */ diff --git a/interface/main.c b/interface/main.c index dfb0aed..7435dff 100644 --- a/interface/main.c +++ b/interface/main.c @@ -23,10 +23,10 @@ #include "gnugo.h" +#include #include #include #include -#include #ifdef HAVE_UNISTD_H /* For isatty(). */ @@ -36,14 +36,14 @@ #endif #if TIME_WITH_SYS_TIME -# include -# include +#include +#include +#else +#if HAVE_SYS_TIME_H +#include #else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif +#include +#endif #endif #include "liberty.h" @@ -53,8 +53,8 @@ #include "winsocket.h" #include "interface.h" -#include "sgftree.h" #include "random.h" +#include "sgftree.h" static void show_copyright(void); static void show_version(void); @@ -62,137 +62,135 @@ 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); - +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 +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 + 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. @@ -200,1300 +198,1289 @@ enum mode { * 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} +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[]) +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 + 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 + 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 (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); } - 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 + /* 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; + 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 + /* 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. + 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); + 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); } - fclose(output_check); - } - switch (playmode) { - case MODE_GMP: - case MODE_SGMP: + switch (playmode) { + case MODE_GMP: + case MODE_SGMP: - /* not supported by the protocol */ - resign_allowed = 0; + /* not supported by the protocol */ + resign_allowed = 0; #if ORACLE - if (metamachine) - summon_oracle(); + if (metamachine) + summon_oracle(); #endif - /* EMPTY is valid for play_gmp.c. */ - gameinfo.computer_player = mandated_color; - play_gmp(&gameinfo, playmode == MODE_SGMP); + /* EMPTY is valid for play_gmp.c. */ + gameinfo.computer_player = mandated_color; + play_gmp(&gameinfo, playmode == MODE_SGMP); #if ORACLE - if (metamachine) - dismiss_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); - } + 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); - } + if (metamachine) { + summon_oracle(); + oracle_loadsgf(infilename, untilstring); + } #endif - load_and_analyze_sgf_file(&gameinfo); + load_and_analyze_sgf_file(&gameinfo); #if ORACLE - dismiss_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); - } + break; - else { - if (mandated_color != EMPTY) - gameinfo.to_move = mandated_color; + case MODE_LOAD_AND_SCORE: + 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 (!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; + 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); + 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); + 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(); - } + /* 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); - } + 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); + play_ascii(&sgftree, &gameinfo, infilename, untilstring); + break; + } - return 0; -} /* end main */ + if (profile_patterns) + report_pattern_profiling(); + sgfFreeNode(sgftree.root); + return 0; +} /* end main */ static void show_version(void) { - printf("GNU Go %s\n", VERSION); + 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\ @@ -1607,7 +1594,7 @@ Informative Output:\n\ " #define COPYRIGHT \ -"Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007\n\ + "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\ @@ -1689,7 +1676,6 @@ Options providing detailed reading results etc.:\n\ \n\ " - /* * Since the maximum string length is 2048 bytes in VC++ we * split the help string. @@ -1697,292 +1683,274 @@ Options providing detailed reading results etc.:\n\ 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); + 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); + 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 +static void show_debug_flags(void) { - printf(DEBUG_FLAGS); + printf(DEBUG_FLAGS); } static void show_copyright(void) { - printf(COPYRIGHT); + printf(COPYRIGHT); } - #ifdef ENABLE_SOCKET_SUPPORT - #if !defined(_WIN32) && !defined(_WIN32_WCE) -#include -#include #include #include +#include +#include -#define closesocket close +#define closesocket close #define init_sockets() -#else /* on Windows */ - +#else /* on Windows */ #include - static void init_sockets(void) { - WSADATA data; - WORD version = MAKEWORD(1, 1); + 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); - } + if (WSAStartup(version, &data) != NO_ERROR) { + fprintf(stderr, "WSAStartup() failed with error %d\n", WSAGetLastError()); + exit(EXIT_FAILURE); + } } - -#endif /* on Windows */ - +#endif /* on Windows */ static void -socket_connect_to(const char *host_name, unsigned int port, - FILE **input_file, FILE **output_file) +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; + struct sockaddr_in address; + int connection_socket; + struct hostent* host_data; + char** address_pointer; - init_sockets(); + init_sockets(); - if (!host_name) - host_name = "127.0.0.1"; + 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); - } + 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); - } + 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"); + *input_file = fdopen(connection_socket, "r"); + *output_file = fdopen(dup(connection_socket), "w"); -#else /* USE_WINDOWS_SOCKET_CLUDGE */ +#else /* USE_WINDOWS_SOCKET_CLUDGE */ - winsocket_activate(connection_socket); + winsocket_activate(connection_socket); - *input_file = NULL; - *output_file = NULL; + *input_file = NULL; + *output_file = NULL; -#endif /* USE_WINDOWS_SOCKET_CLUDGE */ +#endif /* USE_WINDOWS_SOCKET_CLUDGE */ } - static void -socket_listen_at(const char *host_name, unsigned int port, - FILE **input_file, FILE **output_file) +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; + struct sockaddr_in address; + int listening_socket; + int connection_socket; - init_sockets(); + 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); + 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); } - 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); + address.sin_family = AF_INET; + address.sin_port = htons((unsigned short)port); - 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 (verbose) { - if (host_name) { - fprintf(stderr, "Waiting for a connection on %s:%u...\n", - host_name, 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); } - 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"); + *input_file = fdopen(connection_socket, "r"); + *output_file = fdopen(dup(connection_socket), "w"); -#else /* USE_WINDOWS_SOCKET_CLUDGE */ +#else /* USE_WINDOWS_SOCKET_CLUDGE */ - winsocket_activate(connection_socket); + winsocket_activate(connection_socket); - *input_file = NULL; - *output_file = NULL; + *input_file = NULL; + *output_file = NULL; -#endif /* USE_WINDOWS_SOCKET_CLUDGE */ +#endif /* USE_WINDOWS_SOCKET_CLUDGE */ } - static void -socket_close_connection(FILE *input_file, FILE *output_file) +socket_close_connection(FILE* input_file, FILE* output_file) { - /* When connecting, we close the socket first. */ - fclose(input_file); - fclose(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) +socket_stop_listening(FILE* input_file, FILE* output_file) { - int buffer[0x1000]; + int buffer[0x1000]; - if (verbose) - fprintf(stderr, "Waiting for the client to disconnect...\n"); + if (verbose) + fprintf(stderr, "Waiting for the client to disconnect...\n"); - /* When listening, we wait for the client to disconnect first. + /* 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)); + do + fread(buffer, sizeof buffer, 1, input_file); + while (!feof(input_file)); - fclose(input_file); - fclose(output_file); + fclose(input_file); + fclose(output_file); } - -#else /* not ENABLE_SOCKET_SUPPORT */ - +#else /* not ENABLE_SOCKET_SUPPORT */ static void -socket_connect_to(const char *host_name, unsigned int port, - FILE **input_file, FILE **output_file) +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); + 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); + 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) +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); + 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); + 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) +socket_close_connection(FILE* input_file, FILE* output_file) { - UNUSED(input_file); - UNUSED(output_file); + UNUSED(input_file); + UNUSED(output_file); } - static void -socket_stop_listening(FILE *input_file, FILE *output_file) +socket_stop_listening(FILE* input_file, FILE* output_file) { - UNUSED(input_file); - UNUSED(output_file); + UNUSED(input_file); + UNUSED(output_file); } - -#endif /* not ENABLE_SOCKET_SUPPORT */ - +#endif /* not ENABLE_SOCKET_SUPPORT */ /* * Local Variables: - * tab-width: 8 - * c-basic-offset: 2 + * tab-width: 4 + * c-basic-offset: 4 * End: */ diff --git a/interface/play_ascii.c b/interface/play_ascii.c index 57465f7..f091af9 100644 --- a/interface/play_ascii.c +++ b/interface/play_ascii.c @@ -23,20 +23,20 @@ #include "gnugo.h" +#include #include #include #include -#include #if READLINE -#include #include +#include #endif -#include "liberty.h" +#include "gg_utils.h" #include "interface.h" +#include "liberty.h" #include "sgftree.h" -#include "gg_utils.h" #define DEBUG_COMMANDS "\ capture try to capture indicated group\n\ @@ -62,13 +62,13 @@ static int clock_on = 0; /* Keep track of the score estimated before the last computer move. */ static int current_score_estimate = NO_SCORE; -static void do_play_ascii(Gameinfo *gameinfo); -static int ascii_endgame(Gameinfo *gameinfo, int reason); -static void ascii_count(Gameinfo *gameinfo); -static void showcapture(char *line); -static void showdefense(char *line); -static void ascii_goto(Gameinfo *gameinfo, char *line); -static void ascii_free_handicap(Gameinfo *gameinfo, char *handicap_string); +static void do_play_ascii(Gameinfo* gameinfo); +static int ascii_endgame(Gameinfo* gameinfo, int reason); +static void ascii_count(Gameinfo* gameinfo); +static void showcapture(char* line); +static void showdefense(char* line); +static void ascii_goto(Gameinfo* gameinfo, char* line); +static void ascii_free_handicap(Gameinfo* gameinfo, char* handicap_string); /* If sgf game info is written can't reset parameters like handicap, etc. */ static int sgf_initialized; @@ -78,27 +78,26 @@ static int sgf_initialized; */ static void -make_letterbar(int boardsize, char *letterbar) +make_letterbar(int boardsize, char* letterbar) { - int i, letteroffset; - char spaces[64]; - char letter[64]; - - if (boardsize <= 25) - strcpy(spaces, " "); - strcpy(letterbar, " "); - - for (i = 0; i < boardsize; i++) { - letteroffset = 'A'; - if (i+letteroffset >= 'I') - letteroffset++; - strcat(letterbar, spaces); - sprintf(letter, "%c", i+letteroffset); - strcat(letterbar, letter); - } + int i, letteroffset; + char spaces[64]; + char letter[64]; + + if (boardsize <= 25) + strcpy(spaces, " "); + strcpy(letterbar, " "); + + for (i = 0; i < boardsize; i++) { + letteroffset = 'A'; + if (i + letteroffset >= 'I') + letteroffset++; + strcat(letterbar, spaces); + sprintf(letter, "%c", i + letteroffset); + strcat(letterbar, letter); + } } - /* This array contains +'s and -'s for the empty board positions. * hspot_size contains the board size that the grid has been * initialized to. @@ -107,7 +106,6 @@ make_letterbar(int boardsize, char *letterbar) static int hspot_size; static char hspots[MAX_BOARD][MAX_BOARD]; - /* * Mark the handicap spots on the board. */ @@ -115,75 +113,71 @@ static char hspots[MAX_BOARD][MAX_BOARD]; static void set_handicap_spots(int boardsize) { - if (hspot_size == boardsize) - return; - - hspot_size = boardsize; - - memset(hspots, '.', sizeof(hspots)); - - if (boardsize == 5) { - /* place the outer 4 */ - hspots[1][1] = '+'; - hspots[boardsize-2][1] = '+'; - hspots[1][boardsize-2] = '+'; - hspots[boardsize-2][boardsize-2] = '+'; - /* and the middle one */ - hspots[boardsize/2][boardsize/2] = '+'; - return; - } - - if (!(boardsize%2)) { - /* If the board size is even, no center handicap spots. */ - if (boardsize > 2 && boardsize < 12) { - /* Place the outer 4 only. */ - hspots[2][2] = '+'; - hspots[boardsize-3][2] = '+'; - hspots[2][boardsize-3] = '+'; - hspots[boardsize-3][boardsize-3] = '+'; - } - else { - /* Place the outer 4 only. */ - hspots[3][3] = '+'; - hspots[boardsize-4][3] = '+'; - hspots[3][boardsize-4] = '+'; - hspots[boardsize-4][boardsize-4] = '+'; - } - } - else { - /* Uneven board size */ - if (boardsize > 2 && boardsize < 12) { - /* Place the outer 4... */ - hspots[2][2] = '+'; - hspots[boardsize-3][2] = '+'; - hspots[2][boardsize-3] = '+'; - hspots[boardsize-3][boardsize-3] = '+'; - - /* ...and the middle one. */ - hspots[boardsize/2][boardsize/2] = '+'; + if (hspot_size == boardsize) + return; + + hspot_size = boardsize; + + memset(hspots, '.', sizeof(hspots)); + + if (boardsize == 5) { + /* place the outer 4 */ + hspots[1][1] = '+'; + hspots[boardsize - 2][1] = '+'; + hspots[1][boardsize - 2] = '+'; + hspots[boardsize - 2][boardsize - 2] = '+'; + /* and the middle one */ + hspots[boardsize / 2][boardsize / 2] = '+'; + return; } - else if (boardsize > 12) { - /* Place the outer 4... */ - hspots[3][3] = '+'; - hspots[boardsize-4][3] = '+'; - hspots[3][boardsize-4] = '+'; - hspots[boardsize-4][boardsize-4] = '+'; - - /* ...and the inner 4... */ - hspots[3][boardsize/2] = '+'; - hspots[boardsize/2][3] = '+'; - hspots[boardsize/2][boardsize-4] = '+'; - hspots[boardsize-4][boardsize/2] = '+'; - - /* ...and the middle one. */ - hspots[boardsize/2][boardsize/2] = '+'; + + if (!(boardsize % 2)) { + /* If the board size is even, no center handicap spots. */ + if (boardsize > 2 && boardsize < 12) { + /* Place the outer 4 only. */ + hspots[2][2] = '+'; + hspots[boardsize - 3][2] = '+'; + hspots[2][boardsize - 3] = '+'; + hspots[boardsize - 3][boardsize - 3] = '+'; + } else { + /* Place the outer 4 only. */ + hspots[3][3] = '+'; + hspots[boardsize - 4][3] = '+'; + hspots[3][boardsize - 4] = '+'; + hspots[boardsize - 4][boardsize - 4] = '+'; + } + } else { + /* Uneven board size */ + if (boardsize > 2 && boardsize < 12) { + /* Place the outer 4... */ + hspots[2][2] = '+'; + hspots[boardsize - 3][2] = '+'; + hspots[2][boardsize - 3] = '+'; + hspots[boardsize - 3][boardsize - 3] = '+'; + + /* ...and the middle one. */ + hspots[boardsize / 2][boardsize / 2] = '+'; + } else if (boardsize > 12) { + /* Place the outer 4... */ + hspots[3][3] = '+'; + hspots[boardsize - 4][3] = '+'; + hspots[3][boardsize - 4] = '+'; + hspots[boardsize - 4][boardsize - 4] = '+'; + + /* ...and the inner 4... */ + hspots[3][boardsize / 2] = '+'; + hspots[boardsize / 2][3] = '+'; + hspots[boardsize / 2][boardsize - 4] = '+'; + hspots[boardsize - 4][boardsize / 2] = '+'; + + /* ...and the middle one. */ + hspots[boardsize / 2][boardsize / 2] = '+'; + } } - } - return; + return; } - #define WHITECOLOR "\x1B[41m" #define BLACKCOLOR "\x1B[44m" #define RESETCOLOR "\x1B[0m" @@ -198,143 +192,144 @@ set_handicap_spots(int boardsize) static void ascii_showboard(void) { - int i, j; - char letterbar[64]; - int last_pos_was_move; - int pos_is_move; - int dead; - int last_move = get_last_move(); - - make_letterbar(board_size, letterbar); - set_handicap_spots(board_size); - - printf("\n"); - printf(" White (" WHITECOLOR " " RESETCOLOR ") has captured %d pieces\n", black_captured); - printf(" Black (" BLACKCOLOR " " RESETCOLOR ") has captured %d pieces\n", white_captured); - if (showscore) { - if (current_score_estimate == NO_SCORE) - printf(" No score estimate is available yet.\n"); - else if (current_score_estimate < 0) - printf(" Estimated score: Black is ahead by %d\n", - -current_score_estimate); - else if (current_score_estimate > 0) - printf(" Estimated score: White is ahead by %d\n", - current_score_estimate); - else - printf(" Estimated score: Even!\n"); - } - - printf("\n"); - - fflush(stdout); - printf("%s", letterbar); - - if (get_last_player() != EMPTY) { - gfprintf(stdout, " Last move: %s %1m", - get_last_player() == WHITE ? "White" : "Black", - last_move); - } - - printf("\n"); - fflush(stdout); - + int i, j; + char letterbar[64]; + int last_pos_was_move; + int pos_is_move; + int dead; + int last_move = get_last_move(); + + make_letterbar(board_size, letterbar); + set_handicap_spots(board_size); + + printf("\n"); + printf(" White (" WHITECOLOR " " RESETCOLOR ") has captured %d pieces\n", black_captured); + printf(" Black (" BLACKCOLOR " " RESETCOLOR ") has captured %d pieces\n", white_captured); + if (showscore) { + if (current_score_estimate == NO_SCORE) + printf(" No score estimate is available yet.\n"); + else if (current_score_estimate < 0) + printf(" Estimated score: Black is ahead by %d\n", + -current_score_estimate); + else if (current_score_estimate > 0) + printf(" Estimated score: White is ahead by %d\n", + current_score_estimate); + else + printf(" Estimated score: Even!\n"); + } + + printf("\n"); + + fflush(stdout); + printf("%s", letterbar); + + if (get_last_player() != EMPTY) { + gfprintf(stdout, " Last move: %s %1m", + get_last_player() == WHITE ? "White" : "Black", + last_move); + } + + printf("\n"); + fflush(stdout); + for (i = 0; i < board_size; i++) { printf(" %2d", board_size - i); last_pos_was_move = 0; for (j = 0; j < board_size; j++) { - if (POS(i, j) == last_move) pos_is_move = 128; - else pos_is_move = 0; + if (POS(i, j) == last_move) + pos_is_move = 128; + else + pos_is_move = 0; dead = (dragon_status(POS(i, j)) == DEAD) && showdead; switch (BOARD(i, j) + pos_is_move + last_pos_was_move) { - case EMPTY+128: - case EMPTY: - if (i % 2 == 0) { - if (j % 2 == 0) { - printf(BACK1COLOR " " RESETCOLOR); - } else { - printf(BACK2COLOR " " RESETCOLOR); - } + case EMPTY + 128: + case EMPTY: + if (i % 2 == 0) { + if (j % 2 == 0) { + printf(BACK1COLOR " " RESETCOLOR); } else { - if (j % 2 == 0) { - printf(BACK2COLOR " " RESETCOLOR); - } else { - printf(BACK1COLOR " " RESETCOLOR); - } + printf(BACK2COLOR " " RESETCOLOR); } - last_pos_was_move = 0; - break; - case BLACK: - printf(BLACKCOLOR " " RESETCOLOR); - last_pos_was_move = 0; - break; - case WHITE: - printf(WHITECOLOR " " RESETCOLOR); - last_pos_was_move = 0; - break; - case BLACK+128: - printf(BLACKCOLOR "()" RESETCOLOR); - last_pos_was_move = 0; - break; - case WHITE+128: - printf(WHITECOLOR "()" RESETCOLOR); - last_pos_was_move = 0; - break; - case EMPTY+256: - if (i % 2 == 0) { - if (j % 2 == 0) { - printf(BACK1COLOR " " RESETCOLOR); - } else { - printf(BACK2COLOR " " RESETCOLOR); - } + } else { + if (j % 2 == 0) { + printf(BACK2COLOR " " RESETCOLOR); } else { - if (j % 2 == 0) { - printf(BACK2COLOR " " RESETCOLOR); - } else { - printf(BACK1COLOR " " RESETCOLOR); - } + printf(BACK1COLOR " " RESETCOLOR); } - last_pos_was_move = 0; - break; - case BLACK+256: - printf(BLACKCOLOR " " RESETCOLOR); - last_pos_was_move = 0; - break; - case WHITE+256: - printf(WHITECOLOR " " RESETCOLOR); - last_pos_was_move = 0; - break; - default: - fprintf(stderr, "Illegal board value %d\n", (int) BOARD(i, j)); - exit(EXIT_FAILURE); - break; + } + last_pos_was_move = 0; + break; + case BLACK: + printf(BLACKCOLOR " " RESETCOLOR); + last_pos_was_move = 0; + break; + case WHITE: + printf(WHITECOLOR " " RESETCOLOR); + last_pos_was_move = 0; + break; + case BLACK + 128: + printf(BLACKCOLOR "()" RESETCOLOR); + last_pos_was_move = 0; + break; + case WHITE + 128: + printf(WHITECOLOR "()" RESETCOLOR); + last_pos_was_move = 0; + break; + case EMPTY + 256: + if (i % 2 == 0) { + if (j % 2 == 0) { + printf(BACK1COLOR " " RESETCOLOR); + } else { + printf(BACK2COLOR " " RESETCOLOR); + } + } else { + if (j % 2 == 0) { + printf(BACK2COLOR " " RESETCOLOR); + } else { + printf(BACK1COLOR " " RESETCOLOR); + } + } + last_pos_was_move = 0; + break; + case BLACK + 256: + printf(BLACKCOLOR " " RESETCOLOR); + last_pos_was_move = 0; + break; + case WHITE + 256: + printf(WHITECOLOR " " RESETCOLOR); + last_pos_was_move = 0; + break; + default: + fprintf(stderr, "Illegal board value %d\n", (int)BOARD(i, j)); + exit(EXIT_FAILURE); + break; } } - - if (last_pos_was_move == 0) { - if (board_size > 10) - printf(" %2d", board_size - i); - else - printf(" %1d", board_size - i); + + if (last_pos_was_move == 0) { + if (board_size > 10) + printf(" %2d", board_size - i); + else + printf(" %1d", board_size - i); + } else { + if (board_size > 10) + printf("%2d", board_size - i); + else + printf("%1d", board_size - i); + } + printf("\n"); } - else { - if (board_size > 10) - printf("%2d", board_size - i); - else - printf("%1d", board_size - i); + + fflush(stdout); + printf("%s\n\n", letterbar); + fflush(stdout); + + if (clock_on) { + clock_print(WHITE); + clock_print(BLACK); } - printf("\n"); - } - - fflush(stdout); - printf("%s\n\n", letterbar); - fflush(stdout); - - if (clock_on) { - clock_print(WHITE); - clock_print(BLACK); - } - -} /* end ascii_showboard */ + +} /* end ascii_showboard */ /* * command help @@ -343,1004 +338,1045 @@ ascii_showboard(void) static void show_commands(void) { - printf("\nCommands:\n"); - printf(" back Take back your last move\n"); - printf(" boardsize Set boardsize (on move 1 only)\n"); - printf(" comment Write a comment to outputfile\n"); - printf(" depth Set depth for reading\n"); - printf(" display Display game board\n"); - printf(" exit Exit GNU Go\n"); - printf(" force Force a move for current color\n"); - printf(" forward Go to next node in game tree\n"); - printf(" goto Go to movenum in game tree\n"); - printf(" level Playing level (default = 10)\n"); - printf(" handicap Set fixed handicap (on move 1 only)\n"); - printf(" freehandicap Place free handicap (on move 1 only)\n"); - printf(" Omit to place handicap yourself\n"); - printf(" help Display this help menu\n"); - printf(" helpdebug Display debug help menu\n"); - printf(" info Display program settings\n"); - printf(" komi Set komi (on move 1 only)\n"); - printf(" last Goto last node in game tree\n"); - printf(" pass Pass on your move\n"); - printf(" play Play moves\n"); - printf(" playblack Play as Black (switch if White)\n"); - printf(" playwhite Play as White (switch if Black)\n"); - printf(" quit Exit GNU Go\n"); - printf(" resign Resign the current game\n"); - printf(" save Save the current game\n"); - printf(" load Load a game from file\n"); - printf(" score Toggle display of score On/Off\n"); - printf(" showboard Toggle display of board On/Off\n"); - printf(" switch Switch the color you are playing\n"); - printf(" undo Take the last move back (same as back)\n"); - printf(" A move of the format "); - printf("\n"); + printf("\nCommands:\n"); + printf(" back Take back your last move\n"); + printf(" boardsize Set boardsize (on move 1 only)\n"); + printf(" comment Write a comment to outputfile\n"); + printf(" depth Set depth for reading\n"); + printf(" display Display game board\n"); + printf(" exit Exit GNU Go\n"); + printf(" force Force a move for current color\n"); + printf(" forward Go to next node in game tree\n"); + printf(" goto Go to movenum in game tree\n"); + printf(" level Playing level (default = 10)\n"); + printf(" handicap Set fixed handicap (on move 1 only)\n"); + printf(" freehandicap Place free handicap (on move 1 only)\n"); + printf(" Omit to place handicap yourself\n"); + printf(" help Display this help menu\n"); + printf(" helpdebug Display debug help menu\n"); + printf(" info Display program settings\n"); + printf(" komi Set komi (on move 1 only)\n"); + printf(" last Goto last node in game tree\n"); + printf(" pass Pass on your move\n"); + printf(" play Play moves\n"); + printf(" playblack Play as Black (switch if White)\n"); + printf(" playwhite Play as White (switch if Black)\n"); + printf(" quit Exit GNU Go\n"); + printf(" resign Resign the current game\n"); + printf(" save Save the current game\n"); + printf(" load Load a game from file\n"); + printf(" score Toggle display of score On/Off\n"); + printf(" showboard Toggle display of board On/Off\n"); + printf(" switch Switch the color you are playing\n"); + printf(" undo Take the last move back (same as back)\n"); + printf(" A move of the format "); + printf("\n"); } -enum commands {INVALID = -1, END, EXIT, QUIT, RESIGN, - PASS, MOVE, FORCE, SWITCH, - PLAY, PLAYBLACK, PLAYWHITE, - SETHANDICAP, FREEHANDICAP, SETBOARDSIZE, SETKOMI, - SETDEPTH, - INFO, DISPLAY, SHOWBOARD, HELP, UNDO, COMMENT, SCORE, - CMD_DEAD, CMD_BACK, CMD_FORWARD, CMD_LAST, - CMD_CAPTURE, CMD_DEFEND, - CMD_HELPDEBUG, CMD_SHOWAREA, CMD_SHOWMOYO, CMD_SHOWTERRI, - CMD_GOTO, CMD_SAVE, CMD_LOAD, CMD_SHOWDRAGONS, CMD_LISTDRAGONS, - SETLEVEL, NEW, COUNT, CONTINUE +enum commands { INVALID = -1, + END, + EXIT, + QUIT, + RESIGN, + PASS, + MOVE, + FORCE, + SWITCH, + PLAY, + PLAYBLACK, + PLAYWHITE, + SETHANDICAP, + FREEHANDICAP, + SETBOARDSIZE, + SETKOMI, + SETDEPTH, + INFO, + DISPLAY, + SHOWBOARD, + HELP, + UNDO, + COMMENT, + SCORE, + CMD_DEAD, + CMD_BACK, + CMD_FORWARD, + CMD_LAST, + CMD_CAPTURE, + CMD_DEFEND, + CMD_HELPDEBUG, + CMD_SHOWAREA, + CMD_SHOWMOYO, + CMD_SHOWTERRI, + CMD_GOTO, + CMD_SAVE, + CMD_LOAD, + CMD_SHOWDRAGONS, + CMD_LISTDRAGONS, + SETLEVEL, + NEW, + COUNT, + CONTINUE }; - /* * Check if we have a valid command. */ static int -get_command(char *command) +get_command(char* command) { - char c; - int d; - - /* Check to see if a move was input. */ - if (!((sscanf(command, "%c%d", &c, &d) != 2) - || ((c = toupper((int) c)) < 'A') - || ((c = toupper((int) c)) > 'Z') - || (c == 'I'))) - return MOVE; - - /* help shortcut */ - if (command[0] == '?') - return HELP; - - /* Kill leading spaces. */ - while (command[0] == ' ') - command++; - - if (!strncmp(command, "playblack", 9)) return PLAYBLACK; - if (!strncmp(command, "playwhite", 9)) return PLAYWHITE; - if (!strncmp(command, "showboard", 9)) return SHOWBOARD; - if (!strncmp(command, "showdragons", 9)) return CMD_SHOWDRAGONS; - if (!strncmp(command, "listdragons", 9)) return CMD_LISTDRAGONS; - if (!strncmp(command, "boardsize", 9)) return SETBOARDSIZE; - if (!strncmp(command, "freehandicap", 9)) return FREEHANDICAP; - if (!strncmp(command, "handicap", 5)) return SETHANDICAP; - if (!strncmp(command, "display", 7)) return DISPLAY; - if (!strncmp(command, "helpdebug", 7)) return CMD_HELPDEBUG; - if (!strncmp(command, "resign", 6)) return RESIGN; - if (!strncmp(command, "showmoyo", 6)) return CMD_SHOWMOYO; - if (!strncmp(command, "showterri", 6)) return CMD_SHOWTERRI; - if (!strncmp(command, "showarea", 6)) return CMD_SHOWAREA; - if (!strncmp(command, "depth", 5)) return SETDEPTH; - if (!strncmp(command, "switch", 5)) return SWITCH; - if (!strncmp(command, "komi", 4)) return SETKOMI; - if (!strncmp(command, "play", 4)) return PLAY; - if (!strncmp(command, "info", 4)) return INFO; - if (!strncmp(command, "force", 4)) return FORCE; - if (!strncmp(command, "level", 5)) return SETLEVEL; - if (!strncmp(command, "pass", 4)) return PASS; - if (!strncmp(command, "save", 3)) return CMD_SAVE; - if (!strncmp(command, "load", 3)) return CMD_LOAD; - if (!strncmp(command, "end", 3)) return END; - if (!strncmp(command, "move", 3)) return MOVE; - if (!strncmp(command, "undo", 3)) return UNDO; - if (!strncmp(command, "comment", 3)) return COMMENT; - if (!strncmp(command, "score", 3)) return SCORE; - if (!strncmp(command, "dead", 3)) return CMD_DEAD; - if (!strncmp(command, "capture", 3)) return CMD_CAPTURE; - if (!strncmp(command, "defend", 3)) return CMD_DEFEND; - if (!strncmp(command, "exit", 4)) return EXIT; - if (!strncmp(command, "quit", 4)) return QUIT; - if (!strncmp(command, "help", 1)) return HELP; - if (!strncmp(command, "back", 2)) return CMD_BACK; - if (!strncmp(command, "forward", 2)) return CMD_FORWARD; - if (!strncmp(command, "last", 2)) return CMD_LAST; - if (!strncmp(command, "goto", 2)) return CMD_GOTO; - if (!strncmp(command, "game", 2)) return NEW; - if (!strncmp(command, "count", 3)) return COUNT; - if (!strncmp(command, "continue", 4)) return CONTINUE; - - /* No valid command was found. */ - return INVALID; + char c; + int d; + + /* Check to see if a move was input. */ + if (!((sscanf(command, "%c%d", &c, &d) != 2) + || ((c = toupper((int)c)) < 'A') + || ((c = toupper((int)c)) > 'Z') + || (c == 'I'))) + return MOVE; + + /* help shortcut */ + if (command[0] == '?') + return HELP; + + /* Kill leading spaces. */ + while (command[0] == ' ') + command++; + + if (!strncmp(command, "playblack", 9)) + return PLAYBLACK; + if (!strncmp(command, "playwhite", 9)) + return PLAYWHITE; + if (!strncmp(command, "showboard", 9)) + return SHOWBOARD; + if (!strncmp(command, "showdragons", 9)) + return CMD_SHOWDRAGONS; + if (!strncmp(command, "listdragons", 9)) + return CMD_LISTDRAGONS; + if (!strncmp(command, "boardsize", 9)) + return SETBOARDSIZE; + if (!strncmp(command, "freehandicap", 9)) + return FREEHANDICAP; + if (!strncmp(command, "handicap", 5)) + return SETHANDICAP; + if (!strncmp(command, "display", 7)) + return DISPLAY; + if (!strncmp(command, "helpdebug", 7)) + return CMD_HELPDEBUG; + if (!strncmp(command, "resign", 6)) + return RESIGN; + if (!strncmp(command, "showmoyo", 6)) + return CMD_SHOWMOYO; + if (!strncmp(command, "showterri", 6)) + return CMD_SHOWTERRI; + if (!strncmp(command, "showarea", 6)) + return CMD_SHOWAREA; + if (!strncmp(command, "depth", 5)) + return SETDEPTH; + if (!strncmp(command, "switch", 5)) + return SWITCH; + if (!strncmp(command, "komi", 4)) + return SETKOMI; + if (!strncmp(command, "play", 4)) + return PLAY; + if (!strncmp(command, "info", 4)) + return INFO; + if (!strncmp(command, "force", 4)) + return FORCE; + if (!strncmp(command, "level", 5)) + return SETLEVEL; + if (!strncmp(command, "pass", 4)) + return PASS; + if (!strncmp(command, "save", 3)) + return CMD_SAVE; + if (!strncmp(command, "load", 3)) + return CMD_LOAD; + if (!strncmp(command, "end", 3)) + return END; + if (!strncmp(command, "move", 3)) + return MOVE; + if (!strncmp(command, "undo", 3)) + return UNDO; + if (!strncmp(command, "comment", 3)) + return COMMENT; + if (!strncmp(command, "score", 3)) + return SCORE; + if (!strncmp(command, "dead", 3)) + return CMD_DEAD; + if (!strncmp(command, "capture", 3)) + return CMD_CAPTURE; + if (!strncmp(command, "defend", 3)) + return CMD_DEFEND; + if (!strncmp(command, "exit", 4)) + return EXIT; + if (!strncmp(command, "quit", 4)) + return QUIT; + if (!strncmp(command, "help", 1)) + return HELP; + if (!strncmp(command, "back", 2)) + return CMD_BACK; + if (!strncmp(command, "forward", 2)) + return CMD_FORWARD; + if (!strncmp(command, "last", 2)) + return CMD_LAST; + if (!strncmp(command, "goto", 2)) + return CMD_GOTO; + if (!strncmp(command, "game", 2)) + return NEW; + if (!strncmp(command, "count", 3)) + return COUNT; + if (!strncmp(command, "continue", 4)) + return CONTINUE; + + /* No valid command was found. */ + return INVALID; } - /* * Write sgf root node. */ static void -init_sgf(Gameinfo *ginfo) +init_sgf(Gameinfo* ginfo) { - if (sgf_initialized) - return; - sgf_initialized = 1; + if (sgf_initialized) + return; + sgf_initialized = 1; - sgf_write_header(sgftree.root, 1, get_random_seed(), komi, - ginfo->handicap, get_level(), chinese_rules); - if (ginfo->handicap > 0) - sgffile_recordboard(sgftree.root); + sgf_write_header(sgftree.root, 1, get_random_seed(), komi, + ginfo->handicap, get_level(), chinese_rules); + if (ginfo->handicap > 0) + sgffile_recordboard(sgftree.root); } - /* * Generate the computer move. */ static int -computer_move(Gameinfo *gameinfo, int *passes) +computer_move(Gameinfo* gameinfo, int* passes) { - int move; - float move_value; - int resign; - int resignation_declined = 0; - float upper_bound, lower_bound; - - init_sgf(gameinfo); - - /* Generate computer move. */ - if (autolevel_on) - adjust_level_offset(gameinfo->to_move); - move = genmove(gameinfo->to_move, &move_value, &resign); - if (resignation_allowed && resign) { - int state = ascii_endgame(gameinfo, 2); - if (state != -1) - return state; - - /* The opponent declined resignation. Remember not to resign again. */ - resignation_allowed = 0; - resignation_declined = 1; - } - - if (showscore) { - gnugo_estimate_score(&upper_bound, &lower_bound); - current_score_estimate = (int) ((lower_bound + upper_bound) / 2.0); - } - - mprintf("%s(%d): %1m\n", color_to_string(gameinfo->to_move), - movenum + 1, move); - if (is_pass(move)) - (*passes)++; - else - *passes = 0; + int move; + float move_value; + int resign; + int resignation_declined = 0; + float upper_bound, lower_bound; + + init_sgf(gameinfo); + + /* Generate computer move. */ + if (autolevel_on) + adjust_level_offset(gameinfo->to_move); + move = genmove(gameinfo->to_move, &move_value, &resign); + if (resignation_allowed && resign) { + int state = ascii_endgame(gameinfo, 2); + if (state != -1) + return state; + + /* The opponent declined resignation. Remember not to resign again. */ + resignation_allowed = 0; + resignation_declined = 1; + } - gnugo_play_move(move, gameinfo->to_move); - sgffile_add_debuginfo(sgftree.lastnode, move_value); - sgftreeAddPlay(&sgftree, gameinfo->to_move, I(move), J(move)); - if (resignation_declined) - sgftreeAddComment(&sgftree, "GNU Go resignation was declined"); - sgffile_output(&sgftree); + if (showscore) { + gnugo_estimate_score(&upper_bound, &lower_bound); + current_score_estimate = (int)((lower_bound + upper_bound) / 2.0); + } - gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); - return 0; -} + mprintf("%s(%d): %1m\n", color_to_string(gameinfo->to_move), + movenum + 1, move); + if (is_pass(move)) + (*passes)++; + else + *passes = 0; + gnugo_play_move(move, gameinfo->to_move); + sgffile_add_debuginfo(sgftree.lastnode, move_value); + sgftreeAddPlay(&sgftree, gameinfo->to_move, I(move), J(move)); + if (resignation_declined) + sgftreeAddComment(&sgftree, "GNU Go resignation was declined"); + sgffile_output(&sgftree); + + gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); + return 0; +} /* * Make a move. */ static int -do_move(Gameinfo *gameinfo, char *command, int *passes, int force) +do_move(Gameinfo* gameinfo, char* command, int* passes, int force) { - int move = string_to_location(board_size, command); + int move = string_to_location(board_size, command); - if (move == NO_MOVE) { - printf("\nInvalid move: %s\n", command); - return 0; - } - - if (!is_allowed_move(move, gameinfo->to_move)) { - printf("\nIllegal move: %s", command); - return 0; - } - - *passes = 0; - TRACE("\nyour move: %1m\n\n", move); - init_sgf(gameinfo); - gnugo_play_move(move, gameinfo->to_move); - sgffile_add_debuginfo(sgftree.lastnode, 0.0); - sgftreeAddPlay(&sgftree, gameinfo->to_move, I(move), J(move)); - sgffile_output(&sgftree); - - if (opt_showboard) { - ascii_showboard(); - printf("GNU Go is thinking...\n"); - } + if (move == NO_MOVE) { + printf("\nInvalid move: %s\n", command); + return 0; + } - if (force) { - gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player); - gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); - sgftreeAddComment(&sgftree, "forced"); - return 0; - } + if (!is_allowed_move(move, gameinfo->to_move)) { + printf("\nIllegal move: %s", command); + return 0; + } - gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); - return computer_move(gameinfo, passes); -} + *passes = 0; + TRACE("\nyour move: %1m\n\n", move); + init_sgf(gameinfo); + gnugo_play_move(move, gameinfo->to_move); + sgffile_add_debuginfo(sgftree.lastnode, 0.0); + sgftreeAddPlay(&sgftree, gameinfo->to_move, I(move), J(move)); + sgffile_output(&sgftree); + + if (opt_showboard) { + ascii_showboard(); + printf("GNU Go is thinking...\n"); + } + if (force) { + gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player); + gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); + sgftreeAddComment(&sgftree, "forced"); + return 0; + } + + gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); + return computer_move(gameinfo, passes); +} /* * Make a pass. */ static int -do_pass(Gameinfo *gameinfo, int *passes, int force) +do_pass(Gameinfo* gameinfo, int* passes, int force) { - (*passes)++; - init_sgf(gameinfo); - gnugo_play_move(PASS_MOVE, gameinfo->to_move); - sgffile_add_debuginfo(sgftree.lastnode, 0.0); - sgftreeAddPlay(&sgftree, gameinfo->to_move, -1, -1); - sgffile_output(&sgftree); - - gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); - if (force) { - gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player); - sgftreeAddComment(&sgftree, "forced"); - return 0; - } + (*passes)++; + init_sgf(gameinfo); + gnugo_play_move(PASS_MOVE, gameinfo->to_move); + sgffile_add_debuginfo(sgftree.lastnode, 0.0); + sgftreeAddPlay(&sgftree, gameinfo->to_move, -1, -1); + sgffile_output(&sgftree); - return computer_move(gameinfo, passes); -} + gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); + if (force) { + gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player); + sgftreeAddComment(&sgftree, "forced"); + return 0; + } + return computer_move(gameinfo, passes); +} /* * Play a game against an ascii client. */ -void -play_ascii(SGFTree *tree, Gameinfo *gameinfo, char *filename, char *until) +void play_ascii(SGFTree* tree, Gameinfo* gameinfo, char* filename, char* until) { - int sz; - - setvbuf(stdout, (char *)NULL, _IONBF, 0); /* No buffering. */ - - sgftree = *tree; - - if (filename) { - /* No need to check for failure here since that was already done + int sz; + + setvbuf(stdout, (char*)NULL, _IONBF, 0); /* No buffering. */ + + sgftree = *tree; + + if (filename) { + /* No need to check for failure here since that was already done * when it was loaded in main(). * * FIXME: Why do we load the game again? */ - gameinfo_play_sgftree(gameinfo, &sgftree, until); - sgf_initialized = 1; - } - else { - if (sgfGetIntProperty(sgftree.root, "SZ", &sz)) - gnugo_clear_board(sz); - if (gameinfo->handicap == 0) - gameinfo->to_move = BLACK; - else { - gameinfo->handicap = place_fixed_handicap(gameinfo->handicap); - gameinfo->to_move = WHITE; + gameinfo_play_sgftree(gameinfo, &sgftree, until); + sgf_initialized = 1; + } else { + if (sgfGetIntProperty(sgftree.root, "SZ", &sz)) + gnugo_clear_board(sz); + if (gameinfo->handicap == 0) + gameinfo->to_move = BLACK; + else { + gameinfo->handicap = place_fixed_handicap(gameinfo->handicap); + gameinfo->to_move = WHITE; + } + sgf_initialized = 0; } - sgf_initialized = 0; - } - do_play_ascii(gameinfo); - printf("\nThanks! for playing GNU Go.\n\n"); + do_play_ascii(gameinfo); + printf("\nThanks! for playing GNU Go.\n\n"); - /* main() frees the tree and we might have changed it. */ - *tree = sgftree; + /* main() frees the tree and we might have changed it. */ + *tree = sgftree; } - -void -do_play_ascii(Gameinfo *gameinfo) +void do_play_ascii(Gameinfo* gameinfo) { - int m, num; - float fnum; - int passes = 0; /* two passes and its over */ - int tmp; - char line[80]; - char *line_ptr = line; - char *command; - char *tmpstring; - int state = 1; - - if (have_time_settings()) - clock_on = 1; - - while (state == 1) { - state = 0; - - /* No score is estimated yet. */ - current_score_estimate = NO_SCORE; - - /* Allow resignation at interface level (the engine may still be not + int m, num; + float fnum; + int passes = 0; /* two passes and its over */ + int tmp; + char line[80]; + char* line_ptr = line; + char* command; + char* tmpstring; + int state = 1; + + if (have_time_settings()) + clock_on = 1; + + while (state == 1) { + state = 0; + + /* No score is estimated yet. */ + current_score_estimate = NO_SCORE; + + /* Allow resignation at interface level (the engine may still be not * allowed to resign. */ - resignation_allowed = 1; + resignation_allowed = 1; - printf("\nBeginning ASCII mode game.\n\n"); - gameinfo_print(gameinfo); + printf("\nBeginning ASCII mode game.\n\n"); + gameinfo_print(gameinfo); - /* Does the computer play first? If so, make a move. */ - if (gameinfo->computer_player == gameinfo->to_move) - state = computer_move(gameinfo, &passes); + /* Does the computer play first? If so, make a move. */ + if (gameinfo->computer_player == gameinfo->to_move) + state = computer_move(gameinfo, &passes); - /* main ASCII Play loop */ - while (state == 0) { - /* Display game board. */ - if (opt_showboard) - ascii_showboard(); + /* main ASCII Play loop */ + while (state == 0) { + /* Display game board. */ + if (opt_showboard) + ascii_showboard(); #if !READLINE - /* Print the prompt */ - mprintf("%s(%d): ", color_to_string(gameinfo->to_move), movenum + 1); + /* Print the prompt */ + mprintf("%s(%d): ", color_to_string(gameinfo->to_move), movenum + 1); - /* Read a line of input. */ - line_ptr = line; - if (!fgets(line, 80, stdin)) - return; + /* Read a line of input. */ + line_ptr = line; + if (!fgets(line, 80, stdin)) + return; #else - snprintf(line, 79, "%s(%d): ", - color_to_string(gameinfo->to_move), movenum + 1); - if (!(line_ptr = readline(line))) - return; + snprintf(line, 79, "%s(%d): ", + color_to_string(gameinfo->to_move), movenum + 1); + if (!(line_ptr = readline(line))) + return; - add_history(line_ptr); + add_history(line_ptr); #endif - while (state == 0 - && (command = strtok(line_ptr, ";"), line_ptr = 0, command)) { - /* Get the command or move. */ - switch (get_command(command)) { - case RESIGN: - state = ascii_endgame(gameinfo, 1); - break; - - case END: - case EXIT: - case QUIT: - return; - - case HELP: - show_commands(); - break; - - case CMD_HELPDEBUG: - printf(DEBUG_COMMANDS); - break; - - case SHOWBOARD: - opt_showboard = !opt_showboard; - break; - - case INFO: - printf("\n"); - gameinfo_print(gameinfo); - break; - - case SETBOARDSIZE: - if (sgf_initialized) { - printf("Boardsize cannot be changed after record is started!\n"); - break; - } - command += 10; - if (sscanf(command, "%d", &num) != 1) { - printf("\nInvalid command syntax!\n"); - break; - } - if (!check_boardsize(num, stdout)) - break; - /* Init board. */ - board_size = num; - clear_board(); - /* In case max handicap changes on smaller board. */ - gameinfo->handicap = place_fixed_handicap(gameinfo->handicap); - sgfOverwritePropertyInt(sgftree.root, "SZ", board_size); - sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap); - break; - - case SETHANDICAP: - if (sgf_initialized) { - printf("Handicap cannot be changed after game is started!\n"); - break; - } - command += 9; - if (sscanf(command, "%d", &num) != 1) { - printf("\nInvalid command syntax!\n"); - break; - } - if (num < 0 || num > MAX_HANDICAP) { - printf("\nInvalid handicap: %d\n", num); - break; - } - /* Init board. */ - clear_board(); - /* Place stones on board but don't record sgf + while (state == 0 + && (command = strtok(line_ptr, ";"), line_ptr = 0, command)) { + /* Get the command or move. */ + switch (get_command(command)) { + case RESIGN: + state = ascii_endgame(gameinfo, 1); + break; + + case END: + case EXIT: + case QUIT: + return; + + case HELP: + show_commands(); + break; + + case CMD_HELPDEBUG: + printf(DEBUG_COMMANDS); + break; + + case SHOWBOARD: + opt_showboard = !opt_showboard; + break; + + case INFO: + printf("\n"); + gameinfo_print(gameinfo); + break; + + case SETBOARDSIZE: + if (sgf_initialized) { + printf("Boardsize cannot be changed after record is started!\n"); + break; + } + command += 10; + if (sscanf(command, "%d", &num) != 1) { + printf("\nInvalid command syntax!\n"); + break; + } + if (!check_boardsize(num, stdout)) + break; + /* Init board. */ + board_size = num; + clear_board(); + /* In case max handicap changes on smaller board. */ + gameinfo->handicap = place_fixed_handicap(gameinfo->handicap); + sgfOverwritePropertyInt(sgftree.root, "SZ", board_size); + sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap); + break; + + case SETHANDICAP: + if (sgf_initialized) { + printf("Handicap cannot be changed after game is started!\n"); + break; + } + command += 9; + if (sscanf(command, "%d", &num) != 1) { + printf("\nInvalid command syntax!\n"); + break; + } + if (num < 0 || num > MAX_HANDICAP) { + printf("\nInvalid handicap: %d\n", num); + break; + } + /* Init board. */ + clear_board(); + /* Place stones on board but don't record sgf * in case we change more info. */ - gameinfo->handicap = place_fixed_handicap(num); - printf("\nSet handicap to %d\n", gameinfo->handicap); - gameinfo->to_move = (gameinfo->handicap ? WHITE : BLACK); - break; - - case FREEHANDICAP: - if (sgf_initialized) { - printf("Handicap cannot be changed after game is started!\n"); - break; - } - while (*command && *command != ' ') - command++; - ascii_free_handicap(gameinfo, command); - break; - - case SETKOMI: - if (sgf_initialized) { - printf("Komi cannot be modified after game record is started!\n"); - break; - } - command += 5; - if (sscanf(command, "%f", &fnum) != 1) { - printf("\nInvalid command syntax!\n"); - break; - } - komi = fnum; - printf("\nSet Komi to %.1f\n", komi); - break; - - case SETDEPTH: - command += 6; - if (sscanf(command, "%d", &num) != 1) { - printf("\nInvalid command syntax!\n"); - break; - } - mandated_depth = num; - printf("\nSet depth to %d\n", mandated_depth); - break; - - case SETLEVEL: - command += 6; - if (sscanf(command, "%d", &num) != 1) { - printf("\nInvalid command syntax!\n"); - break; - } - set_level(num); - printf("\nSet level to %d\n", num); - break; - - case DISPLAY: - if (!opt_showboard) - ascii_showboard(); - break; - - case FORCE: - command += 6; /* skip the force part... */ - switch (get_command(command)) { - case MOVE: - state = do_move(gameinfo, command, &passes, 1); - break; - case PASS: - state = do_pass(gameinfo, &passes, 1); - break; - default: - printf("Illegal forced move: %s %d\n", command, - get_command(command)); - break; - } - break; - - case MOVE: - state = do_move(gameinfo, command, &passes, 0); - break; - - case PASS: - state = do_pass(gameinfo, &passes, 0); - break; - - case PLAY: - command += 5; - if (sscanf(command, "%d", &num) != 1) { - printf("\nInvalid command syntax!\n"); - break; - } - if (num >= 0) - for (m = 0; m < num; m++) { - gameinfo->computer_player - = OTHER_COLOR(gameinfo->computer_player); - state = computer_move(gameinfo, &passes); - if (state) - break; - if (passes >= 2) - break; - } - else { - printf("\nInvalid number of moves specified: %d\n", num); - break; - } - break; - - case PLAYBLACK: - if (gameinfo->computer_player == WHITE) - gameinfo->computer_player = BLACK; - if (gameinfo->computer_player == gameinfo->to_move) - state = computer_move(gameinfo, &passes); - break; - - case PLAYWHITE: - if (gameinfo->computer_player == BLACK) - gameinfo->computer_player = WHITE; - if (gameinfo->computer_player == gameinfo->to_move) - state = computer_move(gameinfo, &passes); - break; - - case SWITCH: - gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player); - state = computer_move(gameinfo, &passes); - break; - - case UNDO: - case CMD_BACK: - if (undo_move(1)) { - sgftreeAddComment(&sgftree, "undone"); - sgftreeBack(&sgftree); - gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); - } - else - printf("\nCan't undo.\n"); - break; - - case CMD_FORWARD: - if (sgftreeForward(&sgftree)) - gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode, - gameinfo->to_move); - else - printf("\nEnd of game tree.\n"); - break; - - case CMD_LAST: - while (sgftreeForward(&sgftree)) - gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode, - gameinfo->to_move); - break; - - case COMMENT: - printf("\nEnter comment. Press ENTER when ready.\n"); - fgets(line, 80, stdin); - sgftreeAddComment(&sgftree, line); - break; - - case SCORE: - showscore = !showscore; - if (!showscore) - current_score_estimate = NO_SCORE; - break; - - case CMD_DEAD: - silent_examine_position(FULL_EXAMINE_DRAGONS); - showdead = !showdead; - break; - - case CMD_CAPTURE: - strtok(command, " "); - showcapture(strtok(NULL, " ")); - break; - - case CMD_DEFEND: - strtok(command, " "); - showdefense(strtok(NULL, " ")); - break; - - case CMD_SHOWMOYO: - tmp = printmoyo; - printmoyo = PRINTMOYO_MOYO; - silent_examine_position(EXAMINE_DRAGONS); - printmoyo = tmp; - break; - - case CMD_SHOWTERRI: - tmp = printmoyo; - printmoyo = PRINTMOYO_TERRITORY; - silent_examine_position(EXAMINE_DRAGONS); - printmoyo = tmp; - break; - - case CMD_SHOWAREA: - tmp = printmoyo; - printmoyo = PRINTMOYO_AREA; - silent_examine_position(EXAMINE_DRAGONS); - printmoyo = tmp; - break; - - case CMD_SHOWDRAGONS: - silent_examine_position(EXAMINE_DRAGONS); - showboard(1); - break; - - case CMD_GOTO: - strtok(command, " "); - ascii_goto(gameinfo, strtok(NULL, " ")); - break; - - case CMD_SAVE: - strtok(command, " "); - tmpstring = strtok(NULL, " "); - if (tmpstring) { - /* discard newline */ - tmpstring[strlen(tmpstring) - 1] = 0; - /* make sure we are saving proper handicap */ - init_sgf(gameinfo); - writesgf(sgftree.root, tmpstring); - printf("You may resume the game"); - printf(" with -l %s --mode ascii\n", tmpstring); - printf("or load %s\n", tmpstring); - } - else - printf("Please specify filename\n"); - break; - - case CMD_LOAD: - strtok(command, " "); - tmpstring = strtok(NULL, " "); - if (tmpstring) { - /* discard newline */ - tmpstring[strlen(tmpstring) - 1] = 0; - if (!sgftree_readfile(&sgftree, tmpstring)) { - fprintf(stderr, "Cannot open or parse '%s'\n", tmpstring); - break; - } - /* to avoid changing handicap etc. */ - if (gameinfo_play_sgftree(gameinfo, &sgftree, NULL) == EMPTY) - fprintf(stderr, "Cannot load '%s'\n", tmpstring); - else { - sgf_initialized = 1; - sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap); - } - } - else - printf("Please specify a filename\n"); - break; - - case CMD_LISTDRAGONS: - silent_examine_position(EXAMINE_DRAGONS); - show_dragons(); - break; - - default: - printf("\nInvalid command: %s", command); - break; - } - - if (passes >= 2) - state = ascii_endgame(gameinfo, 0); - } + gameinfo->handicap = place_fixed_handicap(num); + printf("\nSet handicap to %d\n", gameinfo->handicap); + gameinfo->to_move = (gameinfo->handicap ? WHITE : BLACK); + break; + + case FREEHANDICAP: + if (sgf_initialized) { + printf("Handicap cannot be changed after game is started!\n"); + break; + } + while (*command && *command != ' ') + command++; + ascii_free_handicap(gameinfo, command); + break; + + case SETKOMI: + if (sgf_initialized) { + printf("Komi cannot be modified after game record is started!\n"); + break; + } + command += 5; + if (sscanf(command, "%f", &fnum) != 1) { + printf("\nInvalid command syntax!\n"); + break; + } + komi = fnum; + printf("\nSet Komi to %.1f\n", komi); + break; + + case SETDEPTH: + command += 6; + if (sscanf(command, "%d", &num) != 1) { + printf("\nInvalid command syntax!\n"); + break; + } + mandated_depth = num; + printf("\nSet depth to %d\n", mandated_depth); + break; + + case SETLEVEL: + command += 6; + if (sscanf(command, "%d", &num) != 1) { + printf("\nInvalid command syntax!\n"); + break; + } + set_level(num); + printf("\nSet level to %d\n", num); + break; + + case DISPLAY: + if (!opt_showboard) + ascii_showboard(); + break; + + case FORCE: + command += 6; /* skip the force part... */ + switch (get_command(command)) { + case MOVE: + state = do_move(gameinfo, command, &passes, 1); + break; + case PASS: + state = do_pass(gameinfo, &passes, 1); + break; + default: + printf("Illegal forced move: %s %d\n", command, + get_command(command)); + break; + } + break; + + case MOVE: + state = do_move(gameinfo, command, &passes, 0); + break; + + case PASS: + state = do_pass(gameinfo, &passes, 0); + break; + + case PLAY: + command += 5; + if (sscanf(command, "%d", &num) != 1) { + printf("\nInvalid command syntax!\n"); + break; + } + if (num >= 0) + for (m = 0; m < num; m++) { + gameinfo->computer_player + = OTHER_COLOR(gameinfo->computer_player); + state = computer_move(gameinfo, &passes); + if (state) + break; + if (passes >= 2) + break; + } + else { + printf("\nInvalid number of moves specified: %d\n", num); + break; + } + break; + + case PLAYBLACK: + if (gameinfo->computer_player == WHITE) + gameinfo->computer_player = BLACK; + if (gameinfo->computer_player == gameinfo->to_move) + state = computer_move(gameinfo, &passes); + break; + + case PLAYWHITE: + if (gameinfo->computer_player == BLACK) + gameinfo->computer_player = WHITE; + if (gameinfo->computer_player == gameinfo->to_move) + state = computer_move(gameinfo, &passes); + break; + + case SWITCH: + gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player); + state = computer_move(gameinfo, &passes); + break; + + case UNDO: + case CMD_BACK: + if (undo_move(1)) { + sgftreeAddComment(&sgftree, "undone"); + sgftreeBack(&sgftree); + gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); + } else + printf("\nCan't undo.\n"); + break; + + case CMD_FORWARD: + if (sgftreeForward(&sgftree)) + gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode, + gameinfo->to_move); + else + printf("\nEnd of game tree.\n"); + break; + + case CMD_LAST: + while (sgftreeForward(&sgftree)) + gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode, + gameinfo->to_move); + break; + + case COMMENT: + printf("\nEnter comment. Press ENTER when ready.\n"); + fgets(line, 80, stdin); + sgftreeAddComment(&sgftree, line); + break; + + case SCORE: + showscore = !showscore; + if (!showscore) + current_score_estimate = NO_SCORE; + break; + + case CMD_DEAD: + silent_examine_position(FULL_EXAMINE_DRAGONS); + showdead = !showdead; + break; + + case CMD_CAPTURE: + strtok(command, " "); + showcapture(strtok(NULL, " ")); + break; + + case CMD_DEFEND: + strtok(command, " "); + showdefense(strtok(NULL, " ")); + break; + + case CMD_SHOWMOYO: + tmp = printmoyo; + printmoyo = PRINTMOYO_MOYO; + silent_examine_position(EXAMINE_DRAGONS); + printmoyo = tmp; + break; + + case CMD_SHOWTERRI: + tmp = printmoyo; + printmoyo = PRINTMOYO_TERRITORY; + silent_examine_position(EXAMINE_DRAGONS); + printmoyo = tmp; + break; + + case CMD_SHOWAREA: + tmp = printmoyo; + printmoyo = PRINTMOYO_AREA; + silent_examine_position(EXAMINE_DRAGONS); + printmoyo = tmp; + break; + + case CMD_SHOWDRAGONS: + silent_examine_position(EXAMINE_DRAGONS); + showboard(1); + break; + + case CMD_GOTO: + strtok(command, " "); + ascii_goto(gameinfo, strtok(NULL, " ")); + break; + + case CMD_SAVE: + strtok(command, " "); + tmpstring = strtok(NULL, " "); + if (tmpstring) { + /* discard newline */ + tmpstring[strlen(tmpstring) - 1] = 0; + /* make sure we are saving proper handicap */ + init_sgf(gameinfo); + writesgf(sgftree.root, tmpstring); + printf("You may resume the game"); + printf(" with -l %s --mode ascii\n", tmpstring); + printf("or load %s\n", tmpstring); + } else + printf("Please specify filename\n"); + break; + + case CMD_LOAD: + strtok(command, " "); + tmpstring = strtok(NULL, " "); + if (tmpstring) { + /* discard newline */ + tmpstring[strlen(tmpstring) - 1] = 0; + if (!sgftree_readfile(&sgftree, tmpstring)) { + fprintf(stderr, "Cannot open or parse '%s'\n", tmpstring); + break; + } + /* to avoid changing handicap etc. */ + if (gameinfo_play_sgftree(gameinfo, &sgftree, NULL) == EMPTY) + fprintf(stderr, "Cannot load '%s'\n", tmpstring); + else { + sgf_initialized = 1; + sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap); + } + } else + printf("Please specify a filename\n"); + break; + + case CMD_LISTDRAGONS: + silent_examine_position(EXAMINE_DRAGONS); + show_dragons(); + break; + + default: + printf("\nInvalid command: %s", command); + break; + } + + if (passes >= 2) + state = ascii_endgame(gameinfo, 0); + } #if READLINE - free(line_ptr); + free(line_ptr); #endif + } - } + sgffile_output(&sgftree); + passes = 0; - sgffile_output(&sgftree); - passes = 0; - - /* Play a different game next time. */ - update_random_seed(); - - /* Free the sgf tree and prepare for a new game. */ - sgfFreeNode(sgftree.root); - sgftree_clear(&sgftree); - sgftreeCreateHeaderNode(&sgftree, board_size, komi, gameinfo->handicap); - sgf_initialized = 0; - - gameinfo_clear(gameinfo); - } -} + /* Play a different game next time. */ + update_random_seed(); + + /* Free the sgf tree and prepare for a new game. */ + sgfFreeNode(sgftree.root); + sgftree_clear(&sgftree); + sgftreeCreateHeaderNode(&sgftree, board_size, komi, gameinfo->handicap); + sgf_initialized = 0; + gameinfo_clear(gameinfo); + } +} /* Communicates with user after a game has ended. */ static int -ascii_endgame(Gameinfo *gameinfo, int reason) +ascii_endgame(Gameinfo* gameinfo, int reason) { - char line[80]; - char *line_ptr; - char *command; - char *tmpstring; - int state = 0; + char line[80]; + char* line_ptr; + char* command; + char* tmpstring; + int state = 0; + + if (reason == 0) { /* Two passes, game is over. */ + who_wins(gameinfo->computer_player, stdout); + printf("\nIf you disagree, we may count the game together.\n"); + + sgftreeWriteResult(&sgftree, (white_score + black_score) / 2.0, 1); + } else { + int color = OTHER_COLOR(gameinfo->to_move); + + if (reason == 1) /* Our opponent has resigned. */ + printf("GNU Go wins by resignation.\n"); + else /* We have resigned. */ + printf("You win by resignation.\n"); + + printf("Result: %c+Resign\n\n", color == WHITE ? 'W' : 'B'); + sgftreeWriteResult(&sgftree, color == WHITE ? 1000.0 : -1000.0, 1); + } - if (reason == 0) { /* Two passes, game is over. */ - who_wins(gameinfo->computer_player, stdout); - printf("\nIf you disagree, we may count the game together.\n"); - - sgftreeWriteResult(&sgftree, (white_score + black_score)/2.0, 1); - } - else { - int color = OTHER_COLOR(gameinfo->to_move); - - if (reason == 1) /* Our opponent has resigned. */ - printf("GNU Go wins by resignation.\n"); - else /* We have resigned. */ - printf("You win by resignation.\n"); - - printf("Result: %c+Resign\n\n", color == WHITE ? 'W' : 'B'); - sgftreeWriteResult(&sgftree, color == WHITE ? 1000.0 : -1000.0, 1); - } - - while (state == 0) { - printf("You may optionally save the game as an SGF file.\n\n"); - printf("Type \"save \" to save,\n"); - if (reason == 0) - printf(" \"count\" to recount,\n"); - else if (reason == 2) - printf(" \"continue\" to decline resignation and continue the game,\n"); - printf(" \"quit\" to quit\n"); - printf(" or \"game\" to play again\n"); - - line_ptr = line; - if (!fgets(line, 80, stdin)) - break; - - command = strtok(line_ptr, ""); - switch (get_command(command)) { - case CMD_SAVE: - strtok(command, " "); - tmpstring = strtok(NULL, " "); - if (tmpstring) { - /* discard newline */ - tmpstring[strlen(tmpstring) - 1] = 0; - init_sgf(gameinfo); - writesgf(sgftree.root, tmpstring); - } - else - printf("Please specify filename\n"); - break; - - case COUNT: - if (reason == 0) - ascii_count(gameinfo); - break; - - case CONTINUE: - state = -1; - break; - - case NEW: - state = 1; - break; - - case QUIT: - state = 2; - break; - - default: - state = 0; + while (state == 0) { + printf("You may optionally save the game as an SGF file.\n\n"); + printf("Type \"save \" to save,\n"); + if (reason == 0) + printf(" \"count\" to recount,\n"); + else if (reason == 2) + printf(" \"continue\" to decline resignation and continue the game,\n"); + printf(" \"quit\" to quit\n"); + printf(" or \"game\" to play again\n"); + + line_ptr = line; + if (!fgets(line, 80, stdin)) + break; + + command = strtok(line_ptr, ""); + switch (get_command(command)) { + case CMD_SAVE: + strtok(command, " "); + tmpstring = strtok(NULL, " "); + if (tmpstring) { + /* discard newline */ + tmpstring[strlen(tmpstring) - 1] = 0; + init_sgf(gameinfo); + writesgf(sgftree.root, tmpstring); + } else + printf("Please specify filename\n"); + break; + + case COUNT: + if (reason == 0) + ascii_count(gameinfo); + break; + + case CONTINUE: + state = -1; + break; + + case NEW: + state = 1; + break; + + case QUIT: + state = 2; + break; + + default: + state = 0; + } } - } - return state; + return state; } - /* ascii_count() scores the game. */ static void -ascii_count(Gameinfo *gameinfo) +ascii_count(Gameinfo* gameinfo) { - char line[12]; - int done = 0; - int i; - int xyzzy = 1; - - printf("\nGame over. Let's count!.\n"); - showdead = 1; - ascii_showboard(); - while (!done) { - printf("Dead stones are marked with small letters (x,o).\n"); - printf("\nIf you don't agree, enter the location of a group\n"); - printf("to toggle its state or \"done\".\n"); - - if (!fgets(line, 12, stdin)) - return; /* EOF or some error */ - - for (i = 0; i < 12; i++) - line[i] = tolower((int) line[i]); - if (!strncmp(line, "done", 4)) - done = 1; - else if (!strncmp(line, "quit", 4)) - return; - else if (!strncmp(line, "xyzzy", 5)) { - if (xyzzy) { - printf("\nYou are in a debris room filled with stuff washed in from the\n"); - printf("surface. A low wide passage with cobbles becomes plugged\n"); - printf("with mud and debris here, but an awkward canyon leads\n"); - printf("upward and west. A note on the wall says:\n"); - printf(" Magic Word \"XYZZY\"\n\n"); - xyzzy = 0; - } - else { - printf("You are inside a building, a well house for a large spring.\n\n"); - xyzzy = 1; - } - } - else if (!strncmp(line, "help", 4)) { - printf("\nIf there are dead stones on the board I will remove them.\n"); - printf("You must tell me where they are. Type the coordinates of a\n"); - printf("dead group, or type \"done\"\n"); - } - else if (!strncmp(line, "undo", 4)) { - printf("UNDO not allowed anymore. The status of the stones now\n"); - printf("toggles after entering the location of it.\n"); - ascii_showboard(); - } - else { - int pos = string_to_location(board_size, line); - if (pos == NO_MOVE || board[pos] == EMPTY) - printf("\ninvalid!\n"); - else { - enum dragon_status status = dragon_status(pos); - status = (status == DEAD) ? ALIVE : DEAD; - change_dragon_status(pos, status); - ascii_showboard(); - } + char line[12]; + int done = 0; + int i; + int xyzzy = 1; + + printf("\nGame over. Let's count!.\n"); + showdead = 1; + ascii_showboard(); + while (!done) { + printf("Dead stones are marked with small letters (x,o).\n"); + printf("\nIf you don't agree, enter the location of a group\n"); + printf("to toggle its state or \"done\".\n"); + + if (!fgets(line, 12, stdin)) + return; /* EOF or some error */ + + for (i = 0; i < 12; i++) + line[i] = tolower((int)line[i]); + if (!strncmp(line, "done", 4)) + done = 1; + else if (!strncmp(line, "quit", 4)) + return; + else if (!strncmp(line, "xyzzy", 5)) { + if (xyzzy) { + printf("\nYou are in a debris room filled with stuff washed in from the\n"); + printf("surface. A low wide passage with cobbles becomes plugged\n"); + printf("with mud and debris here, but an awkward canyon leads\n"); + printf("upward and west. A note on the wall says:\n"); + printf(" Magic Word \"XYZZY\"\n\n"); + xyzzy = 0; + } else { + printf("You are inside a building, a well house for a large spring.\n\n"); + xyzzy = 1; + } + } else if (!strncmp(line, "help", 4)) { + printf("\nIf there are dead stones on the board I will remove them.\n"); + printf("You must tell me where they are. Type the coordinates of a\n"); + printf("dead group, or type \"done\"\n"); + } else if (!strncmp(line, "undo", 4)) { + printf("UNDO not allowed anymore. The status of the stones now\n"); + printf("toggles after entering the location of it.\n"); + ascii_showboard(); + } else { + int pos = string_to_location(board_size, line); + if (pos == NO_MOVE || board[pos] == EMPTY) + printf("\ninvalid!\n"); + else { + enum dragon_status status = dragon_status(pos); + status = (status == DEAD) ? ALIVE : DEAD; + change_dragon_status(pos, status); + ascii_showboard(); + } + } } - } - who_wins(gameinfo->computer_player, stdout); + who_wins(gameinfo->computer_player, stdout); } - static void -showcapture(char *line) +showcapture(char* line) { - int str; - int move; + int str; + int move; + + gg_assert(line); + str = string_to_location(board_size, line); + if (str == NO_MOVE || board[str] == EMPTY) { + printf("\ninvalid point!\n"); + return; + } - gg_assert(line); - str = string_to_location(board_size, line); - if (str == NO_MOVE || board[str] == EMPTY) { - printf("\ninvalid point!\n"); - return; - } - - if (attack(str, &move)) - mprintf("\nSuccessful attack of %1m at %1m\n", str, move); - else - mprintf("\n%1m cannot be attacked\n", str); + if (attack(str, &move)) + mprintf("\nSuccessful attack of %1m at %1m\n", str, move); + else + mprintf("\n%1m cannot be attacked\n", str); } - static void -showdefense(char *line) +showdefense(char* line) { - int str; - int move; - - gg_assert(line); - str = string_to_location(board_size, line); - if (str == NO_MOVE || board[str] == EMPTY) { - printf("\ninvalid point!\n"); - return; - } - - if (attack(str, NULL)) { - if (find_defense(str, &move)) - mprintf("\nSuccessful defense of %1m at %1m\n", str, move); - else - mprintf("\n%1m cannot be defended\n", str); + int str; + int move; + + gg_assert(line); + str = string_to_location(board_size, line); + if (str == NO_MOVE || board[str] == EMPTY) { + printf("\ninvalid point!\n"); + return; } - else - mprintf("\nThere is no need to defend %1m\n", str); -} + if (attack(str, NULL)) { + if (find_defense(str, &move)) + mprintf("\nSuccessful defense of %1m at %1m\n", str, move); + else + mprintf("\n%1m cannot be defended\n", str); + } else + mprintf("\nThere is no need to defend %1m\n", str); +} static void -ascii_goto(Gameinfo *gameinfo, char *line) +ascii_goto(Gameinfo* gameinfo, char* line) { - const char *movenumber = line; + const char* movenumber = line; - if (!line) - return; - - if (!strncmp(line, "last", 4)) - movenumber = "9999"; - else if (!strncmp(line, "first", 4)) - movenumber = "1"; - - printf("goto %s\n", movenumber); - gameinfo_play_sgftree(gameinfo, &sgftree, movenumber); -} + if (!line) + return; + if (!strncmp(line, "last", 4)) + movenumber = "9999"; + else if (!strncmp(line, "first", 4)) + movenumber = "1"; + + printf("goto %s\n", movenumber); + gameinfo_play_sgftree(gameinfo, &sgftree, movenumber); +} static void -ascii_free_handicap(Gameinfo *gameinfo, char *handicap_string) +ascii_free_handicap(Gameinfo* gameinfo, char* handicap_string) { - int handi; - int i; - char line[80]; - int stones[MAX_BOARD*MAX_BOARD]; - - if (sscanf(handicap_string, "%d", &handi) == 1) { - /* GNU Go is to place handicap */ - if (handi < 0 || handi == 1) { - printf("\nInvalid command syntax!\n"); - return; - } + int handi; + int i; + char line[80]; + int stones[MAX_BOARD * MAX_BOARD]; + + if (sscanf(handicap_string, "%d", &handi) == 1) { + /* GNU Go is to place handicap */ + if (handi < 0 || handi == 1) { + printf("\nInvalid command syntax!\n"); + return; + } - clear_board(); - handi = place_free_handicap(handi); - printf("\nPlaced %d stones of free handicap.\n", handi); - } - else { /* User is to place handicap */ - clear_board(); - handi = 0; - - while (1) { - ascii_showboard(); - printf("\nType in coordinates of next handicap stone, or one of the following commands:\n"); - printf(" undo take back the last stone placed\n"); - printf(" clear remove all the stones placed so far\n"); - printf(" done finish placing handicap\n\n"); - printf("You have placed %d handicap stone(s) so far.\n\n", handi); - - if (!fgets(line, 80, stdin)) - return; /* EOF or some error */ - for (i = 0; i < 80; i++) - line[i] = tolower((int) line[i]); - - if (!strncmp(line, "undo", 4)) { - if (!handi) - printf("\nNothing to undo.\n"); - else { - remove_stone(stones[--handi]); - gprintf("\nRemoved the stone at %m.\n", I(stones[handi]), - J(stones[handi])); - } - } - else if (!strncmp(line, "clear", 5)) { + clear_board(); + handi = place_free_handicap(handi); + printf("\nPlaced %d stones of free handicap.\n", handi); + } else { /* User is to place handicap */ clear_board(); handi = 0; - } - else if (!strncmp(line, "done", 4)) { - if (handi == 1) /* Don't bother with checks later */ - printf("\nHandicap cannot be one stone. Either add " - "some more, or delete the only stone.\n"); - else - break; - } - else { - int pos = string_to_location(board_size, line); - if (pos != NO_MOVE) { - if (board[pos] != EMPTY) - printf("\nThere's already a stone there.\n"); - else { - add_stone(pos, BLACK); - stones[handi++] = pos; - } - } - else - printf("\nInvalid command: %s", line); - } + + while (1) { + ascii_showboard(); + printf("\nType in coordinates of next handicap stone, or one of the following commands:\n"); + printf(" undo take back the last stone placed\n"); + printf(" clear remove all the stones placed so far\n"); + printf(" done finish placing handicap\n\n"); + printf("You have placed %d handicap stone(s) so far.\n\n", handi); + + if (!fgets(line, 80, stdin)) + return; /* EOF or some error */ + for (i = 0; i < 80; i++) + line[i] = tolower((int)line[i]); + + if (!strncmp(line, "undo", 4)) { + if (!handi) + printf("\nNothing to undo.\n"); + else { + remove_stone(stones[--handi]); + gprintf("\nRemoved the stone at %m.\n", I(stones[handi]), + J(stones[handi])); + } + } else if (!strncmp(line, "clear", 5)) { + clear_board(); + handi = 0; + } else if (!strncmp(line, "done", 4)) { + if (handi == 1) /* Don't bother with checks later */ + printf("\nHandicap cannot be one stone. Either add " + "some more, or delete the only stone.\n"); + else + break; + } else { + int pos = string_to_location(board_size, line); + if (pos != NO_MOVE) { + if (board[pos] != EMPTY) + printf("\nThere's already a stone there.\n"); + else { + add_stone(pos, BLACK); + stones[handi++] = pos; + } + } else + printf("\nInvalid command: %s", line); + } + } } - } - gameinfo->handicap = handi; - gameinfo->to_move = (handi ? WHITE : BLACK); + gameinfo->handicap = handi; + gameinfo->to_move = (handi ? WHITE : BLACK); } - /* * Local Variables: - * tab-width: 8 - * c-basic-offset: 2 + * tab-width: 4 + * c-basic-offset: 4 * End: */ diff --git a/interface/play_gmp.c b/interface/play_gmp.c index 9099525..270038e 100644 --- a/interface/play_gmp.c +++ b/interface/play_gmp.c @@ -24,254 +24,246 @@ #include "gnugo.h" #include "liberty.h" +#include #include #include -#include -#include "interface.h" +#include "gg_utils.h" #include "gmp.h" +#include "interface.h" #include "sgftree.h" -#include "gg_utils.h" /* --------------------------------------------------------------*/ /* Play a game against a go-modem-protocol (GMP) client. */ /* --------------------------------------------------------------*/ -void -play_gmp(Gameinfo *gameinfo, int simplified) +void play_gmp(Gameinfo* gameinfo, int simplified) { - SGFTree sgftree; + SGFTree sgftree; + + Gmp* ge; + GmpResult message; + const char* error; - Gmp *ge; - GmpResult message; - const char *error; - - int i, j; - int passes = 0; /* two passes and its over */ - int to_move; /* who's turn is next ? */ + int i, j; + int passes = 0; /* two passes and its over */ + int to_move; /* who's turn is next ? */ - int mycolor = -1; /* who has which color */ - int yourcolor; + int mycolor = -1; /* who has which color */ + int yourcolor; - if (gameinfo->computer_player == WHITE) - mycolor = 1; - else if (gameinfo->computer_player == BLACK) - mycolor = 0; + if (gameinfo->computer_player == WHITE) + mycolor = 1; + else if (gameinfo->computer_player == BLACK) + mycolor = 0; - sgftree_clear(&sgftree); - sgftreeCreateHeaderNode(&sgftree, board_size, komi, gameinfo->handicap); + sgftree_clear(&sgftree); + sgftreeCreateHeaderNode(&sgftree, board_size, komi, gameinfo->handicap); - ge = gmp_create(0, 1); - TRACE("board size=%d\n", board_size); + ge = gmp_create(0, 1); + TRACE("board size=%d\n", board_size); - /* + /* * The specification of the go modem protocol doesn't even discuss * komi. So we have to guess the komi. If the komi is set on the * command line, keep it. Otherwise, its value will be 0.0 and we * use 5.5 in an even game, 0.5 otherwise. */ - if (komi == 0.0) { - if (gameinfo->handicap == 0) - komi = 5.5; - else - komi = 0.5; - } + if (komi == 0.0) { + if (gameinfo->handicap == 0) + komi = 5.5; + else + komi = 0.5; + } - if (!simplified) { - /* Leave all the -1's so the client can negotiate the game parameters. */ - if (chinese_rules) - gmp_startGame(ge, -1, -1, 5.5, -1, mycolor, 0); - else - gmp_startGame(ge, -1, -1, 5.5, 0, mycolor, 0); - } - else { - gmp_startGame(ge, board_size, gameinfo->handicap, - komi, chinese_rules, mycolor, 1); - } - - do { - message = gmp_check(ge, 1, NULL, NULL, &error); - } while (message == gmp_nothing || message == gmp_reset); - - if (message == gmp_err) { - fprintf(stderr, "gnugo-gmp: Error \"%s\" occurred.\n", error); - exit(EXIT_FAILURE); - } - else if (message != gmp_newGame) { - fprintf(stderr, "gnugo-gmp: Expecting a newGame, got %s\n", - gmp_resultString(message)); - exit(EXIT_FAILURE); - } - - gameinfo->handicap = gmp_handicap(ge); - if (!check_boardsize(gmp_size(ge), stderr)) - exit(EXIT_FAILURE); - - gnugo_clear_board(gmp_size(ge)); - - /* Let's pretend GMP knows about komi in case something will ever change. */ - komi = gmp_komi(ge); + if (!simplified) { + /* Leave all the -1's so the client can negotiate the game parameters. */ + if (chinese_rules) + gmp_startGame(ge, -1, -1, 5.5, -1, mycolor, 0); + else + gmp_startGame(ge, -1, -1, 5.5, 0, mycolor, 0); + } else { + gmp_startGame(ge, board_size, gameinfo->handicap, + komi, chinese_rules, mycolor, 1); + } + + do { + message = gmp_check(ge, 1, NULL, NULL, &error); + } while (message == gmp_nothing || message == gmp_reset); + + if (message == gmp_err) { + fprintf(stderr, "gnugo-gmp: Error \"%s\" occurred.\n", error); + exit(EXIT_FAILURE); + } else if (message != gmp_newGame) { + fprintf(stderr, "gnugo-gmp: Expecting a newGame, got %s\n", + gmp_resultString(message)); + exit(EXIT_FAILURE); + } + + gameinfo->handicap = gmp_handicap(ge); + if (!check_boardsize(gmp_size(ge), stderr)) + exit(EXIT_FAILURE); + + gnugo_clear_board(gmp_size(ge)); + + /* Let's pretend GMP knows about komi in case something will ever change. */ + komi = gmp_komi(ge); #if ORACLE - if (metamachine && oracle_exists) - oracle_clear_board(board_size); + if (metamachine && oracle_exists) + oracle_clear_board(board_size); #endif - sgfOverwritePropertyInt(sgftree.root, "SZ", board_size); - - TRACE("size=%d, handicap=%d, komi=%f\n", board_size, - gameinfo->handicap, komi); - - if (gameinfo->handicap) - to_move = WHITE; - else - to_move = BLACK; - - if (gmp_iAmWhite(ge)) { - mycolor = WHITE; /* computer white */ - yourcolor = BLACK; /* human black */ - } - else { - mycolor = BLACK; - yourcolor = WHITE; - } - - gameinfo->computer_player = mycolor; - sgf_write_header(sgftree.root, 1, get_random_seed(), komi, - gameinfo->handicap, get_level(), chinese_rules); - gameinfo->handicap = gnugo_sethand(gameinfo->handicap, sgftree.root); - sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap); - - /* main GMP loop */ - while (passes < 2) { - - if (to_move == yourcolor) { - int move; - /* Get opponent's move from gmp client. */ - message = gmp_check(ge, 1, &j, &i, &error); - - if (message == gmp_err) { - fprintf(stderr, "GNU Go: Sorry, error from gmp client\n"); - sgftreeAddComment(&sgftree, "got error from gmp client"); - sgffile_output(&sgftree); - return; - } - - if (message == gmp_undo) { - int k; - assert(j > 0); - - for (k = 0; k < j; k++) { - if (!undo_move(1)) { - fprintf(stderr, "GNU Go: play_gmp UNDO: can't undo %d moves\n", - j - k); - break; - } - sgftreeAddComment(&sgftree, "undone"); - sgftreeBack(&sgftree); - to_move = OTHER_COLOR(to_move); - } - continue; - } - - if (message == gmp_pass) { - passes++; - move = PASS_MOVE; - } - else { - passes = 0; - move = POS(i, j); - } - - TRACE("\nyour move: %1m\n\n", move); - sgftreeAddPlay(&sgftree, to_move, I(move), J(move)); - gnugo_play_move(move, yourcolor); - sgffile_output(&sgftree); + sgfOverwritePropertyInt(sgftree.root, "SZ", board_size); + + TRACE("size=%d, handicap=%d, komi=%f\n", board_size, + gameinfo->handicap, komi); + if (gameinfo->handicap) + to_move = WHITE; + else + to_move = BLACK; + + if (gmp_iAmWhite(ge)) { + mycolor = WHITE; /* computer white */ + yourcolor = BLACK; /* human black */ + } else { + mycolor = BLACK; + yourcolor = WHITE; } - else { - /* Generate my next move. */ - float move_value; - int move; - if (autolevel_on) - adjust_level_offset(mycolor); - move = genmove(mycolor, &move_value, NULL); - gnugo_play_move(move, mycolor); - sgffile_add_debuginfo(sgftree.lastnode, move_value); - - if (is_pass(move)) { - /* pass */ - sgftreeAddPlay(&sgftree, to_move, -1, -1); - gmp_sendPass(ge); - ++passes; - } - else { - /* not pass */ - sgftreeAddPlay(&sgftree, to_move, I(move), J(move)); - gmp_sendMove(ge, J(move), I(move)); - passes = 0; - TRACE("\nmy move: %1m\n\n", move); - } - sgffile_add_debuginfo(sgftree.lastnode, 0.0); - sgffile_output(&sgftree); + + gameinfo->computer_player = mycolor; + sgf_write_header(sgftree.root, 1, get_random_seed(), komi, + gameinfo->handicap, get_level(), chinese_rules); + gameinfo->handicap = gnugo_sethand(gameinfo->handicap, sgftree.root); + sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap); + + /* main GMP loop */ + while (passes < 2) { + + if (to_move == yourcolor) { + int move; + /* Get opponent's move from gmp client. */ + message = gmp_check(ge, 1, &j, &i, &error); + + if (message == gmp_err) { + fprintf(stderr, "GNU Go: Sorry, error from gmp client\n"); + sgftreeAddComment(&sgftree, "got error from gmp client"); + sgffile_output(&sgftree); + return; + } + + if (message == gmp_undo) { + int k; + assert(j > 0); + + for (k = 0; k < j; k++) { + if (!undo_move(1)) { + fprintf(stderr, "GNU Go: play_gmp UNDO: can't undo %d moves\n", + j - k); + break; + } + sgftreeAddComment(&sgftree, "undone"); + sgftreeBack(&sgftree); + to_move = OTHER_COLOR(to_move); + } + continue; + } + + if (message == gmp_pass) { + passes++; + move = PASS_MOVE; + } else { + passes = 0; + move = POS(i, j); + } + + TRACE("\nyour move: %1m\n\n", move); + sgftreeAddPlay(&sgftree, to_move, I(move), J(move)); + gnugo_play_move(move, yourcolor); + sgffile_output(&sgftree); + + } else { + /* Generate my next move. */ + float move_value; + int move; + if (autolevel_on) + adjust_level_offset(mycolor); + move = genmove(mycolor, &move_value, NULL); + gnugo_play_move(move, mycolor); + sgffile_add_debuginfo(sgftree.lastnode, move_value); + + if (is_pass(move)) { + /* pass */ + sgftreeAddPlay(&sgftree, to_move, -1, -1); + gmp_sendPass(ge); + ++passes; + } else { + /* not pass */ + sgftreeAddPlay(&sgftree, to_move, I(move), J(move)); + gmp_sendMove(ge, J(move), I(move)); + passes = 0; + TRACE("\nmy move: %1m\n\n", move); + } + sgffile_add_debuginfo(sgftree.lastnode, 0.0); + sgffile_output(&sgftree); + } + + to_move = OTHER_COLOR(to_move); } - - to_move = OTHER_COLOR(to_move); - } - - /* two passes: game over */ - gmp_sendPass(ge); - - if (!quiet) - fprintf(stderr, "Game over - waiting for client to shut us down\n"); - who_wins(mycolor, stderr); - - if (showtime) { - gprintf("\nSLOWEST MOVE: %d at %1m ", slowest_movenum, slowest_move); - fprintf(stderr, "(%.2f seconds)\n", slowest_time); - fprintf(stderr, "\nAVERAGE TIME: %.2f seconds per move\n", - total_time / movenum); - fprintf(stderr, "\nTOTAL TIME: %.2f seconds\n", - total_time); - } - - - /* play_gmp() does not return to main(), therefore the score + + /* two passes: game over */ + gmp_sendPass(ge); + + if (!quiet) + fprintf(stderr, "Game over - waiting for client to shut us down\n"); + who_wins(mycolor, stderr); + + if (showtime) { + gprintf("\nSLOWEST MOVE: %d at %1m ", slowest_movenum, slowest_move); + fprintf(stderr, "(%.2f seconds)\n", slowest_time); + fprintf(stderr, "\nAVERAGE TIME: %.2f seconds per move\n", + total_time / movenum); + fprintf(stderr, "\nTOTAL TIME: %.2f seconds\n", + total_time); + } + + /* play_gmp() does not return to main(), therefore the score * writing code is here. */ - { - float score = gnugo_estimate_score(NULL, NULL); - sgfWriteResult(sgftree.root, score, 1); - } - sgffile_output(&sgftree); - - if (!simplified) { - /* We hang around here until cgoban asks us to go, since + { + float score = gnugo_estimate_score(NULL, NULL); + sgfWriteResult(sgftree.root, score, 1); + } + sgffile_output(&sgftree); + + if (!simplified) { + /* We hang around here until cgoban asks us to go, since * sometimes cgoban crashes if we exit first. * * FIXME: Check if this is still needed. I made it dependand on * `simplifed' just to avoid changes in GMP mode. */ - while (1) { - message = gmp_check(ge, 1, &j, &i, &error); - if (!quiet) - fprintf(stderr, "Message %d from gmp\n", message); - if (message == gmp_err) - break; + while (1) { + message = gmp_check(ge, 1, &j, &i, &error); + if (!quiet) + fprintf(stderr, "Message %d from gmp\n", message); + if (message == gmp_err) + break; + } } - } #if ORACLE - if (metamachine && oracle_exists) - dismiss_oracle(); + if (metamachine && oracle_exists) + dismiss_oracle(); #endif - if (!quiet) - fprintf(stderr, "gnugo going down\n"); + if (!quiet) + fprintf(stderr, "gnugo going down\n"); } /* * Local Variables: - * tab-width: 8 - * c-basic-offset: 2 + * tab-width: 4 + * c-basic-offset: 4 * End: */ diff --git a/interface/play_gtp.c b/interface/play_gtp.c index f5e416d..cfa3130 100644 --- a/interface/play_gtp.c +++ b/interface/play_gtp.c @@ -23,28 +23,27 @@ #include "gnugo.h" -#include #include #include -#include #include +#include +#include +#include "gg_utils.h" +#include "gtp.h" #include "interface.h" #include "liberty.h" -#include "gtp.h" -#include "gg_utils.h" /* Internal state that's not part of the engine. */ static int report_uncertainty = 0; static int gtp_orientation = 0; static void gtp_print_code(int c); -static void gtp_print_vertices2(int n, int *moves); -static void rotate_on_input(int ai, int aj, int *bi, int *bj); -static void rotate_on_output(int ai, int aj, int *bi, int *bj); +static void gtp_print_vertices2(int n, int* moves); +static void rotate_on_input(int ai, int aj, int* bi, int* bj); +static void rotate_on_output(int ai, int aj, int* bi, int* bj); - -#define DECLARE(func) static int func(char *s) +#define DECLARE(func) static int func(char* s) DECLARE(gtp_aa_confirm_safety); DECLARE(gtp_accurate_approxlib); @@ -185,177 +184,174 @@ DECLARE(gtp_worm_stones); /* List of known commands. */ static struct gtp_command commands[] = { - {"aa_confirm_safety", gtp_aa_confirm_safety}, - {"accurate_approxlib", gtp_accurate_approxlib}, - {"accuratelib", gtp_accuratelib}, - {"advance_random_seed", gtp_advance_random_seed}, - {"all_legal", gtp_all_legal}, - {"all_move_values", gtp_all_move_values}, - {"analyze_eyegraph", gtp_analyze_eyegraph}, - {"analyze_semeai", gtp_analyze_semeai}, - {"analyze_semeai_after_move", gtp_analyze_semeai_after_move}, - {"attack", gtp_attack}, - {"attack_either", gtp_attack_either}, - {"black", gtp_playblack}, - {"block_off", gtp_block_off}, - {"boardsize", gtp_set_boardsize}, - {"break_in", gtp_break_in}, - {"captures", gtp_captures}, - {"clear_board", gtp_clear_board}, - {"clear_cache", gtp_clear_cache}, - {"color", gtp_what_color}, - {"combination_attack", gtp_combination_attack}, - {"combination_defend", gtp_combination_defend}, - {"connect", gtp_connect}, - {"countlib", gtp_countlib}, - {"cputime", gtp_cputime}, - {"decrease_depths", gtp_decrease_depths}, - {"defend", gtp_defend}, - {"defend_both", gtp_defend_both}, - {"disconnect", gtp_disconnect}, - {"does_attack", gtp_does_attack}, - {"does_defend", gtp_does_defend}, - {"does_surround", gtp_does_surround}, - {"dragon_data", gtp_dragon_data}, - {"dragon_status", gtp_dragon_status}, - {"dragon_stones", gtp_dragon_stones}, - {"draw_search_area", gtp_draw_search_area}, - {"dump_stack", gtp_dump_stack}, - {"echo" , gtp_echo}, - {"echo_err" , gtp_echo_err}, - {"estimate_score", gtp_estimate_score}, - {"eval_eye", gtp_eval_eye}, - {"experimental_score", gtp_experimental_score}, - {"eye_data", gtp_eye_data}, - {"final_score", gtp_final_score}, - {"final_status", gtp_final_status}, - {"final_status_list", gtp_final_status_list}, - {"findlib", gtp_findlib}, - {"finish_sgftrace", gtp_finish_sgftrace}, - {"fixed_handicap", gtp_fixed_handicap}, - {"followup_influence", gtp_followup_influence}, - {"genmove", gtp_genmove}, - {"genmove_black", gtp_genmove_black}, - {"genmove_white", gtp_genmove_white}, - {"get_connection_node_counter", gtp_get_connection_node_counter}, - {"get_handicap", gtp_get_handicap}, - {"get_komi", gtp_get_komi}, - {"get_life_node_counter", gtp_get_life_node_counter}, - {"get_owl_node_counter", gtp_get_owl_node_counter}, - {"get_random_seed", gtp_get_random_seed}, - {"get_reading_node_counter", gtp_get_reading_node_counter}, - {"get_trymove_counter", gtp_get_trymove_counter}, - {"gg-undo", gtp_gg_undo}, - {"gg_genmove", gtp_gg_genmove}, - {"half_eye_data", gtp_half_eye_data}, - {"help", gtp_list_commands}, - {"increase_depths", gtp_increase_depths}, - {"initial_influence", gtp_initial_influence}, - {"invariant_hash_for_moves",gtp_invariant_hash_for_moves}, - {"invariant_hash", gtp_invariant_hash}, - {"is_legal", gtp_is_legal}, - {"is_surrounded", gtp_is_surrounded}, - {"kgs-genmove_cleanup", gtp_kgs_genmove_cleanup}, - {"known_command", gtp_known_command}, - {"komi", gtp_set_komi}, - {"ladder_attack", gtp_ladder_attack}, - {"last_move", gtp_last_move}, - {"level", gtp_set_level}, - {"limit_search", gtp_limit_search}, - {"list_commands", gtp_list_commands}, - {"list_stones", gtp_list_stones}, - {"loadsgf", gtp_loadsgf}, - {"move_influence", gtp_move_influence}, - {"move_probabilities", gtp_move_probabilities}, - {"move_reasons", gtp_move_reasons}, - {"move_uncertainty", gtp_move_uncertainty}, - {"move_history", gtp_move_history}, - {"name", gtp_name}, - {"new_score", gtp_estimate_score}, - {"orientation", gtp_set_orientation}, - {"owl_attack", gtp_owl_attack}, - {"owl_connection_defends", gtp_owl_connection_defends}, - {"owl_defend", gtp_owl_defend}, - {"owl_does_attack", gtp_owl_does_attack}, - {"owl_does_defend", gtp_owl_does_defend}, - {"owl_substantial", gtp_owl_substantial}, - {"owl_threaten_attack", gtp_owl_threaten_attack}, - {"owl_threaten_defense", gtp_owl_threaten_defense}, - {"place_free_handicap", gtp_place_free_handicap}, - {"play", gtp_play}, - {"popgo", gtp_popgo}, - {"printsgf", gtp_printsgf}, - {"protocol_version", gtp_protocol_version}, - {"query_boardsize", gtp_query_boardsize}, - {"query_orientation", gtp_query_orientation}, - {"quit", gtp_quit}, - {"reg_genmove", gtp_reg_genmove}, - {"report_uncertainty", gtp_report_uncertainty}, - {"reset_connection_node_counter", gtp_reset_connection_node_counter}, - {"reset_life_node_counter", gtp_reset_life_node_counter}, - {"reset_owl_node_counter", gtp_reset_owl_node_counter}, - {"reset_reading_node_counter", gtp_reset_reading_node_counter}, - {"reset_search_mask", gtp_reset_search_mask}, - {"reset_trymove_counter", gtp_reset_trymove_counter}, - {"restricted_genmove", gtp_restricted_genmove}, - {"same_dragon", gtp_same_dragon}, - {"set_free_handicap", gtp_set_free_handicap}, - {"set_random_seed", gtp_set_random_seed}, - {"set_search_diamond", gtp_set_search_diamond}, - {"set_search_limit", gtp_set_search_limit}, - {"showboard", gtp_showboard}, - {"start_sgftrace", gtp_start_sgftrace}, - {"surround_map", gtp_surround_map}, - {"tactical_analyze_semeai", gtp_tactical_analyze_semeai}, - {"test_eyeshape", gtp_test_eyeshape}, - {"time_left", gtp_time_left}, - {"time_settings", gtp_time_settings}, - {"top_moves", gtp_top_moves}, - {"top_moves_black", gtp_top_moves_black}, - {"top_moves_white", gtp_top_moves_white}, - {"tryko", gtp_tryko}, - {"trymove", gtp_trymove}, - {"tune_move_ordering", gtp_tune_move_ordering}, - {"unconditional_status", gtp_unconditional_status}, - {"undo", gtp_undo}, - {"version", gtp_program_version}, - {"white", gtp_playwhite}, - {"worm_cutstone", gtp_worm_cutstone}, - {"worm_data", gtp_worm_data}, - {"worm_stones", gtp_worm_stones}, - {NULL, NULL} + { "aa_confirm_safety", gtp_aa_confirm_safety }, + { "accurate_approxlib", gtp_accurate_approxlib }, + { "accuratelib", gtp_accuratelib }, + { "advance_random_seed", gtp_advance_random_seed }, + { "all_legal", gtp_all_legal }, + { "all_move_values", gtp_all_move_values }, + { "analyze_eyegraph", gtp_analyze_eyegraph }, + { "analyze_semeai", gtp_analyze_semeai }, + { "analyze_semeai_after_move", gtp_analyze_semeai_after_move }, + { "attack", gtp_attack }, + { "attack_either", gtp_attack_either }, + { "black", gtp_playblack }, + { "block_off", gtp_block_off }, + { "boardsize", gtp_set_boardsize }, + { "break_in", gtp_break_in }, + { "captures", gtp_captures }, + { "clear_board", gtp_clear_board }, + { "clear_cache", gtp_clear_cache }, + { "color", gtp_what_color }, + { "combination_attack", gtp_combination_attack }, + { "combination_defend", gtp_combination_defend }, + { "connect", gtp_connect }, + { "countlib", gtp_countlib }, + { "cputime", gtp_cputime }, + { "decrease_depths", gtp_decrease_depths }, + { "defend", gtp_defend }, + { "defend_both", gtp_defend_both }, + { "disconnect", gtp_disconnect }, + { "does_attack", gtp_does_attack }, + { "does_defend", gtp_does_defend }, + { "does_surround", gtp_does_surround }, + { "dragon_data", gtp_dragon_data }, + { "dragon_status", gtp_dragon_status }, + { "dragon_stones", gtp_dragon_stones }, + { "draw_search_area", gtp_draw_search_area }, + { "dump_stack", gtp_dump_stack }, + { "echo", gtp_echo }, + { "echo_err", gtp_echo_err }, + { "estimate_score", gtp_estimate_score }, + { "eval_eye", gtp_eval_eye }, + { "experimental_score", gtp_experimental_score }, + { "eye_data", gtp_eye_data }, + { "final_score", gtp_final_score }, + { "final_status", gtp_final_status }, + { "final_status_list", gtp_final_status_list }, + { "findlib", gtp_findlib }, + { "finish_sgftrace", gtp_finish_sgftrace }, + { "fixed_handicap", gtp_fixed_handicap }, + { "followup_influence", gtp_followup_influence }, + { "genmove", gtp_genmove }, + { "genmove_black", gtp_genmove_black }, + { "genmove_white", gtp_genmove_white }, + { "get_connection_node_counter", gtp_get_connection_node_counter }, + { "get_handicap", gtp_get_handicap }, + { "get_komi", gtp_get_komi }, + { "get_life_node_counter", gtp_get_life_node_counter }, + { "get_owl_node_counter", gtp_get_owl_node_counter }, + { "get_random_seed", gtp_get_random_seed }, + { "get_reading_node_counter", gtp_get_reading_node_counter }, + { "get_trymove_counter", gtp_get_trymove_counter }, + { "gg-undo", gtp_gg_undo }, + { "gg_genmove", gtp_gg_genmove }, + { "half_eye_data", gtp_half_eye_data }, + { "help", gtp_list_commands }, + { "increase_depths", gtp_increase_depths }, + { "initial_influence", gtp_initial_influence }, + { "invariant_hash_for_moves", gtp_invariant_hash_for_moves }, + { "invariant_hash", gtp_invariant_hash }, + { "is_legal", gtp_is_legal }, + { "is_surrounded", gtp_is_surrounded }, + { "kgs-genmove_cleanup", gtp_kgs_genmove_cleanup }, + { "known_command", gtp_known_command }, + { "komi", gtp_set_komi }, + { "ladder_attack", gtp_ladder_attack }, + { "last_move", gtp_last_move }, + { "level", gtp_set_level }, + { "limit_search", gtp_limit_search }, + { "list_commands", gtp_list_commands }, + { "list_stones", gtp_list_stones }, + { "loadsgf", gtp_loadsgf }, + { "move_influence", gtp_move_influence }, + { "move_probabilities", gtp_move_probabilities }, + { "move_reasons", gtp_move_reasons }, + { "move_uncertainty", gtp_move_uncertainty }, + { "move_history", gtp_move_history }, + { "name", gtp_name }, + { "new_score", gtp_estimate_score }, + { "orientation", gtp_set_orientation }, + { "owl_attack", gtp_owl_attack }, + { "owl_connection_defends", gtp_owl_connection_defends }, + { "owl_defend", gtp_owl_defend }, + { "owl_does_attack", gtp_owl_does_attack }, + { "owl_does_defend", gtp_owl_does_defend }, + { "owl_substantial", gtp_owl_substantial }, + { "owl_threaten_attack", gtp_owl_threaten_attack }, + { "owl_threaten_defense", gtp_owl_threaten_defense }, + { "place_free_handicap", gtp_place_free_handicap }, + { "play", gtp_play }, + { "popgo", gtp_popgo }, + { "printsgf", gtp_printsgf }, + { "protocol_version", gtp_protocol_version }, + { "query_boardsize", gtp_query_boardsize }, + { "query_orientation", gtp_query_orientation }, + { "quit", gtp_quit }, + { "reg_genmove", gtp_reg_genmove }, + { "report_uncertainty", gtp_report_uncertainty }, + { "reset_connection_node_counter", gtp_reset_connection_node_counter }, + { "reset_life_node_counter", gtp_reset_life_node_counter }, + { "reset_owl_node_counter", gtp_reset_owl_node_counter }, + { "reset_reading_node_counter", gtp_reset_reading_node_counter }, + { "reset_search_mask", gtp_reset_search_mask }, + { "reset_trymove_counter", gtp_reset_trymove_counter }, + { "restricted_genmove", gtp_restricted_genmove }, + { "same_dragon", gtp_same_dragon }, + { "set_free_handicap", gtp_set_free_handicap }, + { "set_random_seed", gtp_set_random_seed }, + { "set_search_diamond", gtp_set_search_diamond }, + { "set_search_limit", gtp_set_search_limit }, + { "showboard", gtp_showboard }, + { "start_sgftrace", gtp_start_sgftrace }, + { "surround_map", gtp_surround_map }, + { "tactical_analyze_semeai", gtp_tactical_analyze_semeai }, + { "test_eyeshape", gtp_test_eyeshape }, + { "time_left", gtp_time_left }, + { "time_settings", gtp_time_settings }, + { "top_moves", gtp_top_moves }, + { "top_moves_black", gtp_top_moves_black }, + { "top_moves_white", gtp_top_moves_white }, + { "tryko", gtp_tryko }, + { "trymove", gtp_trymove }, + { "tune_move_ordering", gtp_tune_move_ordering }, + { "unconditional_status", gtp_unconditional_status }, + { "undo", gtp_undo }, + { "version", gtp_program_version }, + { "white", gtp_playwhite }, + { "worm_cutstone", gtp_worm_cutstone }, + { "worm_data", gtp_worm_data }, + { "worm_stones", gtp_worm_stones }, + { NULL, NULL } }; - /* Start playing using the Go Text Protocol. */ -void -play_gtp(FILE *gtp_input, FILE *gtp_output, FILE *gtp_dump_commands, - int gtp_initial_orientation) +void play_gtp(FILE* gtp_input, FILE* gtp_output, FILE* gtp_dump_commands, + int gtp_initial_orientation) { - /* Make sure `gtp_output' is unbuffered. (Line buffering is also + /* Make sure `gtp_output' is unbuffered. (Line buffering is also * okay but not necessary. Block buffering breaks GTP mode.) * * FIXME: Maybe should go to `gtp.c'? */ - setbuf(gtp_output, NULL); - - /* Inform the GTP utility functions about the board size. */ - gtp_internal_set_boardsize(board_size); - gtp_orientation = gtp_initial_orientation; - gtp_set_vertex_transform_hooks(rotate_on_input, rotate_on_output); - - /* Initialize time handling. */ - init_timers(); - - /* Prepare pattern matcher and reading code. */ - reset_engine(); - clearstats(); - gtp_main_loop(commands, gtp_input, gtp_output, gtp_dump_commands); - if (showstatistics) - showstats(); + setbuf(gtp_output, NULL); + + /* Inform the GTP utility functions about the board size. */ + gtp_internal_set_boardsize(board_size); + gtp_orientation = gtp_initial_orientation; + gtp_set_vertex_transform_hooks(rotate_on_input, rotate_on_output); + + /* Initialize time handling. */ + init_timers(); + + /* Prepare pattern matcher and reading code. */ + reset_engine(); + clearstats(); + gtp_main_loop(commands, gtp_input, gtp_output, gtp_dump_commands); + if (showstatistics) + showstats(); } - /**************************** * Administrative commands. * ****************************/ @@ -368,14 +364,13 @@ play_gtp(FILE *gtp_input, FILE *gtp_output, FILE *gtp_dump_commands, * Status: GTP version 2 standard command. */ static int -gtp_quit(char *s) +gtp_quit(char* s) { - UNUSED(s); - gtp_success(""); - return GTP_QUIT; + UNUSED(s); + gtp_success(""); + return GTP_QUIT; } - /* Function: Report protocol version. * Arguments: none * Fails: never @@ -384,13 +379,12 @@ gtp_quit(char *s) * Status: GTP version 2 standard command. */ static int -gtp_protocol_version(char *s) +gtp_protocol_version(char* s) { - UNUSED(s); - return gtp_success("%d", gtp_version); + UNUSED(s); + return gtp_success("%d", gtp_version); } - /**************************** * Program identity. * ****************************/ @@ -403,15 +397,12 @@ gtp_protocol_version(char *s) * Status: GTP version 2 standard command. */ static int -gtp_name(char *s) +gtp_name(char* s) { - UNUSED(s); - return gtp_success("GNU Go"); + UNUSED(s); + return gtp_success("GNU Go"); } - - - /* Function: Report the version number of the program. * Arguments: none * Fails: never @@ -420,13 +411,12 @@ gtp_name(char *s) * Status: GTP version 2 standard command. */ static int -gtp_program_version(char *s) +gtp_program_version(char* s) { - UNUSED(s); - return gtp_success(VERSION); + UNUSED(s); + return gtp_success(VERSION); } - /*************************** * Setting the board size. * ***************************/ @@ -439,31 +429,31 @@ gtp_program_version(char *s) * Status: GTP version 2 standard command. */ static int -gtp_set_boardsize(char *s) +gtp_set_boardsize(char* s) { - int boardsize; + int boardsize; - if (sscanf(s, "%d", &boardsize) < 1) - return gtp_failure("boardsize not an integer"); - - if (!check_boardsize(boardsize, NULL)) { - if (gtp_version == 1) - return gtp_failure("unacceptable boardsize"); - else - return gtp_failure("unacceptable size"); - } + if (sscanf(s, "%d", &boardsize) < 1) + return gtp_failure("boardsize not an integer"); + + if (!check_boardsize(boardsize, NULL)) { + if (gtp_version == 1) + return gtp_failure("unacceptable boardsize"); + else + return gtp_failure("unacceptable size"); + } - /* If this is called with a non-empty board, we assume that a new + /* If this is called with a non-empty board, we assume that a new * game will be started, for which we want a new random seed. */ - if (stones_on_board(BLACK | WHITE) > 0) - update_random_seed(); + if (stones_on_board(BLACK | WHITE) > 0) + update_random_seed(); - board_size = boardsize; - clear_board(); - gtp_internal_set_boardsize(boardsize); - reset_engine(); - return gtp_success(""); + board_size = boardsize; + clear_board(); + gtp_internal_set_boardsize(boardsize); + reset_engine(); + return gtp_success(""); } /* Function: Find the current boardsize @@ -472,11 +462,11 @@ gtp_set_boardsize(char *s) * Returns: board_size */ static int -gtp_query_boardsize(char *s) +gtp_query_boardsize(char* s) { - UNUSED(s); + UNUSED(s); - return gtp_success("%d", board_size); + return gtp_success("%d", board_size); } /*********************** @@ -491,20 +481,20 @@ gtp_query_boardsize(char *s) * Status: GTP version 2 standard command. */ static int -gtp_clear_board(char *s) +gtp_clear_board(char* s) { - UNUSED(s); + UNUSED(s); - /* If this is called with a non-empty board, we assume that a new + /* If this is called with a non-empty board, we assume that a new * game will be started, for which we want a new random seed. */ - if (stones_on_board(BLACK | WHITE) > 0) - update_random_seed(); + if (stones_on_board(BLACK | WHITE) > 0) + update_random_seed(); + + clear_board(); + init_timers(); - clear_board(); - init_timers(); - - return gtp_success(""); + return gtp_success(""); } /**************************** @@ -517,19 +507,19 @@ gtp_clear_board(char *s) * Returns: nothing */ static int -gtp_set_orientation(char *s) +gtp_set_orientation(char* s) { - int orientation; - if (sscanf(s, "%d", &orientation) < 1) - return gtp_failure("orientation not an integer"); - - if (orientation < 0 || orientation > 7) - return gtp_failure("unacceptable orientation"); + int orientation; + if (sscanf(s, "%d", &orientation) < 1) + return gtp_failure("orientation not an integer"); + + if (orientation < 0 || orientation > 7) + return gtp_failure("unacceptable orientation"); - clear_board(); - gtp_orientation = orientation; - gtp_set_vertex_transform_hooks(rotate_on_input, rotate_on_output); - return gtp_success(""); + clear_board(); + gtp_orientation = orientation; + gtp_set_vertex_transform_hooks(rotate_on_input, rotate_on_output); + return gtp_success(""); } /* Function: Find the current orientation @@ -538,11 +528,11 @@ gtp_set_orientation(char *s) * Returns: orientation */ static int -gtp_query_orientation(char *s) +gtp_query_orientation(char* s) { - UNUSED(s); + UNUSED(s); - return gtp_success("%d", gtp_orientation); + return gtp_success("%d", gtp_orientation); } /*************************** @@ -557,14 +547,13 @@ gtp_query_orientation(char *s) * Status: GTP version 2 standard command. */ static int -gtp_set_komi(char *s) +gtp_set_komi(char* s) { - if (sscanf(s, "%f", &komi) < 1) - return gtp_failure("komi not a float"); - - return gtp_success(""); -} + if (sscanf(s, "%f", &komi) < 1) + return gtp_failure("komi not a float"); + return gtp_success(""); +} /*************************** * Getting komi * @@ -576,13 +565,12 @@ gtp_set_komi(char *s) * Returns: Komi */ static int -gtp_get_komi(char *s) +gtp_get_komi(char* s) { - UNUSED(s); - return gtp_success("%4.1f", komi); + UNUSED(s); + return gtp_success("%4.1f", komi); } - /****************** * Playing moves. * ******************/ @@ -595,29 +583,27 @@ gtp_get_komi(char *s) * Status: Obsolete GTP version 1 command. */ static int -gtp_playblack(char *s) +gtp_playblack(char* s) { - int i, j; - char *c; + int i, j; + char* c; - for (c = s; *c; c++) - *c = tolower((int)*c); + for (c = s; *c; c++) + *c = tolower((int)*c); - if (strncmp(s, "pass", 4) == 0) { - i = -1; - j = -1; - } - else if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + if (strncmp(s, "pass", 4) == 0) { + i = -1; + j = -1; + } else if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - if (!is_allowed_move(POS(i, j), BLACK)) - return gtp_failure("illegal move"); + if (!is_allowed_move(POS(i, j), BLACK)) + return gtp_failure("illegal move"); - gnugo_play_move(POS(i, j), BLACK); - return gtp_success(""); + gnugo_play_move(POS(i, j), BLACK); + return gtp_success(""); } - /* Function: Play a white stone at the given vertex. * Arguments: vertex * Fails: invalid vertex, illegal move @@ -626,28 +612,26 @@ gtp_playblack(char *s) * Status: Obsolete GTP version 1 command. */ static int -gtp_playwhite(char *s) +gtp_playwhite(char* s) { - int i, j; - char *c; + int i, j; + char* c; - for (c = s; *c; c++) - *c = tolower((int)*c); + for (c = s; *c; c++) + *c = tolower((int)*c); - if (strncmp(s, "pass", 4) == 0) { - i = -1; - j = -1; - } - else if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); - - if (!is_allowed_move(POS(i, j), WHITE)) - return gtp_failure("illegal move"); + if (strncmp(s, "pass", 4) == 0) { + i = -1; + j = -1; + } else if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - gnugo_play_move(POS(i, j), WHITE); - return gtp_success(""); -} + if (!is_allowed_move(POS(i, j), WHITE)) + return gtp_failure("illegal move"); + gnugo_play_move(POS(i, j), WHITE); + return gtp_success(""); +} /* Function: Play a stone of the given color at the given vertex. * Arguments: color, vertex @@ -657,22 +641,21 @@ gtp_playwhite(char *s) * Status: GTP version 2 standard command. */ static int -gtp_play(char *s) +gtp_play(char* s) { - int i, j; - int color; + int i, j; + int color; - if (!gtp_decode_move(s, &color, &i, &j)) - return gtp_failure("invalid color or coordinate"); + if (!gtp_decode_move(s, &color, &i, &j)) + return gtp_failure("invalid color or coordinate"); - if (!is_allowed_move(POS(i, j), color)) - return gtp_failure("illegal move"); + if (!is_allowed_move(POS(i, j), color)) + return gtp_failure("illegal move"); - gnugo_play_move(POS(i, j), color); - return gtp_success(""); + gnugo_play_move(POS(i, j), color); + return gtp_success(""); } - /* Function: Set up fixed placement handicap stones. * Arguments: number of handicap stones * Fails: invalid number of stones for the current boardsize @@ -681,45 +664,44 @@ gtp_play(char *s) * Status: GTP version 2 standard command. */ static int -gtp_fixed_handicap(char *s) +gtp_fixed_handicap(char* s) { - int m, n; - int first = 1; - int this_handicap; + int m, n; + int first = 1; + int this_handicap; - if (gtp_version == 1) - clear_board(); - else if (stones_on_board(BLACK | WHITE) > 0) - return gtp_failure("board not empty"); + if (gtp_version == 1) + clear_board(); + else if (stones_on_board(BLACK | WHITE) > 0) + return gtp_failure("board not empty"); - if (sscanf(s, "%d", &this_handicap) < 1) - return gtp_failure("handicap not an integer"); - - if (this_handicap < 2 && (gtp_version > 1 || this_handicap != 0)) - return gtp_failure("invalid handicap"); + if (sscanf(s, "%d", &this_handicap) < 1) + return gtp_failure("handicap not an integer"); - if (place_fixed_handicap(this_handicap) != this_handicap) { - clear_board(); - return gtp_failure("invalid handicap"); - } + if (this_handicap < 2 && (gtp_version > 1 || this_handicap != 0)) + return gtp_failure("invalid handicap"); - handicap = this_handicap; + if (place_fixed_handicap(this_handicap) != this_handicap) { + clear_board(); + return gtp_failure("invalid handicap"); + } - gtp_start_response(GTP_SUCCESS); + handicap = this_handicap; - for (m = 0; m < board_size; m++) - for (n = 0; n < board_size; n++) - if (BOARD(m, n) != EMPTY) { - if (!first) - gtp_printf(" "); - else - first = 0; - gtp_mprintf("%m", m, n); - } - - return gtp_finish_response(); -} + gtp_start_response(GTP_SUCCESS); + for (m = 0; m < board_size; m++) + for (n = 0; n < board_size; n++) + if (BOARD(m, n) != EMPTY) { + if (!first) + gtp_printf(" "); + else + first = 0; + gtp_mprintf("%m", m, n); + } + + return gtp_finish_response(); +} /* Function: Choose free placement handicap stones and put them on the board. * Arguments: number of handicap stones @@ -729,37 +711,36 @@ gtp_fixed_handicap(char *s) * Status: GTP version 2 standard command. */ static int -gtp_place_free_handicap(char *s) +gtp_place_free_handicap(char* s) { - int m, n; - int first = 1; - int this_handicap; - if (sscanf(s, "%d", &this_handicap) < 1) - return gtp_failure("handicap not an integer"); - - if (stones_on_board(BLACK | WHITE) > 0) - return gtp_failure("board not empty"); + int m, n; + int first = 1; + int this_handicap; + if (sscanf(s, "%d", &this_handicap) < 1) + return gtp_failure("handicap not an integer"); - if (this_handicap < 2) - return gtp_failure("invalid handicap"); + if (stones_on_board(BLACK | WHITE) > 0) + return gtp_failure("board not empty"); - handicap = place_free_handicap(this_handicap); + if (this_handicap < 2) + return gtp_failure("invalid handicap"); - gtp_start_response(GTP_SUCCESS); + handicap = place_free_handicap(this_handicap); - for (m = 0; m < board_size; m++) - for (n = 0; n < board_size; n++) - if (BOARD(m, n) != EMPTY) { - if (!first) - gtp_printf(" "); - else - first = 0; - gtp_mprintf("%m", m, n); - } - - return gtp_finish_response(); -} + gtp_start_response(GTP_SUCCESS); + for (m = 0; m < board_size; m++) + for (n = 0; n < board_size; n++) + if (BOARD(m, n) != EMPTY) { + if (!first) + gtp_printf(" "); + else + first = 0; + gtp_mprintf("%m", m, n); + } + + return gtp_finish_response(); +} /* Function: Put free placement handicap stones on the board. * Arguments: list of vertices with handicap stones @@ -769,55 +750,52 @@ gtp_place_free_handicap(char *s) * Status: GTP version 2 standard command. */ static int -gtp_set_free_handicap(char *s) -{ - int n; - int i, j; - int k; - - if (stones_on_board(BLACK | WHITE) > 0) - return gtp_failure("board not empty"); +gtp_set_free_handicap(char* s) +{ + int n; + int i, j; + int k; + + if (stones_on_board(BLACK | WHITE) > 0) + return gtp_failure("board not empty"); + + for (k = 0; k < MAX_BOARD * MAX_BOARD; k++) { + n = gtp_decode_coord(s, &i, &j); + if (n > 0) { + if (board[POS(i, j)] != EMPTY) { + clear_board(); + return gtp_failure("repeated vertex"); + } + add_stone(POS(i, j), BLACK); + s += n; + } else if (sscanf(s, "%*s") != EOF) + return gtp_failure("invalid coordinate"); + else + break; + } - for (k = 0; k < MAX_BOARD * MAX_BOARD; k++) { - n = gtp_decode_coord(s, &i, &j); - if (n > 0) { - if (board[POS(i, j)] != EMPTY) { - clear_board(); - return gtp_failure("repeated vertex"); - } - add_stone(POS(i, j), BLACK); - s += n; + if (k < 2) { + clear_board(); + return gtp_failure("invalid handicap"); } - else if (sscanf(s, "%*s") != EOF) - return gtp_failure("invalid coordinate"); - else - break; - } - if (k < 2) { - clear_board(); - return gtp_failure("invalid handicap"); - } + handicap = k; - handicap = k; - - return gtp_success(""); + return gtp_success(""); } - /* Function: Get the handicap * Arguments: none * Fails: never * Returns: handicap */ static int -gtp_get_handicap(char *s) +gtp_get_handicap(char* s) { - UNUSED(s); - return gtp_success("%d", handicap); + UNUSED(s); + return gtp_success("%d", handicap); } - /* Function: Load an sgf file, possibly up to a move number or the first * occurence of a move. * Arguments: filename + move number, vertex, or nothing @@ -827,44 +805,43 @@ gtp_get_handicap(char *s) * Status: GTP version 2 standard command. */ static int -gtp_loadsgf(char *s) +gtp_loadsgf(char* s) { - char filename[GTP_BUFSIZE]; - char untilstring[GTP_BUFSIZE]; - SGFTree sgftree; - Gameinfo gameinfo; - int nread; - int color_to_move; - - nread = sscanf(s, "%s %s", filename, untilstring); - if (nread < 1) - return gtp_failure("missing filename"); + char filename[GTP_BUFSIZE]; + char untilstring[GTP_BUFSIZE]; + SGFTree sgftree; + Gameinfo gameinfo; + int nread; + int color_to_move; - sgftree_clear(&sgftree); - if (!sgftree_readfile(&sgftree, filename)) - return gtp_failure("cannot open or parse '%s'", filename); + nread = sscanf(s, "%s %s", filename, untilstring); + if (nread < 1) + return gtp_failure("missing filename"); - if (nread == 1) - color_to_move = gameinfo_play_sgftree_rot(&gameinfo, &sgftree, NULL, - gtp_orientation); - else - color_to_move = gameinfo_play_sgftree_rot(&gameinfo, &sgftree, untilstring, - gtp_orientation); + sgftree_clear(&sgftree); + if (!sgftree_readfile(&sgftree, filename)) + return gtp_failure("cannot open or parse '%s'", filename); - if (color_to_move == EMPTY) - return gtp_failure("cannot load '%s'", filename); - - gtp_internal_set_boardsize(board_size); - reset_engine(); - init_timers(); + if (nread == 1) + color_to_move = gameinfo_play_sgftree_rot(&gameinfo, &sgftree, NULL, + gtp_orientation); + else + color_to_move = gameinfo_play_sgftree_rot(&gameinfo, &sgftree, untilstring, + gtp_orientation); - sgfFreeNode(sgftree.root); + if (color_to_move == EMPTY) + return gtp_failure("cannot load '%s'", filename); - gtp_start_response(GTP_SUCCESS); - gtp_mprintf("%C", color_to_move); - return gtp_finish_response(); -} + gtp_internal_set_boardsize(board_size); + reset_engine(); + init_timers(); + sgfFreeNode(sgftree.root); + + gtp_start_response(GTP_SUCCESS); + gtp_mprintf("%C", color_to_move); + return gtp_finish_response(); +} /***************** * Board status. * @@ -876,15 +853,14 @@ gtp_loadsgf(char *s) * Returns: "black", "white", or "empty" */ static int -gtp_what_color(char *s) +gtp_what_color(char* s) { - int i, j; - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); - - return gtp_success(color_to_string(BOARD(i, j))); -} + int i, j; + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); + return gtp_success(color_to_string(BOARD(i, j))); +} /* Function: List vertices with either black or white stones. * Arguments: color @@ -892,29 +868,28 @@ gtp_what_color(char *s) * Returns: list of vertices */ static int -gtp_list_stones(char *s) +gtp_list_stones(char* s) { - int i, j; - int color = EMPTY; - int vertexi[MAX_BOARD * MAX_BOARD]; - int vertexj[MAX_BOARD * MAX_BOARD]; - int vertices = 0; - - if (!gtp_decode_color(s, &color)) - return gtp_failure("invalid color"); + int i, j; + int color = EMPTY; + int vertexi[MAX_BOARD * MAX_BOARD]; + int vertexj[MAX_BOARD * MAX_BOARD]; + int vertices = 0; - for (i = 0; i < board_size; i++) - for (j = 0; j < board_size; j++) - if (BOARD(i, j) == color) { - vertexi[vertices] = i; - vertexj[vertices++] = j; - } + if (!gtp_decode_color(s, &color)) + return gtp_failure("invalid color"); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertices(vertices, vertexi, vertexj); - return gtp_finish_response(); -} + for (i = 0; i < board_size; i++) + for (j = 0; j < board_size; j++) + if (BOARD(i, j) == color) { + vertexi[vertices] = i; + vertexj[vertices++] = j; + } + gtp_start_response(GTP_SUCCESS); + gtp_print_vertices(vertices, vertexi, vertexj); + return gtp_finish_response(); +} /* Function: Count number of liberties for the string at a vertex. * Arguments: vertex @@ -922,43 +897,41 @@ gtp_list_stones(char *s) * Returns: Number of liberties. */ static int -gtp_countlib(char *s) +gtp_countlib(char* s) { - int i, j; - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + int i, j; + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - return gtp_success("%d", countlib(POS(i, j))); + return gtp_success("%d", countlib(POS(i, j))); } - /* Function: Return the positions of the liberties for the string at a vertex. * Arguments: vertex * Fails: invalid vertex, empty vertex * Returns: Sorted space separated list of vertices. */ static int -gtp_findlib(char *s) +gtp_findlib(char* s) { - int i, j; - int libs[MAXLIBS]; - int liberties; - - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + int i, j; + int libs[MAXLIBS]; + int liberties; - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - liberties = findlib(POS(i, j), MAXLIBS, libs); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertices2(liberties, libs); - return gtp_finish_response(); -} + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); + liberties = findlib(POS(i, j), MAXLIBS, libs); + gtp_start_response(GTP_SUCCESS); + gtp_print_vertices2(liberties, libs); + return gtp_finish_response(); +} /* Function: Determine which liberties a stone of given color * will get if played at given vertex. @@ -967,27 +940,26 @@ gtp_findlib(char *s) * Returns: Sorted space separated list of liberties */ static int -gtp_accuratelib(char *s) +gtp_accuratelib(char* s) { - int i, j; - int color; - int libs[MAXLIBS]; - int liberties; + int i, j; + int color; + int libs[MAXLIBS]; + int liberties; - if (!gtp_decode_move(s, &color, &i, &j)) - return gtp_failure("invalid color or coordinate"); + if (!gtp_decode_move(s, &color, &i, &j)) + return gtp_failure("invalid color or coordinate"); - if (BOARD(i, j) != EMPTY) - return gtp_failure("vertex must be empty"); + if (BOARD(i, j) != EMPTY) + return gtp_failure("vertex must be empty"); - liberties = accuratelib(POS(i, j), color, MAXLIBS, libs); + liberties = accuratelib(POS(i, j), color, MAXLIBS, libs); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertices2(liberties, libs); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + gtp_print_vertices2(liberties, libs); + return gtp_finish_response(); } - /* Function: Determine which liberties a stone of given color * will get if played at given vertex. * Arguments: move (color + vertex) @@ -998,44 +970,42 @@ gtp_accuratelib(char *s) * can be retired when this is confirmed. */ static int -gtp_accurate_approxlib(char *s) +gtp_accurate_approxlib(char* s) { - int i, j; - int color; - int libs[MAXLIBS]; - int liberties; + int i, j; + int color; + int libs[MAXLIBS]; + int liberties; - if (!gtp_decode_move(s, &color, &i, &j)) - return gtp_failure("invalid color or coordinate"); + if (!gtp_decode_move(s, &color, &i, &j)) + return gtp_failure("invalid color or coordinate"); - if (BOARD(i, j) != EMPTY) - return gtp_failure("vertex must be empty"); + if (BOARD(i, j) != EMPTY) + return gtp_failure("vertex must be empty"); - liberties = accuratelib(POS(i, j), color, MAXLIBS, libs); + liberties = accuratelib(POS(i, j), color, MAXLIBS, libs); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertices2(liberties, libs); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + gtp_print_vertices2(liberties, libs); + return gtp_finish_response(); } - /* Function: Tell whether a move is legal. * Arguments: move * Fails: invalid move * Returns: 1 if the move is legal, 0 if it is not. */ static int -gtp_is_legal(char *s) +gtp_is_legal(char* s) { - int i, j; - int color; - - if (!gtp_decode_move(s, &color, &i, &j)) - return gtp_failure("invalid color or coordinate"); + int i, j; + int color; - return gtp_success("%d", is_allowed_move(POS(i, j), color)); -} + if (!gtp_decode_move(s, &color, &i, &j)) + return gtp_failure("invalid color or coordinate"); + return gtp_success("%d", is_allowed_move(POS(i, j), color)); +} /* Function: List all legal moves for either color. * Arguments: color @@ -1043,29 +1013,28 @@ gtp_is_legal(char *s) * Returns: Sorted space separated list of vertices. */ static int -gtp_all_legal(char *s) +gtp_all_legal(char* s) { - int i, j; - int color; - int movei[MAX_BOARD * MAX_BOARD]; - int movej[MAX_BOARD * MAX_BOARD]; - int moves = 0; - - if (!gtp_decode_color(s, &color)) - return gtp_failure("invalid color"); + int i, j; + int color; + int movei[MAX_BOARD * MAX_BOARD]; + int movej[MAX_BOARD * MAX_BOARD]; + int moves = 0; - for (i = 0; i < board_size; i++) - for (j = 0; j < board_size; j++) - if (BOARD(i, j) == EMPTY && is_allowed_move(POS(i, j), color)) { - movei[moves] = i; - movej[moves++] = j; - } + if (!gtp_decode_color(s, &color)) + return gtp_failure("invalid color"); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertices(moves, movei, movej); - return gtp_finish_response(); -} + for (i = 0; i < board_size; i++) + for (j = 0; j < board_size; j++) + if (BOARD(i, j) == EMPTY && is_allowed_move(POS(i, j), color)) { + movei[moves] = i; + movej[moves++] = j; + } + gtp_start_response(GTP_SUCCESS); + gtp_print_vertices(moves, movei, movej); + return gtp_finish_response(); +} /* Function: List the number of captures taken by either color. * Arguments: color @@ -1073,19 +1042,18 @@ gtp_all_legal(char *s) * Returns: Number of captures. */ static int -gtp_captures(char *s) +gtp_captures(char* s) { - int color; - - if (!gtp_decode_color(s, &color)) - return gtp_failure("invalid color"); + int color; - if (color == BLACK) - return gtp_success("%d", white_captured); - else - return gtp_success("%d", black_captured); -} + if (!gtp_decode_color(s, &color)) + return gtp_failure("invalid color"); + if (color == BLACK) + return gtp_success("%d", white_captured); + else + return gtp_success("%d", black_captured); +} /* Function: Return the last move. * Arguments: none @@ -1093,21 +1061,21 @@ gtp_captures(char *s) * Returns: Color and vertex of last move. */ static int -gtp_last_move(char *s) +gtp_last_move(char* s) { - int pos; - int color; - UNUSED(s); - - if (move_history_pointer <= 0) - return gtp_failure("no previous move known"); - - pos = move_history_pos[move_history_pointer - 1]; - color = move_history_color[move_history_pointer - 1]; - - gtp_start_response(GTP_SUCCESS); - gtp_mprintf("%C %m", color, I(pos), J(pos)); - return gtp_finish_response(); + int pos; + int color; + UNUSED(s); + + if (move_history_pointer <= 0) + return gtp_failure("no previous move known"); + + pos = move_history_pos[move_history_pointer - 1]; + color = move_history_color[move_history_pointer - 1]; + + gtp_start_response(GTP_SUCCESS); + gtp_mprintf("%C %m", color, I(pos), J(pos)); + return gtp_finish_response(); } /* Function: Print the move history in reverse order @@ -1117,40 +1085,38 @@ gtp_last_move(char *s) * color move (one move per line) */ static int -gtp_move_history(char *s) +gtp_move_history(char* s) { - int k, pos, color; - UNUSED(s); - - gtp_start_response(GTP_SUCCESS); - if (move_history_pointer > 0) - for (k = move_history_pointer-1; k >= 0; k--) { - color = move_history_color[k]; - pos = move_history_pos[k]; - gtp_mprintf("%C %m\n", color, I(pos), J(pos)); - } - else + int k, pos, color; + UNUSED(s); + + gtp_start_response(GTP_SUCCESS); + if (move_history_pointer > 0) + for (k = move_history_pointer - 1; k >= 0; k--) { + color = move_history_color[k]; + pos = move_history_pos[k]; + gtp_mprintf("%C %m\n", color, I(pos), J(pos)); + } + else + gtp_printf("\n"); gtp_printf("\n"); - gtp_printf("\n"); - return GTP_OK; + return GTP_OK; } - /* Function: Return the rotation/reflection invariant board hash. * Arguments: none * Fails: never * Returns: Invariant hash for the board as a hexadecimal number. */ static int -gtp_invariant_hash(char *s) +gtp_invariant_hash(char* s) { - Hash_data hash; - UNUSED(s); - hashdata_calc_orientation_invariant(&hash, board, board_ko_pos); - return gtp_success("%s", hashdata_to_string(&hash)); + Hash_data hash; + UNUSED(s); + hashdata_calc_orientation_invariant(&hash, board, board_ko_pos); + return gtp_success("%s", hashdata_to_string(&hash)); } - /* Function: Return the rotation/reflection invariant board hash * obtained by playing all the possible moves for the * given color. @@ -1160,37 +1126,35 @@ gtp_invariant_hash(char *s) * one pair of move + hash per line. */ static int -gtp_invariant_hash_for_moves(char *s) +gtp_invariant_hash_for_moves(char* s) { - Hash_data hash; - int color; - int pos; - int move_found = 0; - - if (!gtp_decode_color(s, &color)) - return gtp_failure("invalid color"); + Hash_data hash; + int color; + int pos; + int move_found = 0; + + if (!gtp_decode_color(s, &color)) + return gtp_failure("invalid color"); - gtp_start_response(GTP_SUCCESS); + gtp_start_response(GTP_SUCCESS); - for (pos = BOARDMIN; pos < BOARDMAX; pos++) { - if (board[pos] == EMPTY - && trymove(pos, color, "gtp_invariant_hash_for_moves", NO_MOVE)) { - hashdata_calc_orientation_invariant(&hash, board, board_ko_pos); - gtp_mprintf("%m %s\n", I(pos), J(pos), hashdata_to_string(&hash)); - popgo(); - move_found = 1; + for (pos = BOARDMIN; pos < BOARDMAX; pos++) { + if (board[pos] == EMPTY + && trymove(pos, color, "gtp_invariant_hash_for_moves", NO_MOVE)) { + hashdata_calc_orientation_invariant(&hash, board, board_ko_pos); + gtp_mprintf("%m %s\n", I(pos), J(pos), hashdata_to_string(&hash)); + popgo(); + move_found = 1; + } } - } - if (!move_found) + if (!move_found) + gtp_printf("\n"); + gtp_printf("\n"); - - gtp_printf("\n"); - return GTP_OK; + return GTP_OK; } - - /********************** * Retractable moves. * **********************/ @@ -1201,17 +1165,17 @@ gtp_invariant_hash_for_moves(char *s) * Returns: nothing */ static int -gtp_trymove(char *s) +gtp_trymove(char* s) { - int i, j; - int color; - if (!gtp_decode_move(s, &color, &i, &j)) - return gtp_failure("invalid color or coordinate"); + int i, j; + int color; + if (!gtp_decode_move(s, &color, &i, &j)) + return gtp_failure("invalid color or coordinate"); - if (!trymove(POS(i, j), color, "gtp_trymove", NO_MOVE)) - return gtp_failure("illegal move"); + if (!trymove(POS(i, j), color, "gtp_trymove", NO_MOVE)) + return gtp_failure("illegal move"); - return gtp_success(""); + return gtp_success(""); } /* Function: Play a stone of the given color at the given vertex, @@ -1221,35 +1185,34 @@ gtp_trymove(char *s) * Returns: nothing */ static int -gtp_tryko(char *s) +gtp_tryko(char* s) { - int i, j; - int color; - if (!gtp_decode_move(s, &color, &i, &j) || POS(i, j) == PASS_MOVE) - return gtp_failure("invalid color or coordinate"); + int i, j; + int color; + if (!gtp_decode_move(s, &color, &i, &j) || POS(i, j) == PASS_MOVE) + return gtp_failure("invalid color or coordinate"); - if (!tryko(POS(i, j), color, "gtp_tryko")) - return gtp_failure("illegal move"); + if (!tryko(POS(i, j), color, "gtp_tryko")) + return gtp_failure("illegal move"); - return gtp_success(""); + return gtp_success(""); } - /* Function: Undo a trymove or tryko. * Arguments: none * Fails: stack empty * Returns: nothing */ static int -gtp_popgo(char *s) +gtp_popgo(char* s) { - UNUSED(s); + UNUSED(s); - if (stackp == 0) - return gtp_failure("Stack empty."); + if (stackp == 0) + return gtp_failure("Stack empty."); - popgo(); - return gtp_success(""); + popgo(); + return gtp_success(""); } /********************* @@ -1263,12 +1226,12 @@ gtp_popgo(char *s) */ static int -gtp_clear_cache(char *s) +gtp_clear_cache(char* s) { - UNUSED(s); - clear_persistent_caches(); - reading_cache_clear(); - return gtp_success(""); + UNUSED(s); + clear_persistent_caches(); + reading_cache_clear(); + return gtp_success(""); } /********************* @@ -1281,28 +1244,27 @@ gtp_clear_cache(char *s) * Returns: attack code followed by attack point if attack code nonzero. */ static int -gtp_attack(char *s) +gtp_attack(char* s) { - int i, j; - int apos; - int attack_code; - - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + int i, j; + int apos; + int attack_code; - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - attack_code = attack(POS(i, j), &apos); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(attack_code); - if (attack_code > 0) { - gtp_printf(" "); - gtp_print_vertex(I(apos), J(apos)); - } - return gtp_finish_response(); -} + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); + attack_code = attack(POS(i, j), &apos); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(attack_code); + if (attack_code > 0) { + gtp_printf(" "); + gtp_print_vertex(I(apos), J(apos)); + } + return gtp_finish_response(); +} /* Function: Try to attack either of two strings * Arguments: two vertices @@ -1312,63 +1274,61 @@ gtp_attack(char *s) * with attack_code, but does not return the move. */ static int -gtp_attack_either(char *s) +gtp_attack_either(char* s) { - int ai, aj; - int bi, bj; - int n; - int acode; + int ai, aj; + int bi, bj; + int n; + int acode; - n = gtp_decode_coord(s, &ai, &aj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ai, &aj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(ai, aj) == EMPTY) - return gtp_failure("string vertex must be empty"); + if (BOARD(ai, aj) == EMPTY) + return gtp_failure("string vertex must be empty"); - n = gtp_decode_coord(s + n, &bi, &bj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s + n, &bi, &bj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(bi, bj) == EMPTY) - return gtp_failure("string vertex must not be empty"); + if (BOARD(bi, bj) == EMPTY) + return gtp_failure("string vertex must not be empty"); - acode = attack_either(POS(ai, aj), POS(bi, bj)); + acode = attack_either(POS(ai, aj), POS(bi, bj)); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(acode); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(acode); + return gtp_finish_response(); } - /* Function: Try to defend a string. * Arguments: vertex * Fails: invalid vertex, empty vertex * Returns: defense code followed by defense point if defense code nonzero. */ static int -gtp_defend(char *s) +gtp_defend(char* s) { - int i, j; - int dpos; - int defend_code; - - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + int i, j; + int dpos; + int defend_code; - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - defend_code = find_defense(POS(i, j), &dpos); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(defend_code); - if (defend_code > 0) { - gtp_printf(" "); - gtp_print_vertex(I(dpos), J(dpos)); - } - return gtp_finish_response(); -} + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); + defend_code = find_defense(POS(i, j), &dpos); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(defend_code); + if (defend_code > 0) { + gtp_printf(" "); + gtp_print_vertex(I(dpos), J(dpos)); + } + return gtp_finish_response(); +} /* Function: Examine whether a specific move attacks a string tactically. * Arguments: vertex (move), vertex (dragon) @@ -1376,37 +1336,36 @@ gtp_defend(char *s) * Returns: attack code */ static int -gtp_does_attack(char *s) +gtp_does_attack(char* s) { - int i, j; - int ti, tj; - int attack_code; - int n; + int i, j; + int ti, tj; + int attack_code; + int n; - n = gtp_decode_coord(s, &ti, &tj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ti, &tj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(ti, tj) != EMPTY) - return gtp_failure("move vertex must be empty"); + if (BOARD(ti, tj) != EMPTY) + return gtp_failure("move vertex must be empty"); - n = gtp_decode_coord(s + n, &i, &j); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s + n, &i, &j); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(i, j) == EMPTY) - return gtp_failure("string vertex must not be empty"); + if (BOARD(i, j) == EMPTY) + return gtp_failure("string vertex must not be empty"); - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); - - attack_code = does_attack(POS(ti, tj), POS(i, j)); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(attack_code); - return gtp_finish_response(); -} + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + attack_code = does_attack(POS(ti, tj), POS(i, j)); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(attack_code); + return gtp_finish_response(); +} /* Function: Examine whether a specific move defends a string tactically. * Arguments: vertex (move), vertex (dragon) @@ -1414,37 +1373,36 @@ gtp_does_attack(char *s) * Returns: attack code */ static int -gtp_does_defend(char *s) +gtp_does_defend(char* s) { - int i, j; - int ti, tj; - int defense_code; - int n; + int i, j; + int ti, tj; + int defense_code; + int n; - n = gtp_decode_coord(s, &ti, &tj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ti, &tj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(ti, tj) != EMPTY) - return gtp_failure("move vertex must be empty"); + if (BOARD(ti, tj) != EMPTY) + return gtp_failure("move vertex must be empty"); - n = gtp_decode_coord(s + n, &i, &j); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s + n, &i, &j); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(i, j) == EMPTY) - return gtp_failure("string vertex must not be empty"); + if (BOARD(i, j) == EMPTY) + return gtp_failure("string vertex must not be empty"); - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); - - defense_code = does_defend(POS(ti, tj), POS(i, j)); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(defense_code); - return gtp_finish_response(); -} + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + defense_code = does_defend(POS(ti, tj), POS(i, j)); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(defense_code); + return gtp_finish_response(); +} /* Function: Try to attack a string strictly in a ladder. * Arguments: vertex @@ -1452,31 +1410,30 @@ gtp_does_defend(char *s) * Returns: attack code followed by attack point if attack code nonzero. */ static int -gtp_ladder_attack(char *s) +gtp_ladder_attack(char* s) { - int i, j; - int apos; - int attack_code; - - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + int i, j; + int apos; + int attack_code; - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - if (countlib(POS(i, j)) != 2) - return gtp_failure("string must have exactly 2 liberties"); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - attack_code = simple_ladder(POS(i, j), &apos); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(attack_code); - if (attack_code > 0) { - gtp_printf(" "); - gtp_print_vertex(I(apos), J(apos)); - } - return gtp_finish_response(); -} + if (countlib(POS(i, j)) != 2) + return gtp_failure("string must have exactly 2 liberties"); + attack_code = simple_ladder(POS(i, j), &apos); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(attack_code); + if (attack_code > 0) { + gtp_printf(" "); + gtp_print_vertex(I(apos), J(apos)); + } + return gtp_finish_response(); +} /* Function: Increase depth values by one. * Arguments: none @@ -1484,13 +1441,12 @@ gtp_ladder_attack(char *s) * Returns: nothing */ static int -gtp_increase_depths(char *s) +gtp_increase_depths(char* s) { - UNUSED(s); - increase_depth_values(); - return gtp_success(""); -} - + UNUSED(s); + increase_depth_values(); + return gtp_success(""); +} /* Function: Decrease depth values by one. * Arguments: none @@ -1498,13 +1454,12 @@ gtp_increase_depths(char *s) * Returns: nothing */ static int -gtp_decrease_depths(char *s) +gtp_decrease_depths(char* s) { - UNUSED(s); - decrease_depth_values(); - return gtp_success(""); -} - + UNUSED(s); + decrease_depth_values(); + return gtp_success(""); +} /****************** * owl reading. * @@ -1516,38 +1471,37 @@ gtp_decrease_depths(char *s) * Returns: attack code followed by attack point if attack code nonzero. */ static int -gtp_owl_attack(char *s) +gtp_owl_attack(char* s) { - int i, j; - int attack_point; - int attack_code; - int result_certain; - int kworm; + int i, j; + int attack_point; + int attack_code; + int result_certain; + int kworm; - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); - - attack_code = owl_attack(POS(i, j), &attack_point, &result_certain, &kworm); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(attack_code); - if (attack_code > 0) { - gtp_printf(" "); - gtp_print_vertex(I(attack_point), J(attack_point)); - } - if (!result_certain && report_uncertainty) - gtp_printf(" uncertain"); - return gtp_finish_response(); -} + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + + attack_code = owl_attack(POS(i, j), &attack_point, &result_certain, &kworm); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(attack_code); + if (attack_code > 0) { + gtp_printf(" "); + gtp_print_vertex(I(attack_point), J(attack_point)); + } + if (!result_certain && report_uncertainty) + gtp_printf(" uncertain"); + return gtp_finish_response(); +} /* Function: Try to defend a dragon. * Arguments: vertex @@ -1555,37 +1509,37 @@ gtp_owl_attack(char *s) * Returns: defense code followed by defense point if defense code nonzero. */ static int -gtp_owl_defend(char *s) +gtp_owl_defend(char* s) { - int i, j; - int defense_point; - int defend_code; - int result_certain; - int kworm; - - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + int i, j; + int defense_point; + int defend_code; + int result_certain; + int kworm; - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - defend_code = owl_defend(POS(i, j), &defense_point, &result_certain, &kworm); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(defend_code); - if (defend_code > 0) { - gtp_printf(" "); - gtp_print_vertex(I(defense_point), J(defense_point)); - } - if (!result_certain && report_uncertainty) - gtp_printf(" uncertain"); - return gtp_finish_response(); -} + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + + defend_code = owl_defend(POS(i, j), &defense_point, &result_certain, &kworm); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(defend_code); + if (defend_code > 0) { + gtp_printf(" "); + gtp_print_vertex(I(defense_point), J(defense_point)); + } + if (!result_certain && report_uncertainty) + gtp_printf(" uncertain"); + return gtp_finish_response(); +} /* Function: Try to attack a dragon in 2 moves. * Arguments: vertex @@ -1594,37 +1548,36 @@ gtp_owl_defend(char *s) * attack code nonzero. */ static int -gtp_owl_threaten_attack(char *s) +gtp_owl_threaten_attack(char* s) { - int i, j; - int attack_point1; - int attack_point2; - int attack_code; + int i, j; + int attack_point1; + int attack_point2; + int attack_code; - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); - - attack_code = owl_threaten_attack(POS(i, j), &attack_point1, &attack_point2); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(attack_code); - if (attack_code > 0) { - gtp_printf(" "); - gtp_print_vertex(I(attack_point1), J(attack_point1)); - gtp_printf(" "); - gtp_print_vertex(I(attack_point2), J(attack_point2)); - } - return gtp_finish_response(); -} + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + + attack_code = owl_threaten_attack(POS(i, j), &attack_point1, &attack_point2); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(attack_code); + if (attack_code > 0) { + gtp_printf(" "); + gtp_print_vertex(I(attack_point1), J(attack_point1)); + gtp_printf(" "); + gtp_print_vertex(I(attack_point2), J(attack_point2)); + } + return gtp_finish_response(); +} /* Function: Try to defend a dragon with 2 moves. * Arguments: vertex @@ -1633,38 +1586,37 @@ gtp_owl_threaten_attack(char *s) * defense code nonzero. */ static int -gtp_owl_threaten_defense(char *s) +gtp_owl_threaten_defense(char* s) { - int i, j; - int defense_point1; - int defense_point2; - int defend_code; - - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + int i, j; + int defense_point1; + int defense_point2; + int defend_code; - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - defend_code = owl_threaten_defense(POS(i, j), &defense_point1, - &defense_point2); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(defend_code); - if (defend_code > 0) { - gtp_printf(" "); - gtp_print_vertex(I(defense_point1), J(defense_point1)); - gtp_printf(" "); - gtp_print_vertex(I(defense_point2), J(defense_point2)); - } - return gtp_finish_response(); -} + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + + defend_code = owl_threaten_defense(POS(i, j), &defense_point1, + &defense_point2); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(defend_code); + if (defend_code > 0) { + gtp_printf(" "); + gtp_print_vertex(I(defense_point1), J(defense_point1)); + gtp_printf(" "); + gtp_print_vertex(I(defense_point2), J(defense_point2)); + } + return gtp_finish_response(); +} /* Function: Examine whether a specific move attacks a dragon. * Arguments: vertex (move), vertex (dragon) @@ -1672,40 +1624,39 @@ gtp_owl_threaten_defense(char *s) * Returns: attack code */ static int -gtp_owl_does_attack(char *s) +gtp_owl_does_attack(char* s) { - int i, j; - int ti, tj; - int attack_code; - int kworm; - int n; + int i, j; + int ti, tj; + int attack_code; + int kworm; + int n; - n = gtp_decode_coord(s, &ti, &tj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ti, &tj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(ti, tj) != EMPTY) - return gtp_failure("move vertex must be empty"); + if (BOARD(ti, tj) != EMPTY) + return gtp_failure("move vertex must be empty"); - n = gtp_decode_coord(s + n, &i, &j); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s + n, &i, &j); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(i, j) == EMPTY) - return gtp_failure("dragon vertex must not be empty"); + if (BOARD(i, j) == EMPTY) + return gtp_failure("dragon vertex must not be empty"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); - - attack_code = owl_does_attack(POS(ti, tj), POS(i, j), &kworm); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(attack_code); - return gtp_finish_response(); -} + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + + attack_code = owl_does_attack(POS(ti, tj), POS(i, j), &kworm); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(attack_code); + return gtp_finish_response(); +} /* Function: Examine whether a specific move defends a dragon. * Arguments: vertex (move), vertex (dragon) @@ -1713,40 +1664,39 @@ gtp_owl_does_attack(char *s) * Returns: defense code */ static int -gtp_owl_does_defend(char *s) +gtp_owl_does_defend(char* s) { - int i, j; - int ti, tj; - int defense_code; - int kworm; - int n; + int i, j; + int ti, tj; + int defense_code; + int kworm; + int n; - n = gtp_decode_coord(s, &ti, &tj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ti, &tj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(ti, tj) != EMPTY) - return gtp_failure("move vertex must be empty"); + if (BOARD(ti, tj) != EMPTY) + return gtp_failure("move vertex must be empty"); - n = gtp_decode_coord(s + n, &i, &j); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s + n, &i, &j); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(i, j) == EMPTY) - return gtp_failure("dragon vertex must not be empty"); + if (BOARD(i, j) == EMPTY) + return gtp_failure("dragon vertex must not be empty"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); - - defense_code = owl_does_defend(POS(ti, tj), POS(i, j), &kworm); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(defense_code); - return gtp_finish_response(); -} + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + + defense_code = owl_does_defend(POS(ti, tj), POS(i, j), &kworm); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(defense_code); + return gtp_finish_response(); +} /* Function: Examine whether a connection defends involved dragons. * Arguments: vertex (move), vertex (dragon1), vertex (dragon2) @@ -1754,49 +1704,48 @@ gtp_owl_does_defend(char *s) * Returns: defense code */ static int -gtp_owl_connection_defends(char *s) +gtp_owl_connection_defends(char* s) { - int ai, aj; - int bi, bj; - int ti, tj; - int defense_code; - int n; + int ai, aj; + int bi, bj; + int ti, tj; + int defense_code; + int n; - n = gtp_decode_coord(s, &ti, &tj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ti, &tj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(ti, tj) != EMPTY) - return gtp_failure("move vertex must be empty"); + if (BOARD(ti, tj) != EMPTY) + return gtp_failure("move vertex must be empty"); - s += n; - n = gtp_decode_coord(s, &ai, &aj); - if (n == 0) - return gtp_failure("invalid coordinate"); + s += n; + n = gtp_decode_coord(s, &ai, &aj); + if (n == 0) + return gtp_failure("invalid coordinate"); - s += n; - n = gtp_decode_coord(s, &bi, &bj); - if (n == 0) - return gtp_failure("invalid coordinate"); + s += n; + n = gtp_decode_coord(s, &bi, &bj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY) - return gtp_failure("dragon vertex must not be empty"); + if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY) + return gtp_failure("dragon vertex must not be empty"); - if (BOARD(ai, aj) != BOARD(bi, bj)) - return gtp_failure("dragon vertices must have the same color"); + if (BOARD(ai, aj) != BOARD(bi, bj)) + return gtp_failure("dragon vertices must have the same color"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); - - defense_code = owl_connection_defends(POS(ti, tj), POS(ai, aj), POS(bi, bj)); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(defense_code); - return gtp_finish_response(); -} + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + + defense_code = owl_connection_defends(POS(ti, tj), POS(ai, aj), POS(bi, bj)); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(defense_code); + return gtp_finish_response(); +} /* Function: Try to defend both of two strings * Arguments: two vertices @@ -1806,63 +1755,60 @@ gtp_owl_connection_defends(char *s) * with defend_code, but does not return the move. */ static int -gtp_defend_both(char *s) +gtp_defend_both(char* s) { - int ai, aj; - int bi, bj; - int n; - int dcode; + int ai, aj; + int bi, bj; + int n; + int dcode; - n = gtp_decode_coord(s, &ai, &aj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ai, &aj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(ai, aj) == EMPTY) - return gtp_failure("string vertex must be empty"); + if (BOARD(ai, aj) == EMPTY) + return gtp_failure("string vertex must be empty"); - n = gtp_decode_coord(s + n, &bi, &bj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s + n, &bi, &bj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(bi, bj) == EMPTY) - return gtp_failure("string vertex must not be empty"); + if (BOARD(bi, bj) == EMPTY) + return gtp_failure("string vertex must not be empty"); - dcode = defend_both(POS(ai, aj), POS(bi, bj)); + dcode = defend_both(POS(ai, aj), POS(bi, bj)); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(dcode); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(dcode); + return gtp_finish_response(); } - - /* Function: Determine whether capturing a string gives a living dragon * Arguments: vertex * Fails: invalid vertex, empty vertex * Returns: 1 if dragon can live, 0 otherwise */ static int -gtp_owl_substantial(char *s) +gtp_owl_substantial(char* s) { - int i, j; - int result; - - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + int i, j; + int result; - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); + + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - result = owl_substantial(POS(i, j)); - return gtp_success("%d", result); -} + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + result = owl_substantial(POS(i, j)); + return gtp_success("%d", result); +} /* Function: Analyze a semeai * Arguments: dragona, dragonb @@ -1870,45 +1816,44 @@ gtp_owl_substantial(char *s) * Returns: semeai defense result, semeai attack result, semeai move */ static int -gtp_analyze_semeai(char *s) +gtp_analyze_semeai(char* s) { - int i, j; - int k; - int dragona, dragonb; - int resulta, resultb, move, result_certain; - - k = gtp_decode_coord(s, &i, &j); + int i, j; + int k; + int dragona, dragonb; + int resulta, resultb, move, result_certain; - if (k == 0) - return gtp_failure("invalid coordinate"); - dragona = POS(i, j); - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + k = gtp_decode_coord(s, &i, &j); - if (!gtp_decode_coord(s+k, &i, &j)) - return gtp_failure("invalid coordinate"); - dragonb = POS(i, j); - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (k == 0) + return gtp_failure("invalid coordinate"); + dragona = POS(i, j); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); + if (!gtp_decode_coord(s + k, &i, &j)) + return gtp_failure("invalid coordinate"); + dragonb = POS(i, j); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - owl_analyze_semeai(dragona, dragonb, &resulta, &resultb, &move, 1, - &result_certain); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(resulta); - gtp_printf(" "); - gtp_print_code(resultb); - gtp_mprintf(" %m", I(move), J(move)); - if (!result_certain && report_uncertainty) - gtp_printf(" uncertain"); + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); - return gtp_finish_response(); -} + owl_analyze_semeai(dragona, dragonb, &resulta, &resultb, &move, 1, + &result_certain); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(resulta); + gtp_printf(" "); + gtp_print_code(resultb); + gtp_mprintf(" %m", I(move), J(move)); + if (!result_certain && report_uncertainty) + gtp_printf(" uncertain"); + return gtp_finish_response(); +} /* Function: Analyze a semeai after a move have been made. * Arguments: color, vertex, dragona, dragonb @@ -1916,56 +1861,55 @@ gtp_analyze_semeai(char *s) * Returns: semeai defense result, semeai attack result, semeai move */ static int -gtp_analyze_semeai_after_move(char *s) -{ - int i, j; - int color; - int move; - int k; - int dragona, dragonb; - int resulta, resultb, semeai_move, result_certain; - - k = gtp_decode_move(s, &color, &i, &j); - move = POS(i, j); - if (k == 0 || move == NO_MOVE) - return gtp_failure("invalid color or coordinate"); - if (board[move] != EMPTY) - return gtp_failure("move vertex is not empty"); - s += k; - - k = gtp_decode_coord(s, &i, &j); - if (k == 0) - return gtp_failure("invalid coordinate"); - dragona = POS(i, j); - if (board[dragona] == EMPTY) - return gtp_failure("dragon vertex must not be empty"); - s += k; - - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); - dragonb = POS(i, j); - if (board[dragonb] == EMPTY) - return gtp_failure("dragon vertex must not be empty"); - - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); - - owl_analyze_semeai_after_move(move, color, dragona, dragonb, - &resulta, &resultb, &semeai_move, 1, - &result_certain, 0); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(resulta); - gtp_printf(" "); - gtp_print_code(resultb); - gtp_mprintf(" %m", I(semeai_move), J(semeai_move)); - if (!result_certain && report_uncertainty) - gtp_printf(" uncertain"); - - return gtp_finish_response(); -} +gtp_analyze_semeai_after_move(char* s) +{ + int i, j; + int color; + int move; + int k; + int dragona, dragonb; + int resulta, resultb, semeai_move, result_certain; + + k = gtp_decode_move(s, &color, &i, &j); + move = POS(i, j); + if (k == 0 || move == NO_MOVE) + return gtp_failure("invalid color or coordinate"); + if (board[move] != EMPTY) + return gtp_failure("move vertex is not empty"); + s += k; + + k = gtp_decode_coord(s, &i, &j); + if (k == 0) + return gtp_failure("invalid coordinate"); + dragona = POS(i, j); + if (board[dragona] == EMPTY) + return gtp_failure("dragon vertex must not be empty"); + s += k; + + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); + dragonb = POS(i, j); + if (board[dragonb] == EMPTY) + return gtp_failure("dragon vertex must not be empty"); + + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); + + owl_analyze_semeai_after_move(move, color, dragona, dragonb, + &resulta, &resultb, &semeai_move, 1, + &result_certain, 0); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(resulta); + gtp_printf(" "); + gtp_print_code(resultb); + gtp_mprintf(" %m", I(semeai_move), J(semeai_move)); + if (!result_certain && report_uncertainty) + gtp_printf(" uncertain"); + return gtp_finish_response(); +} /* Function: Analyze a semeai, not using owl * Arguments: dragona, dragonb @@ -1973,45 +1917,44 @@ gtp_analyze_semeai_after_move(char *s) * Returns: status of dragona, dragonb assuming dragona moves first */ static int -gtp_tactical_analyze_semeai(char *s) +gtp_tactical_analyze_semeai(char* s) { - int i, j; - int k; - int dragona, dragonb; - int resulta, resultb, move, result_certain; - - k = gtp_decode_coord(s, &i, &j); + int i, j; + int k; + int dragona, dragonb; + int resulta, resultb, move, result_certain; - if (k == 0) - return gtp_failure("invalid coordinate"); - dragona = POS(i, j); - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + k = gtp_decode_coord(s, &i, &j); - if (!gtp_decode_coord(s+k, &i, &j)) - return gtp_failure("invalid coordinate"); - dragonb = POS(i, j); - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (k == 0) + return gtp_failure("invalid coordinate"); + dragona = POS(i, j); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - /* to get the variations into the sgf file, clear the reading cache */ - if (sgf_dumptree) - reading_cache_clear(); + if (!gtp_decode_coord(s + k, &i, &j)) + return gtp_failure("invalid coordinate"); + dragonb = POS(i, j); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - owl_analyze_semeai(dragona, dragonb, &resulta, &resultb, &move, 0, - &result_certain); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(resulta); - gtp_printf(" "); - gtp_print_code(resultb); - gtp_mprintf(" %m", I(move), J(move)); - if (!result_certain && report_uncertainty) - gtp_printf(" uncertain"); + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + /* to get the variations into the sgf file, clear the reading cache */ + if (sgf_dumptree) + reading_cache_clear(); - return gtp_finish_response(); -} + owl_analyze_semeai(dragona, dragonb, &resulta, &resultb, &move, 0, + &result_certain); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(resulta); + gtp_printf(" "); + gtp_print_code(resultb); + gtp_mprintf(" %m", I(move), J(move)); + if (!result_certain && report_uncertainty) + gtp_printf(" uncertain"); + return gtp_finish_response(); +} /*********************** * Connection reading. * @@ -2023,36 +1966,35 @@ gtp_tactical_analyze_semeai(char *s) * Returns: connect result followed by connect point if successful. */ static int -gtp_connect(char *s) +gtp_connect(char* s) { - int ai, aj; - int bi, bj; - int connect_move = PASS_MOVE; - int result; - int n; - - n = gtp_decode_coord(s, &ai, &aj); - if (n == 0) - return gtp_failure("invalid coordinate"); + int ai, aj; + int bi, bj; + int connect_move = PASS_MOVE; + int result; + int n; - if (!gtp_decode_coord(s + n, &bi, &bj)) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ai, &aj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (!gtp_decode_coord(s + n, &bi, &bj)) + return gtp_failure("invalid coordinate"); - if (BOARD(ai, aj) != BOARD(bi, bj)) - return gtp_failure("vertices must have same color"); + if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY) + return gtp_failure("vertex must not be empty"); - result = string_connect(POS(ai, aj), POS(bi, bj), &connect_move); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(result); - if (result != 0) - gtp_mprintf(" %m", I(connect_move), J(connect_move)); + if (BOARD(ai, aj) != BOARD(bi, bj)) + return gtp_failure("vertices must have same color"); - return gtp_finish_response(); -} + result = string_connect(POS(ai, aj), POS(bi, bj), &connect_move); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(result); + if (result != 0) + gtp_mprintf(" %m", I(connect_move), J(connect_move)); + return gtp_finish_response(); +} /* Function: Try to disconnect two strings. * Arguments: vertex, vertex @@ -2060,36 +2002,35 @@ gtp_connect(char *s) * Returns: disconnect result followed by disconnect point if successful. */ static int -gtp_disconnect(char *s) +gtp_disconnect(char* s) { - int ai, aj; - int bi, bj; - int disconnect_move = PASS_MOVE; - int result; - int n; - - n = gtp_decode_coord(s, &ai, &aj); - if (n == 0) - return gtp_failure("invalid coordinate"); + int ai, aj; + int bi, bj; + int disconnect_move = PASS_MOVE; + int result; + int n; - if (!gtp_decode_coord(s + n, &bi, &bj)) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ai, &aj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (!gtp_decode_coord(s + n, &bi, &bj)) + return gtp_failure("invalid coordinate"); - if (BOARD(ai, aj) != BOARD(bi, bj)) - return gtp_failure("vertices must have same color"); + if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY) + return gtp_failure("vertex must not be empty"); - result = disconnect(POS(ai, aj), POS(bi, bj), &disconnect_move); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(result); - if (result != 0) - gtp_mprintf(" %m", I(disconnect_move), J(disconnect_move)); + if (BOARD(ai, aj) != BOARD(bi, bj)) + return gtp_failure("vertices must have same color"); - return gtp_finish_response(); -} + result = disconnect(POS(ai, aj), POS(bi, bj), &disconnect_move); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(result); + if (result != 0) + gtp_mprintf(" %m", I(disconnect_move), J(disconnect_move)); + return gtp_finish_response(); +} /* Function: Try to break from string into area. * Arguments: vertex, vertices @@ -2097,45 +2038,44 @@ gtp_disconnect(char *s) * Returns: result followed by break in point if successful. */ static int -gtp_break_in(char *s) +gtp_break_in(char* s) { - int ai, aj; - int i, j; - signed char goal[BOARDMAX]; - int break_move = PASS_MOVE; - int result; - int n; - int k; - - n = gtp_decode_coord(s, &ai, &aj); - if (n == 0) - return gtp_failure("invalid coordinate"); + int ai, aj; + int i, j; + signed char goal[BOARDMAX]; + int break_move = PASS_MOVE; + int result; + int n; + int k; - memset(goal, 0, BOARDMAX); - s += n; + n = gtp_decode_coord(s, &ai, &aj); + if (n == 0) + return gtp_failure("invalid coordinate"); - for (k = 0; k < MAX_BOARD * MAX_BOARD; k++) { - n = gtp_decode_coord(s, &i, &j); - if (n > 0) { - goal[POS(i, j)] = 1; - s += n; + memset(goal, 0, BOARDMAX); + s += n; + + for (k = 0; k < MAX_BOARD * MAX_BOARD; k++) { + n = gtp_decode_coord(s, &i, &j); + if (n > 0) { + goal[POS(i, j)] = 1; + s += n; + } else if (sscanf(s, "%*s") != EOF) + return gtp_failure("invalid coordinate"); + else + break; } - else if (sscanf(s, "%*s") != EOF) - return gtp_failure("invalid coordinate"); - else - break; - } - if (BOARD(ai, aj) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (BOARD(ai, aj) == EMPTY) + return gtp_failure("vertex must not be empty"); - result = break_in(POS(ai, aj), goal, &break_move); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(result); - if (result != 0) - gtp_mprintf(" %m", I(break_move), J(break_move)); + result = break_in(POS(ai, aj), goal, &break_move); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(result); + if (result != 0) + gtp_mprintf(" %m", I(break_move), J(break_move)); - return gtp_finish_response(); + return gtp_finish_response(); } /* Function: Try to block string from area. @@ -2144,49 +2084,46 @@ gtp_break_in(char *s) * Returns: result followed by block point if successful. */ static int -gtp_block_off(char *s) +gtp_block_off(char* s) { - int ai, aj; - int i, j; - signed char goal[BOARDMAX]; - int block_move = PASS_MOVE; - int result; - int n; - int k; - - n = gtp_decode_coord(s, &ai, &aj); - if (n == 0) - return gtp_failure("invalid coordinate"); + int ai, aj; + int i, j; + signed char goal[BOARDMAX]; + int block_move = PASS_MOVE; + int result; + int n; + int k; - memset(goal, 0, BOARDMAX); - s += n; + n = gtp_decode_coord(s, &ai, &aj); + if (n == 0) + return gtp_failure("invalid coordinate"); - for (k = 0; k < MAX_BOARD * MAX_BOARD; k++) { - n = gtp_decode_coord(s, &i, &j); - if (n > 0) { - goal[POS(i, j)] = 1; - s += n; + memset(goal, 0, BOARDMAX); + s += n; + + for (k = 0; k < MAX_BOARD * MAX_BOARD; k++) { + n = gtp_decode_coord(s, &i, &j); + if (n > 0) { + goal[POS(i, j)] = 1; + s += n; + } else if (sscanf(s, "%*s") != EOF) + return gtp_failure("invalid coordinate"); + else + break; } - else if (sscanf(s, "%*s") != EOF) - return gtp_failure("invalid coordinate"); - else - break; - } - if (BOARD(ai, aj) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (BOARD(ai, aj) == EMPTY) + return gtp_failure("vertex must not be empty"); - result = block_off(POS(ai, aj), goal, &block_move); - gtp_start_response(GTP_SUCCESS); - gtp_print_code(result); - if (result != 0) - gtp_mprintf(" %m", I(block_move), J(block_move)); + result = block_off(POS(ai, aj), goal, &block_move); + gtp_start_response(GTP_SUCCESS); + gtp_print_code(result); + if (result != 0) + gtp_mprintf(" %m", I(block_move), J(block_move)); - return gtp_finish_response(); + return gtp_finish_response(); } - - /******** * eyes * ********/ @@ -2201,44 +2138,41 @@ gtp_block_off(char *s) */ static int -gtp_eval_eye(char *s) -{ - int m, n; - struct eyevalue value; - int attack_point; - int defense_point; - int pos; - - if (!gtp_decode_coord(s, &m, &n)) - return gtp_failure("invalid coordinate"); - - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - - if (black_eye[POS(m, n)].color == BLACK) { - pos = black_eye[POS(m, n)].origin; - compute_eyes(pos, &value, &attack_point, &defense_point, - black_eye, half_eye, 0); - } - else if (white_eye[POS(m, n)].color == WHITE) { - pos = white_eye[POS(m, n)].origin; - compute_eyes(pos, &value, &attack_point, &defense_point, - white_eye, half_eye, 0); - } - else - /* Not an eye or not of unique color. */ - return gtp_success("-1"); - - gtp_start_response(GTP_SUCCESS); - gtp_printf("%d %d", min_eyes(&value), max_eyes(&value)); - if (eye_move_urgency(&value) > 0) { - gtp_printf(" "); - gtp_print_vertex(I(attack_point), J(attack_point)); - gtp_printf(" "); - gtp_print_vertex(I(defense_point), J(defense_point)); - } - return gtp_finish_response(); -} +gtp_eval_eye(char* s) +{ + int m, n; + struct eyevalue value; + int attack_point; + int defense_point; + int pos; + if (!gtp_decode_coord(s, &m, &n)) + return gtp_failure("invalid coordinate"); + + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + + if (black_eye[POS(m, n)].color == BLACK) { + pos = black_eye[POS(m, n)].origin; + compute_eyes(pos, &value, &attack_point, &defense_point, + black_eye, half_eye, 0); + } else if (white_eye[POS(m, n)].color == WHITE) { + pos = white_eye[POS(m, n)].origin; + compute_eyes(pos, &value, &attack_point, &defense_point, + white_eye, half_eye, 0); + } else + /* Not an eye or not of unique color. */ + return gtp_success("-1"); + + gtp_start_response(GTP_SUCCESS); + gtp_printf("%d %d", min_eyes(&value), max_eyes(&value)); + if (eye_move_urgency(&value) > 0) { + gtp_printf(" "); + gtp_print_vertex(I(attack_point), J(attack_point)); + gtp_printf(" "); + gtp_print_vertex(I(defense_point), J(defense_point)); + } + return gtp_finish_response(); +} /***************** * dragon status * @@ -2258,62 +2192,60 @@ gtp_eval_eye(char *s) */ static int -gtp_dragon_status(char *s) -{ - int i, j; - int str = NO_MOVE; - int pos; - int empty_response = 1; - - if (gtp_decode_coord(s, &i, &j)) { - str = POS(i, j); - if (board[str] == EMPTY) - return gtp_failure("vertex must not be empty"); - } - else if (sscanf(s, "%*s") != EOF) - return gtp_failure("invalid coordinate"); - - silent_examine_position(EXAMINE_DRAGONS); - - gtp_start_response(GTP_SUCCESS); - - for (pos = BOARDMIN; pos < BOARDMAX; pos++) { - if (ON_BOARD(pos) - && (pos == str - || (str == NO_MOVE - && board[pos] != EMPTY - && dragon[pos].origin == pos))) { - if (str == NO_MOVE) - gtp_mprintf("%m: ", I(pos), J(pos)); - - if (dragon[pos].status == ALIVE) - gtp_printf("alive\n"); - else if (dragon[pos].status == DEAD) - gtp_printf("dead\n"); - else if (dragon[pos].status == UNKNOWN) - gtp_printf("unknown\n"); - else { - /* Only remaining possibility. */ - assert(dragon[pos].status == CRITICAL); - /* Status critical, need to return attack and defense point as well. */ - gtp_mprintf("critical %m %m\n", - I(DRAGON2(pos).owl_attack_point), - J(DRAGON2(pos).owl_attack_point), - I(DRAGON2(pos).owl_defense_point), - J(DRAGON2(pos).owl_defense_point)); - } - empty_response = 0; +gtp_dragon_status(char* s) +{ + int i, j; + int str = NO_MOVE; + int pos; + int empty_response = 1; + + if (gtp_decode_coord(s, &i, &j)) { + str = POS(i, j); + if (board[str] == EMPTY) + return gtp_failure("vertex must not be empty"); + } else if (sscanf(s, "%*s") != EOF) + return gtp_failure("invalid coordinate"); + + silent_examine_position(EXAMINE_DRAGONS); + + gtp_start_response(GTP_SUCCESS); + + for (pos = BOARDMIN; pos < BOARDMAX; pos++) { + if (ON_BOARD(pos) + && (pos == str + || (str == NO_MOVE + && board[pos] != EMPTY + && dragon[pos].origin == pos))) { + if (str == NO_MOVE) + gtp_mprintf("%m: ", I(pos), J(pos)); + + if (dragon[pos].status == ALIVE) + gtp_printf("alive\n"); + else if (dragon[pos].status == DEAD) + gtp_printf("dead\n"); + else if (dragon[pos].status == UNKNOWN) + gtp_printf("unknown\n"); + else { + /* Only remaining possibility. */ + assert(dragon[pos].status == CRITICAL); + /* Status critical, need to return attack and defense point as well. */ + gtp_mprintf("critical %m %m\n", + I(DRAGON2(pos).owl_attack_point), + J(DRAGON2(pos).owl_attack_point), + I(DRAGON2(pos).owl_defense_point), + J(DRAGON2(pos).owl_defense_point)); + } + empty_response = 0; + } } - } - if (empty_response) - gtp_printf("\n"); + if (empty_response) + gtp_printf("\n"); - gtp_printf("\n"); - return GTP_OK; + gtp_printf("\n"); + return GTP_OK; } - /* Function: Determine whether two stones belong to the same dragon. * Arguments: vertex, vertex * Fails: invalid vertex, empty vertex @@ -2321,27 +2253,26 @@ gtp_dragon_status(char *s) */ static int -gtp_same_dragon(char *s) +gtp_same_dragon(char* s) { - int ai, aj; - int bi, bj; - int n; + int ai, aj; + int bi, bj; + int n; - n = gtp_decode_coord(s, &ai, &aj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ai, &aj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (!gtp_decode_coord(s + n, &bi, &bj)) - return gtp_failure("invalid coordinate"); + if (!gtp_decode_coord(s + n, &bi, &bj)) + return gtp_failure("invalid coordinate"); - if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY) + return gtp_failure("vertex must not be empty"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - - return gtp_success("%d", dragon[POS(ai, aj)].id == dragon[POS(bi, bj)].id); -} + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + return gtp_success("%d", dragon[POS(ai, aj)].id == dragon[POS(bi, bj)].id); +} /************************ * Unconditional status * @@ -2357,22 +2288,21 @@ gtp_same_dragon(char *s) */ static int -gtp_unconditional_status(char *s) +gtp_unconditional_status(char* s) { - int i, j; - enum dragon_status status; + int i, j; + enum dragon_status status; - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - silent_examine_position(EXAMINE_WORMS); - - status = worm[POS(i, j)].unconditional_status; - if (status == UNKNOWN) - return gtp_success("undecided"); - return gtp_success("%s", status_to_string(status)); -} + silent_examine_position(EXAMINE_WORMS); + status = worm[POS(i, j)].unconditional_status; + if (status == UNKNOWN) + return gtp_success("undecided"); + return gtp_success("%s", status_to_string(status)); +} /*********************** * combination attacks * @@ -2386,24 +2316,24 @@ gtp_unconditional_status(char *s) */ static int -gtp_combination_attack(char *s) +gtp_combination_attack(char* s) { - int color; - int attack_point; - int n; + int color; + int attack_point; + int n; + + n = gtp_decode_color(s, &color); + if (!n) + return gtp_failure("invalid color"); - n = gtp_decode_color(s, &color); - if (!n) - return gtp_failure("invalid color"); + silent_examine_position(EXAMINE_ALL); - silent_examine_position(EXAMINE_ALL); + if (!atari_atari(color, &attack_point, NULL, verbose)) + attack_point = NO_MOVE; - if (!atari_atari(color, &attack_point, NULL, verbose)) - attack_point = NO_MOVE; - - gtp_start_response(GTP_SUCCESS); - gtp_print_vertex(I(attack_point), J(attack_point)); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + gtp_print_vertex(I(attack_point), J(attack_point)); + return gtp_finish_response(); } /* Function: If color can capture something through a @@ -2415,35 +2345,35 @@ gtp_combination_attack(char *s) */ static int -gtp_combination_defend(char *s) +gtp_combination_defend(char* s) { - int color; - signed char defense_points[BOARDMAX]; - int pos; - int first = 1; - int n; + int color; + signed char defense_points[BOARDMAX]; + int pos; + int first = 1; + int n; - n = gtp_decode_color(s, &color); - if (!n) - return gtp_failure("invalid color"); + n = gtp_decode_color(s, &color); + if (!n) + return gtp_failure("invalid color"); - silent_examine_position(EXAMINE_ALL); + silent_examine_position(EXAMINE_ALL); - memset(defense_points, 0, sizeof(defense_points)); - if (!atari_atari(color, NULL, defense_points, verbose)) - return gtp_success("PASS"); - - gtp_start_response(GTP_SUCCESS); - for (pos = BOARDMIN; pos < BOARDMAX; pos++) - if (ON_BOARD(pos) && defense_points[pos]) { - if (!first) - gtp_printf(" "); - else - first = 0; - gtp_print_vertex(I(pos), J(pos)); - } - - return gtp_finish_response(); + memset(defense_points, 0, sizeof(defense_points)); + if (!atari_atari(color, NULL, defense_points, verbose)) + return gtp_success("PASS"); + + gtp_start_response(GTP_SUCCESS); + for (pos = BOARDMIN; pos < BOARDMAX; pos++) + if (ON_BOARD(pos) && defense_points[pos]) { + if (!first) + gtp_printf(" "); + else + first = 0; + gtp_print_vertex(I(pos), J(pos)); + } + + return gtp_finish_response(); } /* Function: Run atari_atari_confirm_safety(). @@ -2453,39 +2383,38 @@ gtp_combination_defend(char *s) */ static int -gtp_aa_confirm_safety(char *s) +gtp_aa_confirm_safety(char* s) { - int color; - int i, j; - int n; - int minsize = 0; - int result; - int defense_point = NO_MOVE; - signed char saved_dragons[BOARDMAX]; - signed char saved_worms[BOARDMAX]; + int color; + int i, j; + int n; + int minsize = 0; + int result; + int defense_point = NO_MOVE; + signed char saved_dragons[BOARDMAX]; + signed char saved_worms[BOARDMAX]; - n = gtp_decode_move(s, &color, &i, &j); - if (n == 0 || POS(i, j) == NO_MOVE) - return gtp_failure("invalid color or coordinate"); + n = gtp_decode_move(s, &color, &i, &j); + if (n == 0 || POS(i, j) == NO_MOVE) + return gtp_failure("invalid color or coordinate"); - sscanf(s + n, "%d", &minsize); + sscanf(s + n, "%d", &minsize); - genmove(color, NULL, NULL); - get_saved_dragons(POS(i, j), saved_dragons); - get_saved_worms(POS(i, j), saved_worms); - - result = atari_atari_confirm_safety(color, POS(i, j), - &defense_point, minsize, - saved_dragons, saved_worms); - - gtp_start_response(GTP_SUCCESS); - gtp_mprintf("%d", result); - if (result == 0) - gtp_mprintf(" %m", I(defense_point), J(defense_point)); - - return gtp_finish_response(); -} + genmove(color, NULL, NULL); + get_saved_dragons(POS(i, j), saved_dragons); + get_saved_worms(POS(i, j), saved_worms); + result = atari_atari_confirm_safety(color, POS(i, j), + &defense_point, minsize, + saved_dragons, saved_worms); + + gtp_start_response(GTP_SUCCESS); + gtp_mprintf("%d", result); + if (result == 0) + gtp_mprintf(" %m", I(defense_point), J(defense_point)); + + return gtp_finish_response(); +} /******************** * generating moves * @@ -2499,21 +2428,21 @@ gtp_aa_confirm_safety(char *s) * Status: Obsolete GTP version 1 command. */ static int -gtp_genmove_black(char *s) +gtp_genmove_black(char* s) { - int move; - UNUSED(s); + int move; + UNUSED(s); - if (stackp > 0) - return gtp_failure("genmove cannot be called when stackp > 0"); + if (stackp > 0) + return gtp_failure("genmove cannot be called when stackp > 0"); - move = genmove(BLACK, NULL, NULL); + move = genmove(BLACK, NULL, NULL); - gnugo_play_move(move, BLACK); + gnugo_play_move(move, BLACK); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertex(I(move), J(move)); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + gtp_print_vertex(I(move), J(move)); + return gtp_finish_response(); } /* Function: Generate and play the supposedly best white move. @@ -2524,21 +2453,21 @@ gtp_genmove_black(char *s) * Status: Obsolete GTP version 1 command. */ static int -gtp_genmove_white(char *s) +gtp_genmove_white(char* s) { - int move; - UNUSED(s); + int move; + UNUSED(s); - if (stackp > 0) - return gtp_failure("genmove cannot be called when stackp > 0"); + if (stackp > 0) + return gtp_failure("genmove cannot be called when stackp > 0"); - move = genmove(WHITE, NULL, NULL); + move = genmove(WHITE, NULL, NULL); - gnugo_play_move(move, WHITE); + gnugo_play_move(move, WHITE); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertex(I(move), J(move)); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + gtp_print_vertex(I(move), J(move)); + return gtp_finish_response(); } /* Function: Generate and play the supposedly best move for either color. @@ -2549,34 +2478,33 @@ gtp_genmove_white(char *s) * Status: GTP version 2 standard command. */ static int -gtp_genmove(char *s) +gtp_genmove(char* s) { - int move; - int resign; - int color; - int n; + int move; + int resign; + int color; + int n; - n = gtp_decode_color(s, &color); - if (!n) - return gtp_failure("invalid color"); + n = gtp_decode_color(s, &color); + if (!n) + return gtp_failure("invalid color"); - if (stackp > 0) - return gtp_failure("genmove cannot be called when stackp > 0"); + if (stackp > 0) + return gtp_failure("genmove cannot be called when stackp > 0"); - adjust_level_offset(color); - move = genmove(color, NULL, &resign); + adjust_level_offset(color); + move = genmove(color, NULL, &resign); - if (resign) - return gtp_success("resign"); + if (resign) + return gtp_success("resign"); - gnugo_play_move(move, color); + gnugo_play_move(move, color); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertex(I(move), J(move)); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + gtp_print_vertex(I(move), J(move)); + return gtp_finish_response(); } - /* Function: Generate the supposedly best move for either color. * Arguments: color to move * Fails: invalid color @@ -2585,33 +2513,33 @@ gtp_genmove(char *s) * Status: GTP version 2 standard command. */ static int -gtp_reg_genmove(char *s) +gtp_reg_genmove(char* s) { - int move; - int color; - int n; - unsigned int saved_random_seed = get_random_seed(); + int move; + int color; + int n; + unsigned int saved_random_seed = get_random_seed(); - n = gtp_decode_color(s, &color); - if (!n) - return gtp_failure("invalid color"); + n = gtp_decode_color(s, &color); + if (!n) + return gtp_failure("invalid color"); - if (stackp > 0) - return gtp_failure("genmove cannot be called when stackp > 0"); + if (stackp > 0) + return gtp_failure("genmove cannot be called when stackp > 0"); - /* This is intended for regression purposes and should therefore be + /* This is intended for regression purposes and should therefore be * deterministic. The best way to ensure this is to reset the random * number generator before calling genmove(). It is always seeded by * 0. */ - set_random_seed(0); - - move = genmove_conservative(color, NULL); + set_random_seed(0); + + move = genmove_conservative(color, NULL); - set_random_seed(saved_random_seed); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertex(I(move), J(move)); - return gtp_finish_response(); + set_random_seed(saved_random_seed); + gtp_start_response(GTP_SUCCESS); + gtp_print_vertex(I(move), J(move)); + return gtp_finish_response(); } /* Function: Generate the supposedly best move for either color. @@ -2622,38 +2550,37 @@ gtp_reg_genmove(char *s) * This differs from reg_genmove in the optional random seed. */ static int -gtp_gg_genmove(char *s) +gtp_gg_genmove(char* s) { - int move; - int color; - int n; - unsigned int saved_random_seed = get_random_seed(); - unsigned int seed; + int move; + int color; + int n; + unsigned int saved_random_seed = get_random_seed(); + unsigned int seed; - n = gtp_decode_color(s, &color); - if (!n) - return gtp_failure("invalid color"); + n = gtp_decode_color(s, &color); + if (!n) + return gtp_failure("invalid color"); - if (stackp > 0) - return gtp_failure("genmove cannot be called when stackp > 0"); + if (stackp > 0) + return gtp_failure("genmove cannot be called when stackp > 0"); - /* This is intended for regression purposes and should therefore be + /* This is intended for regression purposes and should therefore be * deterministic. The best way to ensure this is to reset the random * number generator before calling genmove(). By default it is * seeded with 0, but if an optional unsigned integer is given in * the command after the color, this is used as seed instead. */ - seed = 0; - sscanf(s+n, "%u", &seed); - set_random_seed(seed); - - move = genmove_conservative(color, NULL); - set_random_seed(saved_random_seed); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertex(I(move), J(move)); - return gtp_finish_response(); -} + seed = 0; + sscanf(s + n, "%u", &seed); + set_random_seed(seed); + move = genmove_conservative(color, NULL); + set_random_seed(saved_random_seed); + gtp_start_response(GTP_SUCCESS); + gtp_print_vertex(I(move), J(move)); + return gtp_finish_response(); +} /* Function: Generate the supposedly best move for either color from a * choice of allowed vertices. @@ -2662,55 +2589,53 @@ gtp_gg_genmove(char *s) * Returns: a move coordinate (or "PASS") */ static int -gtp_restricted_genmove(char *s) +gtp_restricted_genmove(char* s) { - int move; - int i, j; - int color; - int n; - unsigned int saved_random_seed = get_random_seed(); - int allowed_moves[BOARDMAX]; - int number_allowed_moves = 0; - memset(allowed_moves, 0, sizeof(allowed_moves)); + int move; + int i, j; + int color; + int n; + unsigned int saved_random_seed = get_random_seed(); + int allowed_moves[BOARDMAX]; + int number_allowed_moves = 0; + memset(allowed_moves, 0, sizeof(allowed_moves)); - n = gtp_decode_color(s, &color); - if (!n) - return gtp_failure("invalid color"); + n = gtp_decode_color(s, &color); + if (!n) + return gtp_failure("invalid color"); - s += n; - while (1) { - n = gtp_decode_coord(s, &i, &j); - if (n > 0) { - allowed_moves[POS(i, j)] = 1; - number_allowed_moves++; - s += n; + s += n; + while (1) { + n = gtp_decode_coord(s, &i, &j); + if (n > 0) { + allowed_moves[POS(i, j)] = 1; + number_allowed_moves++; + s += n; + } else if (sscanf(s, "%*s") != EOF) + return gtp_failure("invalid coordinate"); + else + break; } - else if (sscanf(s, "%*s") != EOF) - return gtp_failure("invalid coordinate"); - else - break; - } - if (number_allowed_moves == 0) - return gtp_failure("no allowed vertex"); + if (number_allowed_moves == 0) + return gtp_failure("no allowed vertex"); - if (stackp > 0) - return gtp_failure("genmove cannot be called when stackp > 0"); + if (stackp > 0) + return gtp_failure("genmove cannot be called when stackp > 0"); - /* This is intended for regression purposes and should therefore be + /* This is intended for regression purposes and should therefore be * deterministic. The best way to ensure this is to reset the random * number generator before calling genmove(). It is always seeded by * 0. */ - set_random_seed(0); - - move = genmove_restricted(color, allowed_moves); - set_random_seed(saved_random_seed); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertex(I(move), J(move)); - return gtp_finish_response(); -} + set_random_seed(0); + move = genmove_restricted(color, allowed_moves); + set_random_seed(saved_random_seed); + gtp_start_response(GTP_SUCCESS); + gtp_print_vertex(I(move), J(move)); + return gtp_finish_response(); +} /* Function: Generate and play the supposedly best move for either color, * not passing until all dead opponent stones have been removed. @@ -2724,37 +2649,36 @@ gtp_restricted_genmove(char *s) * to GTP version 3 at a later time. */ static int -gtp_kgs_genmove_cleanup(char *s) +gtp_kgs_genmove_cleanup(char* s) { - int move; - int color; - int n; - int save_capture_all_dead = capture_all_dead; + int move; + int color; + int n; + int save_capture_all_dead = capture_all_dead; - n = gtp_decode_color(s, &color); - if (!n) - return gtp_failure("invalid color"); + n = gtp_decode_color(s, &color); + if (!n) + return gtp_failure("invalid color"); - if (stackp > 0) - return gtp_failure("kgs-genmove_cleanup cannot be called when stackp > 0"); + if (stackp > 0) + return gtp_failure("kgs-genmove_cleanup cannot be called when stackp > 0"); - /* Turn on the capture_all_dead option to force removal of dead + /* Turn on the capture_all_dead option to force removal of dead * opponent stones. */ - capture_all_dead = 1; - - adjust_level_offset(color); - move = genmove(color, NULL, NULL); + capture_all_dead = 1; - capture_all_dead = save_capture_all_dead; - - gnugo_play_move(move, color); + adjust_level_offset(color); + move = genmove(color, NULL, NULL); - gtp_start_response(GTP_SUCCESS); - gtp_print_vertex(I(move), J(move)); - return gtp_finish_response(); -} + capture_all_dead = save_capture_all_dead; + gnugo_play_move(move, color); + + gtp_start_response(GTP_SUCCESS); + gtp_print_vertex(I(move), J(move)); + return gtp_finish_response(); +} /* Function : List the move reasons for a move. * Arguments: vertex @@ -2763,20 +2687,20 @@ gtp_kgs_genmove_cleanup(char *s) */ static int -gtp_move_reasons(char *s) +gtp_move_reasons(char* s) { - int i, j; - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + int i, j; + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - if (BOARD(i, j) != EMPTY) - return gtp_failure("vertex must not be occupied"); + if (BOARD(i, j) != EMPTY) + return gtp_failure("vertex must not be occupied"); - gtp_start_response(GTP_SUCCESS); - if (list_move_reasons(gtp_output_file, POS(i, j)) == 0) + gtp_start_response(GTP_SUCCESS); + if (list_move_reasons(gtp_output_file, POS(i, j)) == 0) + gtp_printf("\n"); gtp_printf("\n"); - gtp_printf("\n"); - return GTP_OK; + return GTP_OK; } /* Function : Generate a list of all moves with values larger than zero in @@ -2789,13 +2713,13 @@ gtp_move_reasons(char *s) */ static int -gtp_all_move_values(char *s) +gtp_all_move_values(char* s) { - UNUSED(s); - gtp_start_response(GTP_SUCCESS); - print_all_move_values(gtp_output_file); - gtp_printf("\n"); - return GTP_OK; + UNUSED(s); + gtp_start_response(GTP_SUCCESS); + print_all_move_values(gtp_output_file); + gtp_printf("\n"); + return GTP_OK; } /* Function : Generate a sorted list of the best moves in the previous genmove @@ -2809,18 +2733,18 @@ gtp_all_move_values(char *s) /* FIXME: Don't we want the moves one per row? */ static int -gtp_top_moves(char *s) +gtp_top_moves(char* s) { - int k; - UNUSED(s); - gtp_start_response(GTP_SUCCESS); - for (k = 0; k < 10; k++) - if (best_move_values[k] > 0.0) { - gtp_print_vertex(I(best_moves[k]), J(best_moves[k])); - gtp_printf(" %.2f ", best_move_values[k]); - } - gtp_printf("\n\n"); - return GTP_OK; + int k; + UNUSED(s); + gtp_start_response(GTP_SUCCESS); + for (k = 0; k < 10; k++) + if (best_move_values[k] > 0.0) { + gtp_print_vertex(I(best_moves[k]), J(best_moves[k])); + gtp_printf(" %.2f ", best_move_values[k]); + } + gtp_printf("\n\n"); + return GTP_OK; } /* Function : Generate a list of the best moves for white with weights @@ -2830,18 +2754,18 @@ gtp_top_moves(char *s) */ static int -gtp_top_moves_white(char *s) +gtp_top_moves_white(char* s) { - int k; - UNUSED(s); - genmove(WHITE, NULL, NULL); - gtp_start_response(GTP_SUCCESS); - for (k = 0; k < 10; k++) - if (best_move_values[k] > 0.0) { - gtp_print_vertex(I(best_moves[k]), J(best_moves[k])); - gtp_printf(" %.2f ", best_move_values[k]); - } - return gtp_finish_response(); + int k; + UNUSED(s); + genmove(WHITE, NULL, NULL); + gtp_start_response(GTP_SUCCESS); + for (k = 0; k < 10; k++) + if (best_move_values[k] > 0.0) { + gtp_print_vertex(I(best_moves[k]), J(best_moves[k])); + gtp_printf(" %.2f ", best_move_values[k]); + } + return gtp_finish_response(); } /* Function : Generate a list of the best moves for black with weights @@ -2851,36 +2775,34 @@ gtp_top_moves_white(char *s) */ static int -gtp_top_moves_black(char *s) +gtp_top_moves_black(char* s) { - int k; - UNUSED(s); - genmove(BLACK, NULL, NULL); - gtp_start_response(GTP_SUCCESS); - for (k = 0; k < 10; k++) - if (best_move_values[k] > 0.0) { - gtp_print_vertex(I(best_moves[k]), J(best_moves[k])); - gtp_printf(" %.2f ", best_move_values[k]); - } - return gtp_finish_response(); + int k; + UNUSED(s); + genmove(BLACK, NULL, NULL); + gtp_start_response(GTP_SUCCESS); + for (k = 0; k < 10; k++) + if (best_move_values[k] > 0.0) { + gtp_print_vertex(I(best_moves[k]), J(best_moves[k])); + gtp_printf(" %.2f ", best_move_values[k]); + } + return gtp_finish_response(); } - - /* Function: Set the playing level. * Arguments: int * Fails: incorrect argument * Returns: nothing */ static int -gtp_set_level(char *s) +gtp_set_level(char* s) { - int new_level; - if (sscanf(s, "%d", &new_level) < 1) - return gtp_failure("level not an integer"); - - set_level(new_level); - return gtp_success(""); + int new_level; + if (sscanf(s, "%d", &new_level) < 1) + return gtp_failure("level not an integer"); + + set_level(new_level); + return gtp_success(""); } /* Function: Undo one move @@ -2892,18 +2814,17 @@ gtp_set_level(char *s) */ static int -gtp_undo(char *s) +gtp_undo(char* s) { - UNUSED(s); + UNUSED(s); - if (stackp > 0 || !undo_move(1)) - return gtp_failure("cannot undo"); + if (stackp > 0 || !undo_move(1)) + return gtp_failure("cannot undo"); - reset_engine(); - - return gtp_success(""); -} + reset_engine(); + return gtp_success(""); +} /* Function: Undo a number of moves * Arguments: optional int @@ -2912,23 +2833,22 @@ gtp_undo(char *s) */ static int -gtp_gg_undo(char *s) +gtp_gg_undo(char* s) { - int number_moves = 1; + int number_moves = 1; - sscanf(s, "%d", &number_moves); + sscanf(s, "%d", &number_moves); - if (number_moves < 0) - return gtp_failure("can't undo a negative number of moves"); + if (number_moves < 0) + return gtp_failure("can't undo a negative number of moves"); - if (stackp > 0 || !undo_move(number_moves)) - return gtp_failure("cannot undo"); + if (stackp > 0 || !undo_move(number_moves)) + return gtp_failure("cannot undo"); - reset_engine(); - - return gtp_success(""); -} + reset_engine(); + return gtp_success(""); +} /***************** * time handling * @@ -2943,17 +2863,16 @@ gtp_gg_undo(char *s) */ static int -gtp_time_settings(char *s) +gtp_time_settings(char* s) { - int main_time, byoyomi_time, byoyomi_stones; - - if (sscanf(s, "%d %d %d", &main_time, &byoyomi_time, &byoyomi_stones) < 3) - return gtp_failure("not three integers"); + int main_time, byoyomi_time, byoyomi_stones; - clock_settings(main_time, byoyomi_time, byoyomi_stones); - return gtp_success(""); -} + if (sscanf(s, "%d %d %d", &main_time, &byoyomi_time, &byoyomi_stones) < 3) + return gtp_failure("not three integers"); + clock_settings(main_time, byoyomi_time, byoyomi_stones); + return gtp_success(""); +} /* Function: Report remaining time * Arguments: color color, int time, int stones @@ -2964,25 +2883,24 @@ gtp_time_settings(char *s) */ static int -gtp_time_left(char *s) +gtp_time_left(char* s) { - int color; - int time; - int stones; - int n; + int color; + int time; + int stones; + int n; - n = gtp_decode_color(s, &color); - if (!n) - return gtp_failure("invalid color"); - - if (sscanf(s+n, "%d %d", &time, &stones) < 2) - return gtp_failure("time and stones not two integers"); + n = gtp_decode_color(s, &color); + if (!n) + return gtp_failure("invalid color"); - update_time_left(color, time, stones); - - return gtp_success(""); -} + if (sscanf(s + n, "%d %d", &time, &stones) < 2) + return gtp_failure("time and stones not two integers"); + update_time_left(color, time, stones); + + return gtp_success(""); +} /*********** * scoring * @@ -2990,123 +2908,119 @@ gtp_time_left(char *s) static float final_score; static enum dragon_status final_status[MAX_BOARD][MAX_BOARD]; -static enum dragon_status status_numbers[6] = {ALIVE, DEAD, ALIVE_IN_SEKI, - WHITE_TERRITORY, - BLACK_TERRITORY, DAME}; -static const char *status_names[6] = {"alive", "dead", "seki", - "white_territory", "black_territory", - "dame"}; +static enum dragon_status status_numbers[6] = { ALIVE, DEAD, ALIVE_IN_SEKI, + WHITE_TERRITORY, + BLACK_TERRITORY, DAME }; +static const char* status_names[6] = { "alive", "dead", "seki", + "white_territory", "black_territory", + "dame" }; /* Helper function. */ static void finish_and_score_game(int seed) { - int move; - int i, j; - int next; - int pass = 0; - int moves = 0; - int saved_board[MAX_BOARD][MAX_BOARD]; - struct board_state saved_pos; - static int current_board[MAX_BOARD][MAX_BOARD]; - static int current_seed = -1; - int cached_board = 1; - - if (current_seed != seed) { - current_seed = seed; - cached_board = 0; - } - - for (i = 0; i < board_size; i++) - for (j = 0; j < board_size; j++) - if (BOARD(i, j) != current_board[i][j]) { - current_board[i][j] = BOARD(i, j); - cached_board = 0; - } - - /* If this is exactly the same position as the one we analyzed the + int move; + int i, j; + int next; + int pass = 0; + int moves = 0; + int saved_board[MAX_BOARD][MAX_BOARD]; + struct board_state saved_pos; + static int current_board[MAX_BOARD][MAX_BOARD]; + static int current_seed = -1; + int cached_board = 1; + + if (current_seed != seed) { + current_seed = seed; + cached_board = 0; + } + + for (i = 0; i < board_size; i++) + for (j = 0; j < board_size; j++) + if (BOARD(i, j) != current_board[i][j]) { + current_board[i][j] = BOARD(i, j); + cached_board = 0; + } + + /* If this is exactly the same position as the one we analyzed the * last time, the contents of final_score and final_status are up to date. */ - if (cached_board) - return; + if (cached_board) + return; - doing_scoring = 1; - store_board(&saved_pos); + doing_scoring = 1; + store_board(&saved_pos); - /* Let black start if we have no move history. Otherwise continue + /* Let black start if we have no move history. Otherwise continue * alternation. */ - if (get_last_player() == EMPTY) - next = BLACK; - else - next = OTHER_COLOR(get_last_player()); - - do { - move = genmove_conservative(next, NULL); - gnugo_play_move(move, next); - if (move != PASS_MOVE) { - pass = 0; - moves++; - } + if (get_last_player() == EMPTY) + next = BLACK; else - pass++; - - next = OTHER_COLOR(next); - } while (pass < 2 && moves < board_size * board_size); - - final_score = aftermath_compute_score(next, NULL); - for (i = 0; i < board_size; i++) - for (j = 0; j < board_size; j++) { - final_status[i][j] = aftermath_final_status(next, POS(i, j)); - saved_board[i][j] = BOARD(i, j); - } - - restore_board(&saved_pos); - doing_scoring = 0; - - /* Update the status for vertices which were changed while finishing + next = OTHER_COLOR(get_last_player()); + + do { + move = genmove_conservative(next, NULL); + gnugo_play_move(move, next); + if (move != PASS_MOVE) { + pass = 0; + moves++; + } else + pass++; + + next = OTHER_COLOR(next); + } while (pass < 2 && moves < board_size * board_size); + + final_score = aftermath_compute_score(next, NULL); + for (i = 0; i < board_size; i++) + for (j = 0; j < board_size; j++) { + final_status[i][j] = aftermath_final_status(next, POS(i, j)); + saved_board[i][j] = BOARD(i, j); + } + + restore_board(&saved_pos); + doing_scoring = 0; + + /* Update the status for vertices which were changed while finishing * the game, up to filling dame. */ - for (i = 0; i < board_size; i++) - for (j = 0; j < board_size; j++) { - if (BOARD(i, j) == saved_board[i][j]) - continue; - - if (BOARD(i, j) == EMPTY) { - if (final_status[i][j] == ALIVE - || final_status[i][j] == ALIVE_IN_SEKI) - final_status[i][j] = DAME; - else if (final_status[i][j] == DEAD) { - if (saved_board[i][j] == BLACK) - final_status[i][j] = WHITE_TERRITORY; - else - final_status[i][j] = BLACK_TERRITORY; - } - } - else if (BOARD(i, j) == BLACK) { - if (final_status[i][j] == WHITE_TERRITORY) - final_status[i][j] = DEAD; - else if (final_status[i][j] == DAME) - final_status[i][j] = ALIVE_IN_SEKI; - else if (final_status[i][j] == BLACK_TERRITORY) - final_status[i][j] = ALIVE; - else - final_status[i][j] = DEAD; - } - else if (BOARD(i, j) == WHITE) { - if (final_status[i][j] == BLACK_TERRITORY) - final_status[i][j] = DEAD; - else if (final_status[i][j] == DAME) - final_status[i][j] = ALIVE_IN_SEKI; - else if (final_status[i][j] == WHITE_TERRITORY) - final_status[i][j] = ALIVE; - else - final_status[i][j] = DEAD; - } - } + for (i = 0; i < board_size; i++) + for (j = 0; j < board_size; j++) { + if (BOARD(i, j) == saved_board[i][j]) + continue; + + if (BOARD(i, j) == EMPTY) { + if (final_status[i][j] == ALIVE + || final_status[i][j] == ALIVE_IN_SEKI) + final_status[i][j] = DAME; + else if (final_status[i][j] == DEAD) { + if (saved_board[i][j] == BLACK) + final_status[i][j] = WHITE_TERRITORY; + else + final_status[i][j] = BLACK_TERRITORY; + } + } else if (BOARD(i, j) == BLACK) { + if (final_status[i][j] == WHITE_TERRITORY) + final_status[i][j] = DEAD; + else if (final_status[i][j] == DAME) + final_status[i][j] = ALIVE_IN_SEKI; + else if (final_status[i][j] == BLACK_TERRITORY) + final_status[i][j] = ALIVE; + else + final_status[i][j] = DEAD; + } else if (BOARD(i, j) == WHITE) { + if (final_status[i][j] == BLACK_TERRITORY) + final_status[i][j] = DEAD; + else if (final_status[i][j] == DAME) + final_status[i][j] = ALIVE_IN_SEKI; + else if (final_status[i][j] == WHITE_TERRITORY) + final_status[i][j] = ALIVE; + else + final_status[i][j] = DEAD; + } + } } - /* Function: Compute the score of a finished game. * Arguments: Optional random seed * Fails: never @@ -3115,35 +3029,34 @@ finish_and_score_game(int seed) * Status: GTP version 2 standard command. */ static int -gtp_final_score(char *s) +gtp_final_score(char* s) { - unsigned int saved_random_seed = get_random_seed(); - int seed; - /* This is intended for regression purposes and should therefore be + unsigned int saved_random_seed = get_random_seed(); + int seed; + /* This is intended for regression purposes and should therefore be * deterministic. The best way to ensure this is to reset the random * number generator before calling genmove(). By default it is * seeded with 0, but if an optional unsigned integer is given in * the command after the color, this is used as seed instead. */ - seed = 0; - sscanf(s, "%d", &seed); - set_random_seed(seed); + seed = 0; + sscanf(s, "%d", &seed); + set_random_seed(seed); - finish_and_score_game(seed); + finish_and_score_game(seed); - set_random_seed(saved_random_seed); + set_random_seed(saved_random_seed); - gtp_start_response(GTP_SUCCESS); - if (final_score > 0.0) - gtp_printf("W+%3.1f", final_score); - else if (final_score < 0.0) - gtp_printf("B+%3.1f", -final_score); - else - gtp_printf("0"); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + if (final_score > 0.0) + gtp_printf("W+%3.1f", final_score); + else if (final_score < 0.0) + gtp_printf("B+%3.1f", -final_score); + else + gtp_printf("0"); + return gtp_finish_response(); } - /* Function: Report the final status of a vertex in a finished game. * Arguments: Vertex, optional random seed * Fails: invalid vertex @@ -3151,43 +3064,42 @@ gtp_final_score(char *s) * "seki", "white_territory", "black_territory", or "dame". */ static int -gtp_final_status(char *s) +gtp_final_status(char* s) { - int seed; - int n; - int ai, aj; - int k; - unsigned int saved_random_seed = get_random_seed(); - const char *result = NULL; + int seed; + int n; + int ai, aj; + int k; + unsigned int saved_random_seed = get_random_seed(); + const char* result = NULL; - n = gtp_decode_coord(s, &ai, &aj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &ai, &aj); + if (n == 0) + return gtp_failure("invalid coordinate"); - /* This is intended for regression purposes and should therefore be + /* This is intended for regression purposes and should therefore be * deterministic. The best way to ensure this is to reset the random * number generator before calling genmove(). By default it is * seeded with 0, but if an optional unsigned integer is given in * the command after the color, this is used as seed instead. */ - seed = 0; - sscanf(s + n, "%d", &seed); - set_random_seed(seed); + seed = 0; + sscanf(s + n, "%d", &seed); + set_random_seed(seed); - finish_and_score_game(seed); + finish_and_score_game(seed); - set_random_seed(saved_random_seed); - for (k = 0; k < 6; k++) - if (final_status[ai][aj] == status_numbers[k]) { - result = status_names[k]; - break; - } - assert(result != NULL); + set_random_seed(saved_random_seed); + for (k = 0; k < 6; k++) + if (final_status[ai][aj] == status_numbers[k]) { + result = status_names[k]; + break; + } + assert(result != NULL); - return gtp_success(result); + return gtp_success(result); } - /* Function: Report vertices with a specific final status in a finished game. * Arguments: Status in the form of one of the strings "alive", "dead", * "seki", "white_territory", "black_territory", or "dame". @@ -3202,71 +3114,70 @@ gtp_final_status(char *s) * are private extensions. */ static int -gtp_final_status_list(char *s) +gtp_final_status_list(char* s) { - int seed; - int n; - int i, j; - enum dragon_status status = UNKNOWN; - int k; - char status_string[GTP_BUFSIZE]; - int first; - unsigned int saved_random_seed = get_random_seed(); + int seed; + int n; + int i, j; + enum dragon_status status = UNKNOWN; + int k; + char status_string[GTP_BUFSIZE]; + int first; + unsigned int saved_random_seed = get_random_seed(); + + if (sscanf(s, "%s %n", status_string, &n) != 1) + return gtp_failure("missing status"); - if (sscanf(s, "%s %n", status_string, &n) != 1) - return gtp_failure("missing status"); - - for (k = 0; k < 6; k++) { - if (strcmp(status_string, status_names[k]) == 0) - status = status_numbers[k]; - } + for (k = 0; k < 6; k++) { + if (strcmp(status_string, status_names[k]) == 0) + status = status_numbers[k]; + } - if (status == UNKNOWN) - return gtp_failure("invalid status"); + if (status == UNKNOWN) + return gtp_failure("invalid status"); - /* This is intended for regression purposes and should therefore be + /* This is intended for regression purposes and should therefore be * deterministic. The best way to ensure this is to reset the random * number generator before calling genmove(). By default it is * seeded with 0, but if an optional unsigned integer is given in * the command after the color, this is used as seed instead. */ - seed = 0; - sscanf(s + n, "%d", &seed); - set_random_seed(seed); - - finish_and_score_game(seed); - - set_random_seed(saved_random_seed); - - gtp_start_response(GTP_SUCCESS); - - first = 1; - for (i = 0; i < board_size; i++) - for (j = 0; j < board_size; j++) { - if (final_status[i][j] != status) - continue; - if (BOARD(i, j) == EMPTY) { - if (!first) - gtp_printf(" "); - else - first = 0; - gtp_print_vertex(i, j); - } - else { - int num_stones; - int stones[MAX_BOARD * MAX_BOARD]; - if (find_origin(POS(i, j)) != POS(i, j)) - continue; - if (!first) - gtp_printf("\n"); - else - first = 0; - num_stones = findstones(POS(i, j), board_size * board_size, stones); - gtp_print_vertices2(num_stones, stones); - } - } + seed = 0; + sscanf(s + n, "%d", &seed); + set_random_seed(seed); + + finish_and_score_game(seed); + + set_random_seed(saved_random_seed); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + + first = 1; + for (i = 0; i < board_size; i++) + for (j = 0; j < board_size; j++) { + if (final_status[i][j] != status) + continue; + if (BOARD(i, j) == EMPTY) { + if (!first) + gtp_printf(" "); + else + first = 0; + gtp_print_vertex(i, j); + } else { + int num_stones; + int stones[MAX_BOARD * MAX_BOARD]; + if (find_origin(POS(i, j)) != POS(i, j)) + continue; + if (!first) + gtp_printf("\n"); + else + first = 0; + num_stones = findstones(POS(i, j), board_size * board_size, stones); + gtp_print_vertices2(num_stones, stones); + } + } + + return gtp_finish_response(); } /* Function: Estimate the score @@ -3276,23 +3187,23 @@ gtp_final_status_list(char *s) */ static int -gtp_estimate_score(char *s) +gtp_estimate_score(char* s) { - float score; - float upper_bound, lower_bound; - UNUSED(s); + float score; + float upper_bound, lower_bound; + UNUSED(s); - score = gnugo_estimate_score(&upper_bound, &lower_bound); - gtp_start_response(GTP_SUCCESS); - /* Traditionally W wins jigo */ - if (score >= 0.0) - gtp_printf("W+%3.1f (upper bound: %3.1f, lower: %3.1f)", - score, upper_bound, lower_bound); - else if (score < 0.0) - gtp_printf("B+%3.1f (upper bound: %3.1f, lower: %3.1f)", - -score, upper_bound, lower_bound); - return gtp_finish_response(); -} + score = gnugo_estimate_score(&upper_bound, &lower_bound); + gtp_start_response(GTP_SUCCESS); + /* Traditionally W wins jigo */ + if (score >= 0.0) + gtp_printf("W+%3.1f (upper bound: %3.1f, lower: %3.1f)", + score, upper_bound, lower_bound); + else if (score < 0.0) + gtp_printf("B+%3.1f (upper bound: %3.1f, lower: %3.1f)", + -score, upper_bound, lower_bound); + return gtp_finish_response(); +} /* Function: Estimate the score, taking into account which player moves next * Arguments: Color to play @@ -3307,29 +3218,28 @@ gtp_estimate_score(char *s) */ static int -gtp_experimental_score(char *s) +gtp_experimental_score(char* s) { - float upper_bound, lower_bound, score; - int color; + float upper_bound, lower_bound, score; + int color; - if (!gtp_decode_color(s, &color) - || (color != BLACK && color != WHITE)) - return gtp_failure("invalid color"); + if (!gtp_decode_color(s, &color) + || (color != BLACK && color != WHITE)) + return gtp_failure("invalid color"); - genmove_conservative(color, NULL); - gnugo_estimate_score(&upper_bound, &lower_bound); + genmove_conservative(color, NULL); + gnugo_estimate_score(&upper_bound, &lower_bound); - if (debug & DEBUG_SCORING) - fprintf(stderr, "upper = %3.1f, lower = %3.1f, best = %3.1f\n", - upper_bound, lower_bound, best_move_values[0]); - if (color == WHITE) - score = lower_bound + best_move_values[0]; - else - score = upper_bound - best_move_values[0]; - - return gtp_success("%3.1f", score); -} + if (debug & DEBUG_SCORING) + fprintf(stderr, "upper = %3.1f, lower = %3.1f, best = %3.1f\n", + upper_bound, lower_bound, best_move_values[0]); + if (color == WHITE) + score = lower_bound + best_move_values[0]; + else + score = upper_bound - best_move_values[0]; + return gtp_success("%3.1f", score); +} /************** * statistics * @@ -3344,13 +3254,12 @@ gtp_experimental_score(char *s) * compatibility. */ static int -gtp_reset_life_node_counter(char *s) +gtp_reset_life_node_counter(char* s) { - UNUSED(s); - return gtp_success(""); + UNUSED(s); + return gtp_success(""); } - /* Function: Retrieve the count of life nodes. * Arguments: none * Fails: never @@ -3360,160 +3269,148 @@ gtp_reset_life_node_counter(char *s) * compatibility. */ static int -gtp_get_life_node_counter(char *s) +gtp_get_life_node_counter(char* s) { - UNUSED(s); - return gtp_success("0"); + UNUSED(s); + return gtp_success("0"); } - /* Function: Reset the count of owl nodes. * Arguments: none * Fails: never * Returns: nothing */ static int -gtp_reset_owl_node_counter(char *s) +gtp_reset_owl_node_counter(char* s) { - UNUSED(s); - reset_owl_node_counter(); - return gtp_success(""); + UNUSED(s); + reset_owl_node_counter(); + return gtp_success(""); } - /* Function: Retrieve the count of owl nodes. * Arguments: none * Fails: never * Returns: number of owl nodes */ static int -gtp_get_owl_node_counter(char *s) +gtp_get_owl_node_counter(char* s) { - int nodes = get_owl_node_counter(); - UNUSED(s); - return gtp_success("%d", nodes); + int nodes = get_owl_node_counter(); + UNUSED(s); + return gtp_success("%d", nodes); } - /* Function: Reset the count of reading nodes. * Arguments: none * Fails: never * Returns: nothing */ static int -gtp_reset_reading_node_counter(char *s) +gtp_reset_reading_node_counter(char* s) { - UNUSED(s); - reset_reading_node_counter(); - return gtp_success(""); + UNUSED(s); + reset_reading_node_counter(); + return gtp_success(""); } - /* Function: Retrieve the count of reading nodes. * Arguments: none * Fails: never * Returns: number of reading nodes */ static int -gtp_get_reading_node_counter(char *s) +gtp_get_reading_node_counter(char* s) { - int nodes = get_reading_node_counter(); - UNUSED(s); - return gtp_success("%d", nodes); + int nodes = get_reading_node_counter(); + UNUSED(s); + return gtp_success("%d", nodes); } - /* Function: Reset the count of trymoves/trykos. * Arguments: none * Fails: never * Returns: nothing */ static int -gtp_reset_trymove_counter(char *s) +gtp_reset_trymove_counter(char* s) { - UNUSED(s); - reset_trymove_counter(); - return gtp_success(""); + UNUSED(s); + reset_trymove_counter(); + return gtp_success(""); } - /* Function: Retrieve the count of trymoves/trykos. * Arguments: none * Fails: never * Returns: number of trymoves/trykos */ static int -gtp_get_trymove_counter(char *s) +gtp_get_trymove_counter(char* s) { - int nodes = get_trymove_counter(); - UNUSED(s); - return gtp_success("%d", nodes); + int nodes = get_trymove_counter(); + UNUSED(s); + return gtp_success("%d", nodes); } - /* Function: Reset the count of connection nodes. * Arguments: none * Fails: never * Returns: nothing */ static int -gtp_reset_connection_node_counter(char *s) +gtp_reset_connection_node_counter(char* s) { - UNUSED(s); - reset_connection_node_counter(); - return gtp_success(""); + UNUSED(s); + reset_connection_node_counter(); + return gtp_success(""); } - /* Function: Retrieve the count of connection nodes. * Arguments: none * Fails: never * Returns: number of connection nodes */ static int -gtp_get_connection_node_counter(char *s) +gtp_get_connection_node_counter(char* s) { - int nodes = get_connection_node_counter(); - UNUSED(s); - return gtp_success("%d", nodes); + int nodes = get_connection_node_counter(); + UNUSED(s); + return gtp_success("%d", nodes); } - - /********* * debug * *********/ - /* Function: Test an eyeshape for inconsistent evaluations * Arguments: Eyeshape vertices * Fails: Bad vertices * Returns: Failure reports on stderr. */ static int -gtp_test_eyeshape(char *s) +gtp_test_eyeshape(char* s) { - int n; - int i, j; - int eye_vertices[MAX_BOARD * MAX_BOARD]; - int eyesize = 0; + int n; + int i, j; + int eye_vertices[MAX_BOARD * MAX_BOARD]; + int eyesize = 0; - n = gtp_decode_coord(s, &i, &j); - while (n > 0) { - eye_vertices[eyesize] = POS(i, j); - eyesize++; - s += n; n = gtp_decode_coord(s, &i, &j); - } - - if (eyesize == 0) - return gtp_failure("invalid coordinate"); + while (n > 0) { + eye_vertices[eyesize] = POS(i, j); + eyesize++; + s += n; + n = gtp_decode_coord(s, &i, &j); + } - test_eyeshape(eyesize, eye_vertices); + if (eyesize == 0) + return gtp_failure("invalid coordinate"); - return gtp_success(""); -} + test_eyeshape(eyesize, eye_vertices); + return gtp_success(""); +} /* Function: Compute an eyevalue and vital points for an eye graph * Arguments: Eyeshape encoded in string @@ -3521,34 +3418,30 @@ gtp_test_eyeshape(char *s) * Returns: Eyevalue, vital points */ static int -gtp_analyze_eyegraph(char *s) +gtp_analyze_eyegraph(char* s) { - struct eyevalue value; - char analyzed_eyegraph[1024]; - int result = analyze_eyegraph(s, &value, analyzed_eyegraph); + struct eyevalue value; + char analyzed_eyegraph[1024]; + int result = analyze_eyegraph(s, &value, analyzed_eyegraph); - if (result == 0) - return gtp_failure("failed to analyze"); + if (result == 0) + return gtp_failure("failed to analyze"); - return gtp_success("%s\n%s", eyevalue_to_string(&value), analyzed_eyegraph); + return gtp_success("%s\n%s", eyevalue_to_string(&value), analyzed_eyegraph); } - - /* Function: Returns elapsed CPU time in seconds. * Arguments: none * Fails: never * Returns: Total elapsed (user + system) CPU time in seconds. */ static int -gtp_cputime(char *s) +gtp_cputime(char* s) { - UNUSED(s); - return gtp_success("%.3f", gg_cputime()); + UNUSED(s); + return gtp_success("%.3f", gg_cputime()); } - - /* Function: Write the position to stdout. * Arguments: none * Fails: never @@ -3557,16 +3450,15 @@ gtp_cputime(char *s) * Status: GTP version 2 standard command. */ static int -gtp_showboard(char *s) +gtp_showboard(char* s) { - UNUSED(s); - - gtp_start_response(GTP_SUCCESS); - gtp_printf("\n"); - simple_showboard(gtp_output_file); - return gtp_finish_response(); -} + UNUSED(s); + gtp_start_response(GTP_SUCCESS); + gtp_printf("\n"); + simple_showboard(gtp_output_file); + return gtp_finish_response(); +} /* Function: Dump stack to stderr. * Arguments: none @@ -3574,87 +3466,87 @@ gtp_showboard(char *s) * Returns: nothing */ static int -gtp_dump_stack(char *s) +gtp_dump_stack(char* s) { - UNUSED(s); - dump_stack(); - return gtp_success(""); + UNUSED(s); + dump_stack(); + return gtp_success(""); } /* Determine whether a string starts with a specific substring. */ static int -has_prefix(const char *s, const char *prefix) -{ - return strncmp(s, prefix, strlen(prefix)) == 0; -} - -static int -print_influence_data(struct influence_data *q, char *what_data) -{ - float white_influence[BOARDMAX]; - float black_influence[BOARDMAX]; - float white_strength[BOARDMAX]; - float black_strength[BOARDMAX]; - float white_attenuation[BOARDMAX]; - float black_attenuation[BOARDMAX]; - float white_permeability[BOARDMAX]; - float black_permeability[BOARDMAX]; - float territory_value[BOARDMAX]; - int influence_regions[BOARDMAX]; - int non_territory[BOARDMAX]; - int m, n; - - float *float_pointer = NULL; - int *int_pointer = NULL; - - while (*what_data == ' ') - what_data++; - - get_influence(q, white_influence, black_influence, - white_strength, black_strength, - white_attenuation, black_attenuation, - white_permeability, black_permeability, - territory_value, influence_regions, non_territory); - - if (has_prefix(what_data, "white_influence")) - float_pointer = white_influence; - else if (has_prefix(what_data, "black_influence")) - float_pointer = black_influence; - else if (has_prefix(what_data, "white_strength")) - float_pointer = white_strength; - else if (has_prefix(what_data, "black_strength")) - float_pointer = black_strength; - else if (has_prefix(what_data, "white_attenuation")) - float_pointer = white_attenuation; - else if (has_prefix(what_data, "black_attenuation")) - float_pointer = black_attenuation; - else if (has_prefix(what_data, "white_permeability")) - float_pointer = white_permeability; - else if (has_prefix(what_data, "black_permeability")) - float_pointer = black_permeability; - else if (has_prefix(what_data, "territory_value")) - float_pointer = territory_value; - else if (has_prefix(what_data, "influence_regions")) - int_pointer = influence_regions; - else if (has_prefix(what_data, "non_territory")) - int_pointer = non_territory; - else - return gtp_failure("unknown influence data"); - - gtp_start_response(GTP_SUCCESS); - for (m = 0; m < board_size; m++) { - for (n = 0; n < board_size; n++) { - if (float_pointer) - gtp_printf("%6.2f ", float_pointer[POS(m, n)]); - else - gtp_printf("%2d ", int_pointer[POS(m, n)]); +has_prefix(const char* s, const char* prefix) +{ + return strncmp(s, prefix, strlen(prefix)) == 0; +} + +static int +print_influence_data(struct influence_data* q, char* what_data) +{ + float white_influence[BOARDMAX]; + float black_influence[BOARDMAX]; + float white_strength[BOARDMAX]; + float black_strength[BOARDMAX]; + float white_attenuation[BOARDMAX]; + float black_attenuation[BOARDMAX]; + float white_permeability[BOARDMAX]; + float black_permeability[BOARDMAX]; + float territory_value[BOARDMAX]; + int influence_regions[BOARDMAX]; + int non_territory[BOARDMAX]; + int m, n; + + float* float_pointer = NULL; + int* int_pointer = NULL; + + while (*what_data == ' ') + what_data++; + + get_influence(q, white_influence, black_influence, + white_strength, black_strength, + white_attenuation, black_attenuation, + white_permeability, black_permeability, + territory_value, influence_regions, non_territory); + + if (has_prefix(what_data, "white_influence")) + float_pointer = white_influence; + else if (has_prefix(what_data, "black_influence")) + float_pointer = black_influence; + else if (has_prefix(what_data, "white_strength")) + float_pointer = white_strength; + else if (has_prefix(what_data, "black_strength")) + float_pointer = black_strength; + else if (has_prefix(what_data, "white_attenuation")) + float_pointer = white_attenuation; + else if (has_prefix(what_data, "black_attenuation")) + float_pointer = black_attenuation; + else if (has_prefix(what_data, "white_permeability")) + float_pointer = white_permeability; + else if (has_prefix(what_data, "black_permeability")) + float_pointer = black_permeability; + else if (has_prefix(what_data, "territory_value")) + float_pointer = territory_value; + else if (has_prefix(what_data, "influence_regions")) + int_pointer = influence_regions; + else if (has_prefix(what_data, "non_territory")) + int_pointer = non_territory; + else + return gtp_failure("unknown influence data"); + + gtp_start_response(GTP_SUCCESS); + for (m = 0; m < board_size; m++) { + for (n = 0; n < board_size; n++) { + if (float_pointer) + gtp_printf("%6.2f ", float_pointer[POS(m, n)]); + else + gtp_printf("%2d ", int_pointer[POS(m, n)]); + } + gtp_printf("\n"); } + + /* We already have one newline and thus can't use gtp_finish_response(). */ gtp_printf("\n"); - } - - /* We already have one newline and thus can't use gtp_finish_response(). */ - gtp_printf("\n"); - return GTP_OK; + return GTP_OK; } /* Function: Return information about the initial influence function. @@ -3695,23 +3587,22 @@ print_influence_data(struct influence_data *q, char *what_data) * -4 black stone */ static int -gtp_initial_influence(char *s) +gtp_initial_influence(char* s) { - int color; - struct influence_data *q; - int n; + int color; + struct influence_data* q; + int n; - n = gtp_decode_color(s, &color); - if (n == 0) - return gtp_failure("invalid color"); + n = gtp_decode_color(s, &color); + if (n == 0) + return gtp_failure("invalid color"); - q = INITIAL_INFLUENCE(color); - - silent_examine_position(EXAMINE_ALL); + q = INITIAL_INFLUENCE(color); - return print_influence_data(q, s + n); -} + silent_examine_position(EXAMINE_ALL); + return print_influence_data(q, s + n); +} /* Function: Return information about the influence function after a move. * Arguments: move, what information @@ -3719,21 +3610,20 @@ gtp_initial_influence(char *s) * Returns: Influence data formatted like for initial_influence. */ static int -gtp_move_influence(char *s) +gtp_move_influence(char* s) { - int color; - int i, j; - int n; + int color; + int i, j; + int n; - n = gtp_decode_move(s, &color, &i, &j); - if (n == 0) - return gtp_failure("invalid move"); + n = gtp_decode_move(s, &color, &i, &j); + if (n == 0) + return gtp_failure("invalid move"); - prepare_move_influence_debugging(POS(i, j), color); - - return print_influence_data(&move_influence, s + n); -} + prepare_move_influence_debugging(POS(i, j), color); + return print_influence_data(&move_influence, s + n); +} /* Function: List probabilities of each move being played (when non-zero). * If no previous genmove command has been issued, the result @@ -3743,33 +3633,32 @@ gtp_move_influence(char *s) * Returns: Move, probabilty pairs, one per row. */ static int -gtp_move_probabilities(char *s) +gtp_move_probabilities(char* s) { - float probabilities[BOARDMAX]; - int pos; - int any_moves_printed = 0; + float probabilities[BOARDMAX]; + int pos; + int any_moves_printed = 0; - UNUSED(s); + UNUSED(s); - compute_move_probabilities(probabilities); + compute_move_probabilities(probabilities); - gtp_start_response(GTP_SUCCESS); - for (pos = BOARDMIN; pos < BOARDMAX; pos++) { - if (ON_BOARD(pos) && probabilities[pos] != 0.0) { - gtp_mprintf("%m ", I(pos), J(pos)); - gtp_printf("%.4f\n", probabilities[pos]); - any_moves_printed = 1; + gtp_start_response(GTP_SUCCESS); + for (pos = BOARDMIN; pos < BOARDMAX; pos++) { + if (ON_BOARD(pos) && probabilities[pos] != 0.0) { + gtp_mprintf("%m ", I(pos), J(pos)); + gtp_printf("%.4f\n", probabilities[pos]); + any_moves_printed = 1; + } } - } - if (!any_moves_printed) + if (!any_moves_printed) + gtp_printf("\n"); gtp_printf("\n"); - gtp_printf("\n"); - return GTP_OK; + return GTP_OK; } - /* Function: Return the number of bits of uncertainty in the move. * If no previous genmove command has been issued, the result * of this command will be meaningless. @@ -3778,53 +3667,49 @@ gtp_move_probabilities(char *s) * Returns: bits of uncertainty */ static int -gtp_move_uncertainty(char *s) +gtp_move_uncertainty(char* s) { - float probabilities[BOARDMAX]; - int pos; - double uncertainty = 0.0; + float probabilities[BOARDMAX]; + int pos; + double uncertainty = 0.0; - UNUSED(s); + UNUSED(s); - compute_move_probabilities(probabilities); + compute_move_probabilities(probabilities); - gtp_start_response(GTP_SUCCESS); - for (pos = BOARDMIN; pos < BOARDMAX; pos++) { - if (ON_BOARD(pos) && probabilities[pos] > 0.0) { - /* Shannon's formula */ - uncertainty += -1 * ((double)probabilities[pos]) * - log((double)probabilities[pos]) / log(2.0); + gtp_start_response(GTP_SUCCESS); + for (pos = BOARDMIN; pos < BOARDMAX; pos++) { + if (ON_BOARD(pos) && probabilities[pos] > 0.0) { + /* Shannon's formula */ + uncertainty += -1 * ((double)probabilities[pos]) * log((double)probabilities[pos]) / log(2.0); + } } - } - gtp_printf("%.4f\n\n", uncertainty); + gtp_printf("%.4f\n\n", uncertainty); - return GTP_OK; + return GTP_OK; } - - /* Function: Return information about the followup influence after a move. * Arguments: move, what information * Fails: never * Returns: Influence data formatted like for initial_influence. */ static int -gtp_followup_influence(char *s) +gtp_followup_influence(char* s) { - int color; - int i, j; - int n; + int color; + int i, j; + int n; - n = gtp_decode_move(s, &color, &i, &j); - if (n == 0) - return gtp_failure("invalid move"); + n = gtp_decode_move(s, &color, &i, &j); + if (n == 0) + return gtp_failure("invalid move"); - prepare_move_influence_debugging(POS(i, j), color); - - return print_influence_data(&followup_influence, s + n); -} + prepare_move_influence_debugging(POS(i, j), color); + return print_influence_data(&followup_influence, s + n); +} /* Function: Return the information in the worm data structure. * Arguments: optional vertex @@ -3861,52 +3746,52 @@ gtp_followup_influence(char *s) * If an intersection is specified, only data for this one will be returned. */ static int -gtp_worm_data(char *s) -{ - int i = -1; - int j = -1; - int m, n; - - if (sscanf(s, "%*c") >= 0 && !gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid color or coordinate"); - - silent_examine_position(EXAMINE_WORMS); - - gtp_start_response(GTP_SUCCESS); - - for (m = 0; m < board_size; m++) - for (n = 0; n < board_size; n++) - if (i == -1 || (m == i && n == j)) { - struct worm_data *w = &worm[POS(m, n)]; - gtp_print_vertex(m, n); - gtp_printf(":\n"); - gtp_mprintf("origin %m\n", I(w->origin), J(w->origin)); - gtp_mprintf("color %C\n", w->color); - gtp_printf("size %d\n", w->size); - gtp_printf("effective_size %.2f\n", w->effective_size); - gtp_printf("liberties %d\n", w->liberties); - gtp_printf("liberties2 %d\n", w->liberties2); - gtp_printf("liberties3 %d\n", w->liberties3); - gtp_printf("liberties4 %d\n", w->liberties4); - gtp_printf("attack_code %d\n", w->attack_codes[0]); - gtp_mprintf("attack_point %m\n", - I(w->attack_points[0]), J(w->attack_points[0])); - gtp_printf("defense_code %d\n", w->defense_codes[0]); - gtp_mprintf("defense_point %m\n", - I(w->defense_points[0]), J(w->defense_points[0])); - gtp_mprintf("lunch %m\n", - I(w->lunch), J(w->lunch)); - gtp_printf("cutstone %d\n", w->cutstone); - gtp_printf("cutstone2 %d\n", w->cutstone2); - gtp_printf("genus %d\n", w->genus); - gtp_printf("inessential %d\n", w->inessential); - gtp_printf("invincible %d\n", w->invincible); - gtp_printf("unconditional_status %s\n", - status_to_string(w->unconditional_status)); - } - - gtp_printf("\n"); - return GTP_OK; +gtp_worm_data(char* s) +{ + int i = -1; + int j = -1; + int m, n; + + if (sscanf(s, "%*c") >= 0 && !gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid color or coordinate"); + + silent_examine_position(EXAMINE_WORMS); + + gtp_start_response(GTP_SUCCESS); + + for (m = 0; m < board_size; m++) + for (n = 0; n < board_size; n++) + if (i == -1 || (m == i && n == j)) { + struct worm_data* w = &worm[POS(m, n)]; + gtp_print_vertex(m, n); + gtp_printf(":\n"); + gtp_mprintf("origin %m\n", I(w->origin), J(w->origin)); + gtp_mprintf("color %C\n", w->color); + gtp_printf("size %d\n", w->size); + gtp_printf("effective_size %.2f\n", w->effective_size); + gtp_printf("liberties %d\n", w->liberties); + gtp_printf("liberties2 %d\n", w->liberties2); + gtp_printf("liberties3 %d\n", w->liberties3); + gtp_printf("liberties4 %d\n", w->liberties4); + gtp_printf("attack_code %d\n", w->attack_codes[0]); + gtp_mprintf("attack_point %m\n", + I(w->attack_points[0]), J(w->attack_points[0])); + gtp_printf("defense_code %d\n", w->defense_codes[0]); + gtp_mprintf("defense_point %m\n", + I(w->defense_points[0]), J(w->defense_points[0])); + gtp_mprintf("lunch %m\n", + I(w->lunch), J(w->lunch)); + gtp_printf("cutstone %d\n", w->cutstone); + gtp_printf("cutstone2 %d\n", w->cutstone2); + gtp_printf("genus %d\n", w->genus); + gtp_printf("inessential %d\n", w->inessential); + gtp_printf("invincible %d\n", w->invincible); + gtp_printf("unconditional_status %s\n", + status_to_string(w->unconditional_status)); + } + + gtp_printf("\n"); + return GTP_OK; } /* Function: List the stones of a worm @@ -3915,52 +3800,50 @@ gtp_worm_data(char *s) * Returns: list of stones */ static int -gtp_worm_stones(char *s) -{ - int i = -1; - int j = -1; - int color = EMPTY; - int m, n; - int u, v; - int board_empty = 1; - - if (sscanf(s, "%*c") >= 0) { - if (!gtp_decode_coord(s, &i, &j) - && !gtp_decode_color(s, &color)) - return gtp_failure("invalid coordinate"); - } - - if (BOARD(i, j) == EMPTY) - return gtp_failure("worm_stones called on an empty vertex"); - - gtp_start_response(GTP_SUCCESS); - - for (u = 0; u < board_size; u++) - for (v = 0; v < board_size; v++) { - if (BOARD(u, v) == EMPTY - || (color != EMPTY && BOARD(u, v) != color)) - continue; - board_empty = 0; - if (find_origin(POS(u, v)) != POS(u, v)) - continue; - if (ON_BOARD2(i, j) - && !same_string(POS(u, v), POS(i, j))) - continue; - for (m = 0; m < board_size; m++) - for (n = 0; n < board_size; n++) - if (BOARD(m, n) != EMPTY - && same_string(POS(m, n), POS(u, v))) - gtp_mprintf("%m ", m, n); - gtp_printf("\n"); +gtp_worm_stones(char* s) +{ + int i = -1; + int j = -1; + int color = EMPTY; + int m, n; + int u, v; + int board_empty = 1; + + if (sscanf(s, "%*c") >= 0) { + if (!gtp_decode_coord(s, &i, &j) + && !gtp_decode_color(s, &color)) + return gtp_failure("invalid coordinate"); } - - if (board_empty) - gtp_printf("\n"); /* in case no stones have been printed */ - gtp_printf("\n"); - return GTP_OK; -} + if (BOARD(i, j) == EMPTY) + return gtp_failure("worm_stones called on an empty vertex"); + gtp_start_response(GTP_SUCCESS); + + for (u = 0; u < board_size; u++) + for (v = 0; v < board_size; v++) { + if (BOARD(u, v) == EMPTY + || (color != EMPTY && BOARD(u, v) != color)) + continue; + board_empty = 0; + if (find_origin(POS(u, v)) != POS(u, v)) + continue; + if (ON_BOARD2(i, j) + && !same_string(POS(u, v), POS(i, j))) + continue; + for (m = 0; m < board_size; m++) + for (n = 0; n < board_size; n++) + if (BOARD(m, n) != EMPTY + && same_string(POS(m, n), POS(u, v))) + gtp_mprintf("%m ", m, n); + gtp_printf("\n"); + } + + if (board_empty) + gtp_printf("\n"); /* in case no stones have been printed */ + gtp_printf("\n"); + return GTP_OK; +} /* Function: Return the cutstone field in the worm data structure. * Arguments: non-empty vertex @@ -3968,19 +3851,19 @@ gtp_worm_stones(char *s) * Returns: cutstone */ static int -gtp_worm_cutstone(char *s) +gtp_worm_cutstone(char* s) { - int i, j; - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + int i, j; + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - if (BOARD(i, j) == EMPTY) - return gtp_failure("vertex must not be empty"); + if (BOARD(i, j) == EMPTY) + return gtp_failure("vertex must not be empty"); - silent_examine_position(EXAMINE_WORMS); + silent_examine_position(EXAMINE_WORMS); - return gtp_success(" %d", worm[POS(i, j)].cutstone); + return gtp_success(" %d", worm[POS(i, j)].cutstone); } /* Function: Return the information in the dragon data structure. @@ -3989,43 +3872,43 @@ gtp_worm_cutstone(char *s) * Returns: Dragon data formatted in the corresponding way to gtp_worm_data. */ static int -gtp_dragon_data(char *s) +gtp_dragon_data(char* s) { - int i = -1; - int j = -1; - int m, n; - int newline_needed = 0; + int i = -1; + int j = -1; + int m, n; + int newline_needed = 0; - if (sscanf(s, "%*c") >= 0 && !gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + if (sscanf(s, "%*c") >= 0 && !gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - if (stackp > 0) - return gtp_failure("dragon data unavailable when stackp > 0"); + if (stackp > 0) + return gtp_failure("dragon data unavailable when stackp > 0"); - silent_examine_position(FULL_EXAMINE_DRAGONS); + silent_examine_position(FULL_EXAMINE_DRAGONS); - gtp_start_response(GTP_SUCCESS); + gtp_start_response(GTP_SUCCESS); - if (ON_BOARD2(i, j) && BOARD(i, j) == EMPTY) - gtp_mprintf("%m empty\n", i, j); - else { - newline_needed = 1; - for (m = 0; m < board_size; m++) - for (n = 0; n < board_size; n++) - if ((m == i && n == j) - || (i == -1 - && BOARD(m, n) != EMPTY - && dragon[POS(m, n)].origin == POS(m, n))) { - gtp_print_vertex(m, n); - gtp_printf(":\n"); - report_dragon(gtp_output_file, POS(m, n)); - newline_needed = 0; - } - } - if (newline_needed) + if (ON_BOARD2(i, j) && BOARD(i, j) == EMPTY) + gtp_mprintf("%m empty\n", i, j); + else { + newline_needed = 1; + for (m = 0; m < board_size; m++) + for (n = 0; n < board_size; n++) + if ((m == i && n == j) + || (i == -1 + && BOARD(m, n) != EMPTY + && dragon[POS(m, n)].origin == POS(m, n))) { + gtp_print_vertex(m, n); + gtp_printf(":\n"); + report_dragon(gtp_output_file, POS(m, n)); + newline_needed = 0; + } + } + if (newline_needed) + gtp_printf("\n"); gtp_printf("\n"); - gtp_printf("\n"); - return GTP_OK; + return GTP_OK; } /* Function: List the stones of a dragon @@ -4034,46 +3917,45 @@ gtp_dragon_data(char *s) * Returns: list of stones */ static int -gtp_dragon_stones(char *s) -{ - int i = -1; - int j = -1; - int color = EMPTY; - int m, n; - int u, v; - - if (sscanf(s, "%*c") >= 0) { - if (!gtp_decode_coord(s, &i, &j) - && !gtp_decode_color(s, &color)) - return gtp_failure("invalid coordinate"); - } - - if (BOARD(i, j) == EMPTY) - return gtp_failure("dragon_stones called on an empty vertex"); - - silent_examine_position(EXAMINE_DRAGONS); - - gtp_start_response(GTP_SUCCESS); - - - for (u = 0; u < board_size; u++) - for (v = 0; v < board_size; v++) { - if (BOARD(u, v) == EMPTY - || (color != EMPTY && BOARD(u, v) != color)) - continue; - if (dragon[POS(u, v)].origin != POS(u, v)) - continue; - if (ON_BOARD2(i, j) && dragon[POS(i, j)].origin != POS(u, v)) - continue; - for (m = 0; m < board_size; m++) - for (n = 0; n < board_size; n++) - if (dragon[POS(m, n)].origin == POS(u, v)) - gtp_mprintf("%m ", m, n); - gtp_printf("\n"); +gtp_dragon_stones(char* s) +{ + int i = -1; + int j = -1; + int color = EMPTY; + int m, n; + int u, v; + + if (sscanf(s, "%*c") >= 0) { + if (!gtp_decode_coord(s, &i, &j) + && !gtp_decode_color(s, &color)) + return gtp_failure("invalid coordinate"); } - - gtp_printf("\n"); - return GTP_OK; + + if (BOARD(i, j) == EMPTY) + return gtp_failure("dragon_stones called on an empty vertex"); + + silent_examine_position(EXAMINE_DRAGONS); + + gtp_start_response(GTP_SUCCESS); + + for (u = 0; u < board_size; u++) + for (v = 0; v < board_size; v++) { + if (BOARD(u, v) == EMPTY + || (color != EMPTY && BOARD(u, v) != color)) + continue; + if (dragon[POS(u, v)].origin != POS(u, v)) + continue; + if (ON_BOARD2(i, j) && dragon[POS(i, j)].origin != POS(u, v)) + continue; + for (m = 0; m < board_size; m++) + for (n = 0; n < board_size; n++) + if (dragon[POS(m, n)].origin == POS(u, v)) + gtp_mprintf("%m ", m, n); + gtp_printf("\n"); + } + + gtp_printf("\n"); + return GTP_OK; } /* Function: Return the information in the eye data structure. @@ -4082,41 +3964,40 @@ gtp_dragon_stones(char *s) * Returns: eye data fields and values, one pair per row */ static int -gtp_eye_data(char *s) +gtp_eye_data(char* s) { - int color = EMPTY; - int i = -1; - int j = -1; - struct eye_data *e; + int color = EMPTY; + int i = -1; + int j = -1; + struct eye_data* e; - if (!gtp_decode_move(s, &color, &i, &j)) - return gtp_failure("invalid color or coordinate"); + if (!gtp_decode_move(s, &color, &i, &j)) + return gtp_failure("invalid color or coordinate"); - if (stackp > 0) - return gtp_failure("eye data unavailable when stackp > 0"); + if (stackp > 0) + return gtp_failure("eye data unavailable when stackp > 0"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - gtp_start_response(GTP_SUCCESS); + gtp_start_response(GTP_SUCCESS); - if (color == BLACK) - e = &black_eye[POS(i, j)]; - else - e = &white_eye[POS(i, j)]; - - gtp_mprintf("origin %m\n", I(e->origin), J(e->origin)); - gtp_mprintf("color %C\n", e->color); - gtp_printf("esize %d\n", e->esize); - gtp_printf("msize %d\n", e->msize); - gtp_printf("value %s\n", eyevalue_to_string(&e->value)); - gtp_printf("marginal %d\n", e->marginal); - gtp_printf("neighbors %d\n", e->neighbors); - gtp_printf("marginal_neighbors %d\n", e->marginal_neighbors); - - gtp_printf("\n"); - return GTP_OK; -} + if (color == BLACK) + e = &black_eye[POS(i, j)]; + else + e = &white_eye[POS(i, j)]; + gtp_mprintf("origin %m\n", I(e->origin), J(e->origin)); + gtp_mprintf("color %C\n", e->color); + gtp_printf("esize %d\n", e->esize); + gtp_printf("msize %d\n", e->msize); + gtp_printf("value %s\n", eyevalue_to_string(&e->value)); + gtp_printf("marginal %d\n", e->marginal); + gtp_printf("neighbors %d\n", e->neighbors); + gtp_printf("marginal_neighbors %d\n", e->marginal_neighbors); + + gtp_printf("\n"); + return GTP_OK; +} /* Function: Return the information in the half eye data structure. * Arguments: vertex @@ -4124,45 +4005,44 @@ gtp_eye_data(char *s) * Returns: half eye data fields and values, one pair per row */ static int -gtp_half_eye_data(char *s) +gtp_half_eye_data(char* s) { - int i = -1; - int j = -1; - struct half_eye_data *h; - int k; + int i = -1; + int j = -1; + struct half_eye_data* h; + int k; - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - if (stackp > 0) - return gtp_failure("half eye data unavailable when stackp > 0"); + if (stackp > 0) + return gtp_failure("half eye data unavailable when stackp > 0"); - silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); + silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); - gtp_start_response(GTP_SUCCESS); + gtp_start_response(GTP_SUCCESS); - h = &half_eye[POS(i, j)]; - - gtp_printf("value %.2f\n", h->value); - if (h->type == HALF_EYE) - gtp_printf("type HALF_EYE\n"); - else if (h->type == FALSE_EYE) - gtp_printf("type FALSE_EYE\n"); - else - gtp_printf("type %d\n", h->type); - gtp_printf("num_attacks %d\n", h->num_attacks); - for (k = 0; k < h->num_attacks; k++) - gtp_mprintf("attack_point[%d] %m\n", k, I(h->attack_point[k]), - J(h->attack_point[k])); - gtp_printf("num_defenses %d\n", h->num_defenses); - for (k = 0; k < h->num_defenses; k++) - gtp_mprintf("defense_point[%d] %m\n", k, I(h->defense_point[k]), - J(h->defense_point[k])); - - gtp_printf("\n"); - return GTP_OK; -} + h = &half_eye[POS(i, j)]; + gtp_printf("value %.2f\n", h->value); + if (h->type == HALF_EYE) + gtp_printf("type HALF_EYE\n"); + else if (h->type == FALSE_EYE) + gtp_printf("type FALSE_EYE\n"); + else + gtp_printf("type %d\n", h->type); + gtp_printf("num_attacks %d\n", h->num_attacks); + for (k = 0; k < h->num_attacks; k++) + gtp_mprintf("attack_point[%d] %m\n", k, I(h->attack_point[k]), + J(h->attack_point[k])); + gtp_printf("num_defenses %d\n", h->num_defenses); + for (k = 0; k < h->num_defenses; k++) + gtp_mprintf("defense_point[%d] %m\n", k, I(h->defense_point[k]), + J(h->defense_point[k])); + + gtp_printf("\n"); + return GTP_OK; +} static SGFTree gtp_sgftree; @@ -4176,15 +4056,14 @@ static SGFTree gtp_sgftree; * command. */ static int -gtp_start_sgftrace(char *s) +gtp_start_sgftrace(char* s) { - UNUSED(s); - sgffile_begindump(>p_sgftree); - count_variations = 1; - return gtp_success(""); + UNUSED(s); + sgffile_begindump(>p_sgftree); + count_variations = 1; + return gtp_success(""); } - /* Function: Finish storing moves in an sgf tree and write it to file. * Arguments: filename * Fails: never @@ -4194,20 +4073,19 @@ gtp_start_sgftrace(char *s) * command. */ static int -gtp_finish_sgftrace(char *s) +gtp_finish_sgftrace(char* s) { - char filename[GTP_BUFSIZE]; - int nread; - - nread = sscanf(s, "%s", filename); - if (nread < 1) - return gtp_failure("missing filename"); + char filename[GTP_BUFSIZE]; + int nread; - sgffile_enddump(filename); - count_variations = 0; - return gtp_success(""); -} + nread = sscanf(s, "%s", filename); + if (nread < 1) + return gtp_failure("missing filename"); + sgffile_enddump(filename); + count_variations = 0; + return gtp_success(""); +} /* Function: Dump the current position as a static sgf file to filename, * or as output if filename is missing or "-" @@ -4216,34 +4094,32 @@ gtp_finish_sgftrace(char *s) * Returns: nothing if filename, otherwise the sgf */ static int -gtp_printsgf(char *s) +gtp_printsgf(char* s) { - char filename[GTP_BUFSIZE]; - int nread; - int next; - - if (get_last_player() == EMPTY) - next = BLACK; - else - next = OTHER_COLOR(get_last_player()); + char filename[GTP_BUFSIZE]; + int nread; + int next; - nread = sscanf(s, "%s", filename); + if (get_last_player() == EMPTY) + next = BLACK; + else + next = OTHER_COLOR(get_last_player()); - if (nread < 1) - gg_snprintf(filename, GTP_BUFSIZE, "%s", "-"); + nread = sscanf(s, "%s", filename); - if (strcmp(filename, "-") == 0) { - gtp_start_response(GTP_SUCCESS); - sgffile_printsgf(next, filename); - gtp_printf("\n"); - return GTP_OK; - } - else { - sgffile_printsgf(next, filename); - return gtp_success(""); - } -} + if (nread < 1) + gg_snprintf(filename, GTP_BUFSIZE, "%s", "-"); + if (strcmp(filename, "-") == 0) { + gtp_start_response(GTP_SUCCESS); + sgffile_printsgf(next, filename); + gtp_printf("\n"); + return GTP_OK; + } else { + sgffile_printsgf(next, filename); + return gtp_success(""); + } +} /* Function: Tune the parameters for the move ordering in the tactical * reading. @@ -4252,23 +4128,23 @@ gtp_printsgf(char *s) * Returns: nothing */ static int -gtp_tune_move_ordering(char *s) +gtp_tune_move_ordering(char* s) { - int params[MOVE_ORDERING_PARAMETERS]; - int k; - int p; - int n; + int params[MOVE_ORDERING_PARAMETERS]; + int k; + int p; + int n; - for (k = 0; k < MOVE_ORDERING_PARAMETERS; k++) { - if (sscanf(s, "%d%n", &p, &n) == 0) - return gtp_failure("incorrect arguments, expected %d integers", - MOVE_ORDERING_PARAMETERS); - params[k] = p; - s += n; - } + for (k = 0; k < MOVE_ORDERING_PARAMETERS; k++) { + if (sscanf(s, "%d%n", &p, &n) == 0) + return gtp_failure("incorrect arguments, expected %d integers", + MOVE_ORDERING_PARAMETERS); + params[k] = p; + s += n; + } - tune_move_ordering(params); - return gtp_success(""); + tune_move_ordering(params); + return gtp_success(""); } /* Function: Echo the parameter @@ -4277,24 +4153,23 @@ gtp_tune_move_ordering(char *s) * Returns: nothing */ static int -gtp_echo(char *s) +gtp_echo(char* s) { - return gtp_success("%s", s); + return gtp_success("%s", s); } - /* Function: Echo the parameter to stdout AND stderr * Arguments: string * Fails: never * Returns: nothing */ static int -gtp_echo_err(char *s) +gtp_echo_err(char* s) { - fprintf(stderr, "%s", s); - fflush(gtp_output_file); - fflush(stderr); - return gtp_success("%s", s); + fprintf(stderr, "%s", s); + fflush(gtp_output_file); + fflush(stderr); + return gtp_success("%s", s); } /* Function: List all known commands @@ -4305,21 +4180,20 @@ gtp_echo_err(char *s) * Status: GTP version 2 standard command. */ static int -gtp_list_commands(char *s) +gtp_list_commands(char* s) { - int k; - UNUSED(s); + int k; + UNUSED(s); - gtp_start_response(GTP_SUCCESS); + gtp_start_response(GTP_SUCCESS); - for (k = 0; commands[k].name != NULL; k++) - gtp_printf("%s\n", commands[k].name); + for (k = 0; commands[k].name != NULL; k++) + gtp_printf("%s\n", commands[k].name); - gtp_printf("\n"); - return GTP_OK; + gtp_printf("\n"); + return GTP_OK; } - /* Function: Tell whether a command is known. * Arguments: command name * Fails: never @@ -4328,21 +4202,20 @@ gtp_list_commands(char *s) * Status: GTP version 2 standard command. */ static int -gtp_known_command(char *s) +gtp_known_command(char* s) { - int k; - char command[GTP_BUFSIZE]; + int k; + char command[GTP_BUFSIZE]; - if (sscanf(s, "%s", command) == 1) { - for (k = 0; commands[k].name != NULL; k++) - if (strcmp(command, commands[k].name) == 0) - return gtp_success("true"); - } + if (sscanf(s, "%s", command) == 1) { + for (k = 0; commands[k].name != NULL; k++) + if (strcmp(command, commands[k].name) == 0) + return gtp_success("true"); + } - return gtp_success("false"); + return gtp_success("false"); } - /* Function: Turn uncertainty reports from owl_attack * and owl_defend on or off. * Arguments: "on" or "off" @@ -4350,47 +4223,46 @@ gtp_known_command(char *s) * Returns: nothing */ static int -gtp_report_uncertainty(char *s) +gtp_report_uncertainty(char* s) { - if (!strncmp(s, "on", 2)) { - report_uncertainty = 1; - return gtp_success(""); - } - if (!strncmp(s, "off", 3)) { - report_uncertainty = 0; - return gtp_success(""); - } - return gtp_failure("invalid argument"); + if (!strncmp(s, "on", 2)) { + report_uncertainty = 1; + return gtp_success(""); + } + if (!strncmp(s, "off", 3)) { + report_uncertainty = 0; + return gtp_success(""); + } + return gtp_failure("invalid argument"); } - static void gtp_print_code(int c) { - static int conversion[6] = { - 0, /* LOSE */ - 3, /* KO_B */ - 5, /* LOSS */ - 4, /* GAIN */ - 2, /* KO_A */ - 1, /* WIN */ - }; - gtp_printf("%d", conversion[c]); + static int conversion[6] = { + 0, /* LOSE */ + 3, /* KO_B */ + 5, /* LOSS */ + 4, /* GAIN */ + 2, /* KO_A */ + 1, /* WIN */ + }; + gtp_printf("%d", conversion[c]); } static void -gtp_print_vertices2(int n, int *moves) +gtp_print_vertices2(int n, int* moves) { - int movei[MAX_BOARD * MAX_BOARD]; - int movej[MAX_BOARD * MAX_BOARD]; - int k; + int movei[MAX_BOARD * MAX_BOARD]; + int movej[MAX_BOARD * MAX_BOARD]; + int k; + + for (k = 0; k < n; k++) { + movei[k] = I(moves[k]); + movej[k] = J(moves[k]); + } - for (k = 0; k < n; k++) { - movei[k] = I(moves[k]); - movej[k] = J(moves[k]); - } - - gtp_print_vertices(n, movei, movej); + gtp_print_vertices(n, movei, movej); } /************* @@ -4398,18 +4270,17 @@ gtp_print_vertices2(int n, int *moves) *************/ static void -rotate_on_input(int ai, int aj, int *bi, int *bj) +rotate_on_input(int ai, int aj, int* bi, int* bj) { - rotate(ai, aj, bi, bj, board_size, gtp_orientation); + rotate(ai, aj, bi, bj, board_size, gtp_orientation); } static void -rotate_on_output(int ai, int aj, int *bi, int *bj) +rotate_on_output(int ai, int aj, int* bi, int* bj) { - inv_rotate(ai, aj, bi, bj, board_size, gtp_orientation); + inv_rotate(ai, aj, bi, bj, board_size, gtp_orientation); } - /*************** * random seed * ***************/ @@ -4420,10 +4291,10 @@ rotate_on_output(int ai, int aj, int *bi, int *bj) * Returns: random seed */ static int -gtp_get_random_seed(char *s) +gtp_get_random_seed(char* s) { - UNUSED(s); - return gtp_success("%d", get_random_seed()); + UNUSED(s); + return gtp_success("%d", get_random_seed()); } /* Function: Set the random seed @@ -4432,16 +4303,15 @@ gtp_get_random_seed(char *s) * Returns: nothing */ static int -gtp_set_random_seed(char *s) +gtp_set_random_seed(char* s) { - int seed; - if (sscanf(s, "%d", &seed) < 1) - return gtp_failure("invalid seed"); - - set_random_seed(seed); - return gtp_success(""); -} + int seed; + if (sscanf(s, "%d", &seed) < 1) + return gtp_failure("invalid seed"); + set_random_seed(seed); + return gtp_success(""); +} /* Function: Advance the random seed by a number of games. * Arguments: integer @@ -4449,18 +4319,18 @@ gtp_set_random_seed(char *s) * Returns: New random seed. */ static int -gtp_advance_random_seed(char *s) +gtp_advance_random_seed(char* s) { - int i; - int games; - if (sscanf(s, "%d", &games) < 1 - || games < 0) - return gtp_failure("invalid number of games"); - - for (i = 0; i < games; i++) - update_random_seed(); + int i; + int games; + if (sscanf(s, "%d", &games) < 1 + || games < 0) + return gtp_failure("invalid number of games"); + + for (i = 0; i < games; i++) + update_random_seed(); - return gtp_success("%d", get_random_seed()); + return gtp_success("%d", get_random_seed()); } /*************** @@ -4473,20 +4343,20 @@ gtp_advance_random_seed(char *s) * Returns: 1 if surrounded, 2 if weakly surrounded, 0 if not */ static int -gtp_is_surrounded(char *s) +gtp_is_surrounded(char* s) { - int i, j; - int n; + int i, j; + int n; - n = gtp_decode_coord(s, &i, &j); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &i, &j); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(i, j) == EMPTY) - return gtp_failure("dragon vertex must be nonempty"); + if (BOARD(i, j) == EMPTY) + return gtp_failure("dragon vertex must be nonempty"); - silent_examine_position(EXAMINE_DRAGONS); - return gtp_success("%d", DRAGON2(POS(i, j)).surround_status); + silent_examine_position(EXAMINE_DRAGONS); + return gtp_success("%d", DRAGON2(POS(i, j)).surround_status); } /* Function: Determine if a move surrounds a dragon @@ -4495,27 +4365,27 @@ gtp_is_surrounded(char *s) * Returns: 1 if (move) surrounds (dragon) */ static int -gtp_does_surround(char *s) +gtp_does_surround(char* s) { - int si, sj, di, dj; - int n; + int si, sj, di, dj; + int n; - n = gtp_decode_coord(s, &si, &sj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &si, &sj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(si, sj) != EMPTY) - return gtp_failure("move vertex must be empty"); + if (BOARD(si, sj) != EMPTY) + return gtp_failure("move vertex must be empty"); - n = gtp_decode_coord(s + n, &di, &dj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s + n, &di, &dj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(di, dj) == EMPTY) - return gtp_failure("dragon vertex must be nonempty"); + if (BOARD(di, dj) == EMPTY) + return gtp_failure("dragon vertex must be nonempty"); - silent_examine_position(EXAMINE_DRAGONS); - return gtp_success("%d", does_surround(POS(si, sj), POS(di, dj))); + silent_examine_position(EXAMINE_DRAGONS); + return gtp_success("%d", does_surround(POS(si, sj), POS(di, dj))); } /* Function: Report the surround map for dragon at a vertex @@ -4526,24 +4396,24 @@ gtp_does_surround(char *s) */ static int -gtp_surround_map(char *s) +gtp_surround_map(char* s) { - int di, dj, mi, mj; - int n; + int di, dj, mi, mj; + int n; - n = gtp_decode_coord(s, &di, &dj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s, &di, &dj); + if (n == 0) + return gtp_failure("invalid coordinate"); - if (BOARD(di, dj) == EMPTY) - return gtp_failure("dragon vertex must not be empty"); + if (BOARD(di, dj) == EMPTY) + return gtp_failure("dragon vertex must not be empty"); - n = gtp_decode_coord(s + n, &mi, &mj); - if (n == 0) - return gtp_failure("invalid coordinate"); + n = gtp_decode_coord(s + n, &mi, &mj); + if (n == 0) + return gtp_failure("invalid coordinate"); - silent_examine_position(EXAMINE_DRAGONS); - return gtp_success("%d", surround_map(POS(di, dj), POS(mi, mj))); + silent_examine_position(EXAMINE_DRAGONS); + return gtp_success("%d", surround_map(POS(di, dj), POS(mi, mj))); } /*************** @@ -4556,16 +4426,16 @@ gtp_surround_map(char *s) * Returns: nothing */ static int -gtp_set_search_diamond(char *s) +gtp_set_search_diamond(char* s) { - int i, j; + int i, j; + + if (!gtp_decode_coord(s, &i, &j)) + return gtp_failure("invalid coordinate"); - if (!gtp_decode_coord(s, &i, &j)) - return gtp_failure("invalid coordinate"); - - set_limit_search(1); - set_search_diamond(POS(i, j)); - return gtp_success(""); + set_limit_search(1); + set_search_diamond(POS(i, j)); + return gtp_success(""); } /* Function: unmark the entire board for limited search @@ -4574,28 +4444,28 @@ gtp_set_search_diamond(char *s) * Returns: nothing */ static int -gtp_reset_search_mask(char *s) +gtp_reset_search_mask(char* s) { - UNUSED(s); + UNUSED(s); - reset_search_mask(); - return gtp_success(""); + reset_search_mask(); + return gtp_success(""); } - + /* Function: sets the global variable limit_search * Arguments: value * Fails: invalid arguments * Returns: nothing */ static int -gtp_limit_search(char *s) +gtp_limit_search(char* s) { - int value; + int value; - if (sscanf(s, "%d", &value) < 1) - return gtp_failure("invalid value for search limit"); - set_limit_search(value); - return gtp_success(""); + if (sscanf(s, "%d", &value) < 1) + return gtp_failure("invalid value for search limit"); + set_limit_search(value); + return gtp_success(""); } /* Function: mark a vertex for limited search @@ -4604,36 +4474,34 @@ gtp_limit_search(char *s) * Returns: nothing */ static int -gtp_set_search_limit(char *s) +gtp_set_search_limit(char* s) { - int i, j; + int i, j; - gtp_decode_coord(s, &i, &j); - set_search_mask(POS(i, j), 1); - return gtp_success(""); + gtp_decode_coord(s, &i, &j); + set_search_mask(POS(i, j), 1); + return gtp_success(""); } - + /* Function: Draw search area. Writes to stderr. * Arguments: none * Fails: never * Returns: nothing */ static int -gtp_draw_search_area(char *s) +gtp_draw_search_area(char* s) { - UNUSED(s); + UNUSED(s); - gtp_start_response(GTP_SUCCESS); - gtp_printf("\n"); - draw_search_area(); - return gtp_finish_response(); + gtp_start_response(GTP_SUCCESS); + gtp_printf("\n"); + draw_search_area(); + return gtp_finish_response(); } - - /* * Local Variables: - * tab-width: 8 - * c-basic-offset: 2 + * tab-width: 4 + * c-basic-offset: 4 * End: */ diff --git a/interface/play_solo.c b/interface/play_solo.c index cf210c6..8a1265a 100644 --- a/interface/play_solo.c +++ b/interface/play_solo.c @@ -23,152 +23,146 @@ #include "gnugo.h" +#include #include #include #include -#include #include "interface.h" #include "liberty.h" /* to get to the stats */ -#include "sgftree.h" -#include "random.h" #include "gg_utils.h" +#include "random.h" +#include "sgftree.h" -void -play_solo(Gameinfo *gameinfo, int moves) +void play_solo(Gameinfo* gameinfo, int moves) { - SGFTree sgftree; - int passes = 0; /* num. consecutive passes */ - float move_value; - double t1, t2; - int save_moves = moves; + SGFTree sgftree; + int passes = 0; /* num. consecutive passes */ + float move_value; + double t1, t2; + int save_moves = moves; - struct stats_data totalstats; - int total_owl_count = 0; + struct stats_data totalstats; + int total_owl_count = 0; - /* It tends not to be very imaginative in the opening, + /* It tends not to be very imaginative in the opening, * so we scatter a few stones randomly to start with. * We add two random numbers to reduce the probability * of playing stones near the edge. */ - - int n = 6 + 2*gg_rand()%5; - int i, j; - - komi = 5.5; - - sgftree_clear(&sgftree); - sgftreeCreateHeaderNode(&sgftree, board_size, komi, handicap); - sgf_write_header(sgftree.root, 1, get_random_seed(), 5.5, handicap, - get_level(), chinese_rules); - - /* Generate some random moves. */ - if (board_size > 6) { - do { - do { - i = (gg_rand() % 4) + (gg_rand() % (board_size - 4)); - j = (gg_rand() % 4) + (gg_rand() % (board_size - 4)); - } while (!is_allowed_move(POS(i, j), gameinfo->to_move)); - - gnugo_play_move(POS(i, j), gameinfo->to_move); - sgftreeAddPlay(&sgftree, gameinfo->to_move, i, j); - sgftreeAddComment(&sgftree, "random move"); - gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); - } while (--n > 0); - } - - t1 = gg_cputime(); - memset(&totalstats, '\0', sizeof(totalstats)); - while (passes < 2 && --moves >= 0) { - int move; - reset_owl_node_counter(); - move = genmove(gameinfo->to_move, &move_value, NULL); - gnugo_play_move(move, gameinfo->to_move); - sgffile_add_debuginfo(sgftree.lastnode, move_value); - sgftreeAddPlay(&sgftree, gameinfo->to_move, I(move), J(move)); - sgffile_output(&sgftree); - gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); + int n = 6 + 2 * gg_rand() % 5; + int i, j; + + komi = 5.5; + + sgftree_clear(&sgftree); + sgftreeCreateHeaderNode(&sgftree, board_size, komi, handicap); + sgf_write_header(sgftree.root, 1, get_random_seed(), 5.5, handicap, + get_level(), chinese_rules); + + /* Generate some random moves. */ + if (board_size > 6) { + do { + do { + i = (gg_rand() % 4) + (gg_rand() % (board_size - 4)); + j = (gg_rand() % 4) + (gg_rand() % (board_size - 4)); + } while (!is_allowed_move(POS(i, j), gameinfo->to_move)); + + gnugo_play_move(POS(i, j), gameinfo->to_move); + sgftreeAddPlay(&sgftree, gameinfo->to_move, i, j); + sgftreeAddComment(&sgftree, "random move"); + gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); + } while (--n > 0); + } - if (move == PASS_MOVE) { - passes++; - printf("%s(%d): Pass\n", gameinfo->to_move == BLACK ? "Black" : "White", - movenum); + t1 = gg_cputime(); + memset(&totalstats, '\0', sizeof(totalstats)); + while (passes < 2 && --moves >= 0) { + int move; + reset_owl_node_counter(); + move = genmove(gameinfo->to_move, &move_value, NULL); + + gnugo_play_move(move, gameinfo->to_move); + sgffile_add_debuginfo(sgftree.lastnode, move_value); + sgftreeAddPlay(&sgftree, gameinfo->to_move, I(move), J(move)); + sgffile_output(&sgftree); + gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); + + if (move == PASS_MOVE) { + passes++; + printf("%s(%d): Pass\n", gameinfo->to_move == BLACK ? "Black" : "White", + movenum); + } else { + passes = 0; + gprintf("%s(%d): %1m\n", gameinfo->to_move == BLACK ? "Black" : "White", + movenum, move); + } + + totalstats.nodes += stats.nodes; + totalstats.read_result_entered += stats.read_result_entered; + totalstats.read_result_hits += stats.read_result_hits; + totalstats.trusted_read_result_hits += stats.trusted_read_result_hits; + total_owl_count += get_owl_node_counter(); } - else { - passes = 0; - gprintf("%s(%d): %1m\n", gameinfo->to_move == BLACK ? "Black" : "White", - movenum, move); + t2 = gg_cputime(); + + /* Two passes and it's over. (EMPTY == BOTH) */ + who_wins(EMPTY, stdout); + + { + float score = gnugo_estimate_score(NULL, NULL); + sgfWriteResult(sgftree.root, score, 1); } + sgffile_output(&sgftree); - totalstats.nodes += stats.nodes; - totalstats.read_result_entered += stats.read_result_entered; - totalstats.read_result_hits += stats.read_result_hits; - totalstats.trusted_read_result_hits += stats.trusted_read_result_hits; - total_owl_count += get_owl_node_counter(); - } - t2 = gg_cputime(); - - /* Two passes and it's over. (EMPTY == BOTH) */ - who_wins(EMPTY, stdout); - - { - float score = gnugo_estimate_score(NULL, NULL); - sgfWriteResult(sgftree.root, score, 1); - } - sgffile_output(&sgftree); - - printf("%10d moves played in %0.3f seconds\n", save_moves-moves, t2-t1); - if (save_moves != moves) - printf("%10.3f seconds/move\n", (t2-t1)/(save_moves-moves)); - - printf("%10d nodes\n", totalstats.nodes); - printf("%10d read results entered\n", totalstats.read_result_entered); - printf("%10d read result hits\n", totalstats.read_result_hits); - printf("%10d trusted read result hits\n", - totalstats.trusted_read_result_hits); - printf("%10d owl nodes\n", total_owl_count); -} + printf("%10d moves played in %0.3f seconds\n", save_moves - moves, t2 - t1); + if (save_moves != moves) + printf("%10.3f seconds/move\n", (t2 - t1) / (save_moves - moves)); + printf("%10d nodes\n", totalstats.nodes); + printf("%10d read results entered\n", totalstats.read_result_entered); + printf("%10d read result hits\n", totalstats.read_result_hits); + printf("%10d trusted read result hits\n", + totalstats.trusted_read_result_hits); + printf("%10d owl nodes\n", total_owl_count); +} /* ================================================================ */ - /* * Load SGF file and run genmove(). */ -void -load_and_analyze_sgf_file(Gameinfo *gameinfo) +void load_and_analyze_sgf_file(Gameinfo* gameinfo) { - SGFTree sgftree; - int move; - int next; - float move_value; - - next = gameinfo->to_move; - sgftree = gameinfo->game_record; - - if (metamachine) - sgffile_begindump(&sgftree); - - move = genmove(next, &move_value, NULL); - - gprintf("%s move %1m\n", next == WHITE ? "white (O)" : "black (X)", move); - - if (metamachine) - sgffile_enddump(outfilename); - else { - gnugo_play_move(move, next); - sgftreeAddPlay(&sgftree, next, I(move), J(move)); - sgftreeAddComment(&sgftree, "load and analyze mode"); - sgffile_add_debuginfo(sgftree.lastnode, move_value); - sgffile_output(&sgftree); - } -} + SGFTree sgftree; + int move; + int next; + float move_value; + + next = gameinfo->to_move; + sgftree = gameinfo->game_record; + + if (metamachine) + sgffile_begindump(&sgftree); + move = genmove(next, &move_value, NULL); + + gprintf("%s move %1m\n", next == WHITE ? "white (O)" : "black (X)", move); + + if (metamachine) + sgffile_enddump(outfilename); + else { + gnugo_play_move(move, next); + sgftreeAddPlay(&sgftree, next, I(move), J(move)); + sgftreeAddComment(&sgftree, "load and analyze mode"); + sgffile_add_debuginfo(sgftree.lastnode, move_value); + sgffile_output(&sgftree); + } +} /* * Load SGF file and score the game @@ -179,103 +173,99 @@ load_and_analyze_sgf_file(Gameinfo *gameinfo) * get an accurate score */ -#define ESTIMATE 0 -#define FINISH 1 +#define ESTIMATE 0 +#define FINISH 1 #define AFTERMATH 2 -void -load_and_score_sgf_file(SGFTree *tree, Gameinfo *gameinfo, - const char *scoringmode) +void load_and_score_sgf_file(SGFTree* tree, Gameinfo* gameinfo, + const char* scoringmode) { - int move; - float move_value; - char *tempc = NULL; - char text[250]; - char winner; - int next; - int pass = 0; - int method; - float score; - SGFTree local_tree; - SGFTree *score_tree = tree; - - /* Default scoring method is ESTIMATE since it's fastest. */ - method = ESTIMATE; - if (strcmp(scoringmode, "finish") == 0) - method = FINISH; - else if (strcmp(scoringmode, "aftermath") == 0) - method = AFTERMATH; - - /* For aftermath scoring we compress the previous moves to a static + int move; + float move_value; + char* tempc = NULL; + char text[250]; + char winner; + int next; + int pass = 0; + int method; + float score; + SGFTree local_tree; + SGFTree* score_tree = tree; + + /* Default scoring method is ESTIMATE since it's fastest. */ + method = ESTIMATE; + if (strcmp(scoringmode, "finish") == 0) + method = FINISH; + else if (strcmp(scoringmode, "aftermath") == 0) + method = AFTERMATH; + + /* For aftermath scoring we compress the previous moves to a static * board position in the output sgf. This helps a lot when debugging * scoring mistakes. We don't do this for the finish method, * however, since users may be better served by having GNU Go's * selfplay added to the original game record. */ - if (method == AFTERMATH) { - sgftree_clear(&local_tree); - /* Modify komi to compensate for captured stones. We start at a + if (method == AFTERMATH) { + sgftree_clear(&local_tree); + /* Modify komi to compensate for captured stones. We start at a * setup position and since there is no standard sgf property to * tell the number of captured stones, a modified komi is the best * available solution. */ - sgftreeCreateHeaderNode(&local_tree, board_size, - komi + black_captured - white_captured, handicap); - sgffile_printboard(&local_tree); - sgfAddProperty(local_tree.lastnode, "PL", - gameinfo->to_move == WHITE ? "W" : "B"); - score_tree = &local_tree; - } - - next = gameinfo->to_move; - reset_engine(); - - /* Complete the game by selfplay for the finish and aftermath methods. */ - if (method != ESTIMATE) { - doing_scoring = 1; - while (pass < 2) { - move = genmove_conservative(next, &move_value); - if (move != PASS_MOVE) { - pass = 0; - gprintf("%d %s move %1m\n", movenum, - next == WHITE ? "white (O)" : "black (X)", move); - } - else { - pass++; - gprintf("%d %s move PASS\n", movenum, - next == WHITE ? "white (O)" : "black (X)"); - } - play_move(move, next); - sgffile_add_debuginfo(score_tree->lastnode, move_value); - sgftreeAddPlay(score_tree, next, I(move), J(move)); - sgffile_output(score_tree); - next = OTHER_COLOR(next); + sgftreeCreateHeaderNode(&local_tree, board_size, + komi + black_captured - white_captured, handicap); + sgffile_printboard(&local_tree); + sgfAddProperty(local_tree.lastnode, "PL", + gameinfo->to_move == WHITE ? "W" : "B"); + score_tree = &local_tree; } - doing_scoring = 0; - } - - /* Calculate the score. */ - if (method == AFTERMATH) - score = aftermath_compute_score(next, score_tree); - else - score = gnugo_estimate_score(NULL, NULL); - - if (score < 0.0) { - sprintf(text, "Black wins by %1.1f points\n", -score); - winner = 'B'; - } - else if (score > 0.0) { - sprintf(text, "White wins by %1.1f points\n", score); - winner = 'W'; - } - else { - sprintf(text, "Jigo\n"); - winner = '0'; - } - fputs(text, stdout); - sgftreeAddComment(score_tree, text); - - /* For the finish and aftermath methods we compare the score with + + next = gameinfo->to_move; + reset_engine(); + + /* Complete the game by selfplay for the finish and aftermath methods. */ + if (method != ESTIMATE) { + doing_scoring = 1; + while (pass < 2) { + move = genmove_conservative(next, &move_value); + if (move != PASS_MOVE) { + pass = 0; + gprintf("%d %s move %1m\n", movenum, + next == WHITE ? "white (O)" : "black (X)", move); + } else { + pass++; + gprintf("%d %s move PASS\n", movenum, + next == WHITE ? "white (O)" : "black (X)"); + } + play_move(move, next); + sgffile_add_debuginfo(score_tree->lastnode, move_value); + sgftreeAddPlay(score_tree, next, I(move), J(move)); + sgffile_output(score_tree); + next = OTHER_COLOR(next); + } + doing_scoring = 0; + } + + /* Calculate the score. */ + if (method == AFTERMATH) + score = aftermath_compute_score(next, score_tree); + else + score = gnugo_estimate_score(NULL, NULL); + + if (score < 0.0) { + sprintf(text, "Black wins by %1.1f points\n", -score); + winner = 'B'; + } else if (score > 0.0) { + sprintf(text, "White wins by %1.1f points\n", score); + winner = 'W'; + } else { + sprintf(text, "Jigo\n"); + winner = '0'; + } + fputs(text, stdout); + sgftreeAddComment(score_tree, text); + + /* For the finish and aftermath methods we compare the score with * what's stored in the game record. * * FIXME: No comparison is made if the stored result was 0. Wins by @@ -284,40 +274,38 @@ load_and_score_sgf_file(SGFTree *tree, Gameinfo *gameinfo, * FIXME: Does anybody actually care about this information? Just * removing this piece of code is a tempting alternative. */ - if (method != ESTIMATE && sgfGetCharProperty(tree->root, "RE", &tempc)) { - char dummy; - float result; - if (sscanf(tempc, "%1c%f", &dummy, &result) == 2) { - fprintf(stdout, "Result from file: %c+%1.1f\n", dummy, result); - fputs("GNU Go result and result from file are ", stdout); - if (result == fabs(score) && winner == dummy) - fputs("identical\n", stdout); - else - fputs("different\n", stdout); - + if (method != ESTIMATE && sgfGetCharProperty(tree->root, "RE", &tempc)) { + char dummy; + float result; + if (sscanf(tempc, "%1c%f", &dummy, &result) == 2) { + fprintf(stdout, "Result from file: %c+%1.1f\n", dummy, result); + fputs("GNU Go result and result from file are ", stdout); + if (result == fabs(score) && winner == dummy) + fputs("identical\n", stdout); + else + fputs("different\n", stdout); + + } else { + if (tempc[2] == 'R') { + fprintf(stdout, "Result from file: Resign\n"); + fputs("GNU Go result and result from file are ", stdout); + if (tempc[0] == winner) + fputs("identical\n", stdout); + else + fputs("different\n", stdout); + } + } } - else { - if (tempc[2] == 'R') { - fprintf(stdout, "Result from file: Resign\n"); - fputs("GNU Go result and result from file are ", stdout); - if (tempc[0] == winner) - fputs("identical\n", stdout); - else - fputs("different\n", stdout); - } - } - } - if (method != ESTIMATE) - sgfWriteResult(score_tree->root, score, 1); - - sgffile_output(score_tree); -} + if (method != ESTIMATE) + sgfWriteResult(score_tree->root, score, 1); + sgffile_output(score_tree); +} /* * Local Variables: - * tab-width: 8 - * c-basic-offset: 2 + * tab-width: 4 + * c-basic-offset: 4 * End: */ diff --git a/interface/play_test.c b/interface/play_test.c index eb07321..09ad964 100644 --- a/interface/play_test.c +++ b/interface/play_test.c @@ -23,86 +23,83 @@ #include "gnugo.h" +#include #include #include #include -#include -#include "interface.h" -#include "sgftree.h" #include "gg_utils.h" +#include "interface.h" #include "liberty.h" +#include "sgftree.h" -static void replay_node(SGFNode *node, int color_to_test, float *replay_score, - float *total_score); - +static void replay_node(SGFNode* node, int color_to_test, float* replay_score, + float* total_score); /* --------------------------------------------------------------*/ /* replay a game */ /* --------------------------------------------------------------*/ -void -play_replay(SGFTree *tree, int color_to_replay) +void play_replay(SGFTree* tree, int color_to_replay) { - char *tmpc = NULL; - float replay_score = 0.0; - float total_score = 0.0; + char* tmpc = NULL; + float replay_score = 0.0; + float total_score = 0.0; - SGFNode *node = tree->root; + SGFNode* node = tree->root; - /* Board size and komi are already set up correctly since the game + /* Board size and komi are already set up correctly since the game * has already been loaded before this function is called. Now we * only have to clear the board before starting over. */ - clear_board(); - - if (!quiet) { - printf("Board Size: %d\n", board_size); - if (sgfGetCharProperty(node, "HA", &tmpc)) - printf("Handicap: %s\n", tmpc); - printf("Komi: %.1f\n", komi); - if (sgfGetCharProperty(node, "RU", &tmpc)) - printf("Ruleset: %s\n", tmpc); - if (sgfGetCharProperty(node, "GN", &tmpc)) - printf("Game Name: %s\n", tmpc); - if (sgfGetCharProperty(node, "DT", &tmpc)) - printf("Game Date: %s\n", tmpc); - if (sgfGetCharProperty(node, "GC", &tmpc)) - printf("Game Comment: %s\n", tmpc); - if (sgfGetCharProperty(node, "US", &tmpc)) - printf("Game User: %s\n", tmpc); - if (sgfGetCharProperty(node, "PB", &tmpc)) - printf("Black Player: %s\n", tmpc); - if (sgfGetCharProperty(node, "PW", &tmpc)) - printf("White Player: %s\n", tmpc); - if (sgfGetCharProperty(node, "RE", &tmpc)) - printf("Result: %s\n", tmpc); - } - - /* + clear_board(); + + if (!quiet) { + printf("Board Size: %d\n", board_size); + if (sgfGetCharProperty(node, "HA", &tmpc)) + printf("Handicap: %s\n", tmpc); + printf("Komi: %.1f\n", komi); + if (sgfGetCharProperty(node, "RU", &tmpc)) + printf("Ruleset: %s\n", tmpc); + if (sgfGetCharProperty(node, "GN", &tmpc)) + printf("Game Name: %s\n", tmpc); + if (sgfGetCharProperty(node, "DT", &tmpc)) + printf("Game Date: %s\n", tmpc); + if (sgfGetCharProperty(node, "GC", &tmpc)) + printf("Game Comment: %s\n", tmpc); + if (sgfGetCharProperty(node, "US", &tmpc)) + printf("Game User: %s\n", tmpc); + if (sgfGetCharProperty(node, "PB", &tmpc)) + printf("Black Player: %s\n", tmpc); + if (sgfGetCharProperty(node, "PW", &tmpc)) + printf("White Player: %s\n", tmpc); + if (sgfGetCharProperty(node, "RE", &tmpc)) + printf("Result: %s\n", tmpc); + } + + /* * Now actually run through the file. This is the interesting part. * We need to traverse the SGF tree, and every time we encounter a node * we need to check what move GNU Go would make, and see if it is OK. */ - while (node) { - replay_node(node, color_to_replay, &replay_score, &total_score); - sgffile_output(tree); - node = node->child; - } - - if (!quiet) - printf("Global score: %.2f / %.2f\n", replay_score, total_score); - - if (showtime) { - gprintf("SLOWEST MOVE: %d at %1m ", slowest_movenum, slowest_move); - fprintf(stderr, "(%.2f seconds)\n", slowest_time); - fprintf(stderr, "AVERAGE TIME: %.2f seconds per move\n", - total_time / movenum); - fprintf(stderr, "TOTAL TIME: %.2f seconds\n", - total_time); - } -} + while (node) { + replay_node(node, color_to_replay, &replay_score, &total_score); + sgffile_output(tree); + node = node->child; + } + if (!quiet) + printf("Global score: %.2f / %.2f\n", replay_score, total_score); + + if (showtime) { + gprintf("SLOWEST MOVE: %d at %1m ", slowest_movenum, slowest_move); + fprintf(stderr, "(%.2f seconds)\n", slowest_time); + fprintf(stderr, "AVERAGE TIME: %.2f seconds per move\n", + total_time / movenum); + fprintf(stderr, "TOTAL TIME: %.2f seconds\n", + total_time); + } +} #define BUFSIZE 128 @@ -111,110 +108,108 @@ play_replay(SGFTree *tree, int color_to_replay) */ static void -replay_node(SGFNode *node, int color_to_replay, float *replay_score, - float *total_score) +replay_node(SGFNode* node, int color_to_replay, float* replay_score, + float* total_score) { - SGFProperty *sgf_prop; /* iterate over properties of the node */ - SGFProperty *move_prop = NULL; /* remember if we see a move property */ - int color; /* color of move to be made at this node. */ - - int old_move; /* The move played in the file. */ - int new_move; /* The move generated by GNU Go. */ + SGFProperty* sgf_prop; /* iterate over properties of the node */ + SGFProperty* move_prop = NULL; /* remember if we see a move property */ + int color; /* color of move to be made at this node. */ + + int old_move; /* The move played in the file. */ + int new_move; /* The move generated by GNU Go. */ - char buf[BUFSIZE]; + char buf[BUFSIZE]; - /* Handle any AB / AW properties, and note presence + /* Handle any AB / AW properties, and note presence * of move properties. */ - for (sgf_prop = node->props; sgf_prop; sgf_prop = sgf_prop->next) { - switch (sgf_prop->name) { - case SGFAB: - /* add black */ - add_stone(get_sgfmove(sgf_prop), BLACK); - break; - case SGFAW: - /* add white */ - add_stone(get_sgfmove(sgf_prop), WHITE); - break; - case SGFB: - case SGFW: - move_prop = sgf_prop; /* remember it for later */ - break; + for (sgf_prop = node->props; sgf_prop; sgf_prop = sgf_prop->next) { + switch (sgf_prop->name) { + case SGFAB: + /* add black */ + add_stone(get_sgfmove(sgf_prop), BLACK); + break; + case SGFAW: + /* add white */ + add_stone(get_sgfmove(sgf_prop), WHITE); + break; + case SGFB: + case SGFW: + move_prop = sgf_prop; /* remember it for later */ + break; + } } - } - - /* Only generate moves at move nodes. */ - if (!move_prop) - return; - - old_move = get_sgfmove(move_prop); - color = (move_prop->name == SGFW) ? WHITE : BLACK; - - if (color == color_to_replay || color_to_replay == GRAY) { - float new_move_value = 0.0; - float old_move_value = 0.0; - - /* Get a move from the engine for color. */ - int resign; - new_move = genmove(color, NULL, &resign); - - /* Pick up the relevant values from the potential_moves[] array. */ - if (new_move != PASS_MOVE) - new_move_value = potential_moves[new_move]; - if (old_move != PASS_MOVE) - old_move_value = potential_moves[old_move]; - - /* Now report on how well the computer generated the move. */ - if (new_move != old_move || !quiet) { - mprintf("Move %d (%C): ", movenum + 1, color); - - if (resign) - printf("GNU Go resigns "); - else { - mprintf("GNU Go plays %1m ", new_move); - if (new_move != PASS_MOVE) - printf("(%.2f) ", new_move_value); - } - - mprintf("- Game move %1m ", old_move); - if (new_move != PASS_MOVE && old_move_value > 0.0) - printf("(%.2f) ", old_move_value); - printf("\n"); - - *replay_score += new_move_value - old_move_value; - *total_score += new_move_value; - } - - if (new_move != old_move) { - if (resign) - gg_snprintf(buf, BUFSIZE, "GNU Go resigns - Game move %s (%.2f)", - location_to_string(old_move), old_move_value); - else { - gg_snprintf(buf, BUFSIZE, - "GNU Go plays %s (%.2f) - Game move %s (%.2f)", - location_to_string(new_move), new_move_value, - location_to_string(old_move), old_move_value); - if (new_move != PASS_MOVE) - sgfCircle(node, I(new_move), J(new_move)); - } + + /* Only generate moves at move nodes. */ + if (!move_prop) + return; + + old_move = get_sgfmove(move_prop); + color = (move_prop->name == SGFW) ? WHITE : BLACK; + + if (color == color_to_replay || color_to_replay == GRAY) { + float new_move_value = 0.0; + float old_move_value = 0.0; + + /* Get a move from the engine for color. */ + int resign; + new_move = genmove(color, NULL, &resign); + + /* Pick up the relevant values from the potential_moves[] array. */ + if (new_move != PASS_MOVE) + new_move_value = potential_moves[new_move]; + if (old_move != PASS_MOVE) + old_move_value = potential_moves[old_move]; + + /* Now report on how well the computer generated the move. */ + if (new_move != old_move || !quiet) { + mprintf("Move %d (%C): ", movenum + 1, color); + + if (resign) + printf("GNU Go resigns "); + else { + mprintf("GNU Go plays %1m ", new_move); + if (new_move != PASS_MOVE) + printf("(%.2f) ", new_move_value); + } + + mprintf("- Game move %1m ", old_move); + if (new_move != PASS_MOVE && old_move_value > 0.0) + printf("(%.2f) ", old_move_value); + printf("\n"); + + *replay_score += new_move_value - old_move_value; + *total_score += new_move_value; + } + + if (new_move != old_move) { + if (resign) + gg_snprintf(buf, BUFSIZE, "GNU Go resigns - Game move %s (%.2f)", + location_to_string(old_move), old_move_value); + else { + gg_snprintf(buf, BUFSIZE, + "GNU Go plays %s (%.2f) - Game move %s (%.2f)", + location_to_string(new_move), new_move_value, + location_to_string(old_move), old_move_value); + if (new_move != PASS_MOVE) + sgfCircle(node, I(new_move), J(new_move)); + } + } else + gg_snprintf(buf, BUFSIZE, "GNU Go plays the same move %s (%.2f)", + location_to_string(new_move), new_move_value); + + sgfAddComment(node, buf); + sgffile_add_debuginfo(node, 0.0); } - else - gg_snprintf(buf, BUFSIZE, "GNU Go plays the same move %s (%.2f)", - location_to_string(new_move), new_move_value); - - sgfAddComment(node, buf); - sgffile_add_debuginfo(node, 0.0); - } - - /* Finally, do play the move from the file. */ - play_move(old_move, color); -} + /* Finally, do play the move from the file. */ + play_move(old_move, color); +} /* * Local Variables: - * tab-width: 8 - * c-basic-offset: 2 + * tab-width: 4 + * c-basic-offset: 4 * End: */ -- 2.20.1