Initial commit of GNU Go v3.8.
[sgk-go] / interface / gtp_examples / gtp2_6
This patch to GNU Go 2.6 allows it to play with the Go Text Protocol.
diff -u -N -r -x *\.orig -x *\.info* ./configure.in ../gnugo-2.6.1/gnugo-2.6.1/configure.in
--- ./configure.in Sun Feb 13 03:02:11 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/configure.in Sat Aug 4 00:10:58 2001
@@ -8,7 +8,7 @@
AC_PREREQ(2.12)dnl dnl Minimum Autoconf version required.
dnl this defines VERSION and PACKAGE
-AM_INIT_AUTOMAKE([gnugo], [2.6])
+AM_INIT_AUTOMAKE([gnugo], [2.6.1])
GNU_PACKAGE="GNU $PACKAGE"
AC_DEFINE_UNQUOTED(GNU_PACKAGE, "$GNU_PACKAGE")
diff -u -N -r -x *\.orig -x *\.info* ./engine/liberty.h ../gnugo-2.6.1/gnugo-2.6.1/engine/liberty.h
--- ./engine/liberty.h Tue Feb 8 19:59:07 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/engine/liberty.h Fri Aug 10 16:20:09 2001
@@ -53,6 +53,7 @@
#define WHITE 1
#define BLACK 2
#define GRAY_BORDER 3
+#define GRAY 3
#define WHITE_BORDER 4
#define BLACK_BORDER 5
#define NONE 6 /* for use with is_computer_player */
@@ -138,8 +139,7 @@
void restore_state(void);
int dragon_status(int i, int j);
void change_dragon_status(int x, int y, int status);
-
-void who_wins(int color, float fkomi, FILE* stdwhat);
+void who_wins(int color, float fkomi, FILE * stdwhat);
/* data concerning a dragon. A copy is kept at each stone of the string */
@@ -362,6 +362,7 @@
void find_cuts(void);
void find_connections(void);
void endgame(void);
+float estimate_score(float komi);
/* various different strategies for finding a move */
diff -u -N -r -x *\.orig -x *\.info* ./engine/moyo.c ../gnugo-2.6.1/gnugo-2.6.1/engine/moyo.c
--- ./engine/moyo.c Tue Feb 8 19:59:07 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/engine/moyo.c Fri Aug 10 16:21:10 2001
@@ -2489,6 +2489,20 @@
fprintf(stdwhat, "%c says \"I lost!\"\n", (color == WHITE) ? 'W' : 'B');
}
+float
+estimate_score(float fkomi)
+{
+ float white_score;
+ float black_score;
+ float result;
+
+ make_moyo(BLACK);
+ white_score = (float) terri_eval[WHITE] + fkomi;
+ black_score = (float) terri_eval[BLACK];
+ result = white_score - black_score;
+ return result;
+}
+
void
diff -u -N -r -x *\.orig -x *\.info* ./engine/reading.c ../gnugo-2.6.1/gnugo-2.6.1/engine/reading.c
--- ./engine/reading.c Tue Feb 8 19:59:07 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/engine/reading.c Sat Aug 4 00:10:58 2001
@@ -2732,9 +2732,6 @@
{
int safe=0;
- if (stackp == 0 && safe_move_cache_when[i][j][color==BLACK] == movenum)
- return safe_move_cache[i][j][color==BLACK];
-
if (trymove(i, j, color, "safe_move", -1, -1)) {
int acode = attack(i, j, NULL, NULL);
if (acode != 1)
@@ -2742,10 +2739,6 @@
popgo();
}
- if (stackp == 0) {
- safe_move_cache_when[i][j][color==BLACK] = movenum;
- safe_move_cache[i][j][color==BLACK] = safe;
- }
return safe;
}
diff -u -N -r -x *\.orig -x *\.info* ./engine/sethand.c ../gnugo-2.6.1/gnugo-2.6.1/engine/sethand.c
--- ./engine/sethand.c Sat Feb 5 05:59:53 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/engine/sethand.c Sat Aug 4 00:10:58 2001
@@ -158,13 +158,16 @@
if (handicap > maxhand)
handicap = maxhand;
- sgfAddPropertyInt(sgf_root,"HA",handicap);
+ if (sgf_root)
+ sgfAddPropertyInt(sgf_root,"HA",handicap);
/* special cases: 5 and 7 */
if (handicap == 5 || handicap == 7) {
p[mid][mid] = BLACK;
handicap--;
- sgfAddStone(sgf_root,BLACK,mid,mid);
- sgf_set_stone(mid,mid,BLACK);
+ if (sgf_root) {
+ sgfAddStone(sgf_root,BLACK,mid,mid);
+ sgf_set_stone(mid,mid,BLACK);
+ }
}
for (x=0; x<handicap; ++x) {
@@ -185,8 +188,10 @@
if ( j < 0) j += board_size-1;
p[i][j] = BLACK;
- sgfAddStone(sgf_root,BLACK,i,j);
- sgf_set_stone(i,j,BLACK);
+ if (sgf_root) {
+ sgfAddStone(sgf_root,BLACK,i,j);
+ sgf_set_stone(i,j,BLACK);
+ }
}
return handicap;
}
diff -u -N -r -x *\.orig -x *\.info* ./engine/utils.c ../gnugo-2.6.1/gnugo-2.6.1/engine/utils.c
--- ./engine/utils.c Tue Feb 8 19:59:07 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/engine/utils.c Sat Aug 4 00:10:58 2001
@@ -349,7 +349,6 @@
case 's':
{
char *s = va_arg(ap, char*);
- assert( (int)*s >= board_size ); /* in case %s used in place of %m */
fputs(s, outputfile);
break;
}
diff -u -N -r -x *\.orig -x *\.info* ./interface/Makefile.am ../gnugo-2.6.1/gnugo-2.6.1/interface/Makefile.am
--- ./interface/Makefile.am Thu Feb 3 20:48:50 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/Makefile.am Sat Aug 4 00:10:58 2001
@@ -26,7 +26,10 @@
play_gmp.c \
play_solo.c \
play_test.c \
- gmp.c
+ play_gtp.c \
+ gmp.c \
+ gtp.c \
+ gtp.h
AIXOPTS=-O -qmaxmem=16384 -qro -qroconst -qinfo
diff -u -N -r -x *\.orig -x *\.info* ./interface/Makefile.in ../gnugo-2.6.1/gnugo-2.6.1/interface/Makefile.in
--- ./interface/Makefile.in Mon Feb 14 07:10:44 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/Makefile.in Tue Aug 14 01:17:57 2001
@@ -88,7 +88,7 @@
LDADD = ../engine/libengine.a ../patterns/libpatterns.a ../sgf/libsgf.a ../utils/libutils.a
-gnugo_SOURCES = main.c interface.c play_ascii.c play_gmp.c play_solo.c play_test.c gmp.c
+gnugo_SOURCES = main.c interface.c play_ascii.c play_gmp.c play_solo.c play_test.c play_gtp.c gmp.c gtp.c gtp.h
AIXOPTS = -O -qmaxmem=16384 -qro -qroconst -qinfo
@@ -104,7 +104,7 @@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
gnugo_OBJECTS = main.o interface.o play_ascii.o play_gmp.o play_solo.o \
-play_test.o gmp.o
+play_test.o play_gtp.o gmp.o gtp.o
gnugo_LDADD = $(LDADD)
gnugo_DEPENDENCIES = ../engine/libengine.a ../patterns/libpatterns.a \
../sgf/libsgf.a ../utils/libutils.a
@@ -120,7 +120,7 @@
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
-TAR = tar
+TAR = gtar
GZIP_ENV = --best
SOURCES = $(gnugo_SOURCES)
OBJECTS = $(gnugo_OBJECTS)
@@ -229,6 +229,7 @@
fi; \
done
gmp.o: gmp.c ../config.h gmp.h
+gtp.o: gtp.c gtp.h
interface.o: interface.c ../config.h ../sgf/sgf.h ../engine/liberty.h \
../engine/hash.h interface.h ../engine/main.h
main.o: main.c ../config.h ../utils/getopt.h ../engine/main.h \
@@ -241,6 +242,8 @@
play_gmp.o: play_gmp.c interface.h ../engine/liberty.h ../config.h \
../engine/hash.h gmp.h ../sgf/sgf.h ../sgf/ttsgf.h \
../sgf/ttsgf_write.h ../sgf/sgfana.h
+play_gtp.o: play_gtp.c ../config.h ../engine/liberty.h ../engine/hash.h \
+ interface.h gtp.h
play_solo.o: play_solo.c ../config.h interface.h ../engine/liberty.h \
../engine/hash.h ../sgf/sgf.h ../sgf/sgf_properties.h \
../sgf/ttsgf_read.h ../sgf/ttsgf.h ../sgf/sgfana.h
diff -u -N -r -x *\.orig -x *\.info* ./interface/gtp.c ../gnugo-2.6.1/gnugo-2.6.1/interface/gtp.c
--- ./interface/gtp.c Thu Jan 1 00:00:00 1970
+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/gtp.c Tue Aug 14 00:50:36 2001
@@ -0,0 +1,417 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
+ * http://www.gnu.org/software/gnugo/ for more information. *
+ * *
+ * To facilitate development of the Go Text Protocol, the two *
+ * files gtp.c and gtp.h are licensed under less restrictive *
+ * terms than the rest of GNU Go. *
+ * *
+ * Copyright 2001 by the Free Software Foundation. *
+ * *
+ * Permission is hereby granted, free of charge, to any person *
+ * obtaining a copy of this file gtp.c, to deal in the Software *
+ * without restriction, including without limitation the rights *
+ * to use, copy, modify, merge, publish, distribute, and/or *
+ * sell copies of the Software, and to permit persons to whom *
+ * the Software is furnished to do so, provided that the above *
+ * copyright notice(s) and this permission notice appear in all *
+ * copies of the Software and that both the above copyright *
+ * notice(s) and this permission notice appear in supporting *
+ * documentation. *
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY *
+ * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR *
+ * PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO *
+ * EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS *
+ * NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR *
+ * CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING *
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF *
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT *
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS *
+ * SOFTWARE. *
+ * *
+ * Except as contained in this notice, the name of a copyright *
+ * holder shall not be used in advertising or otherwise to *
+ * promote the sale, use or other dealings in this Software *
+ * without prior written authorization of the copyright holder. *
+\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#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
+
+/* We need to keep track of the board size in order to be able to
+ * convert between coordinate descriptions. We could also have passed
+ * the board size in all calls needing it, but that would be
+ * unnecessarily inconvenient.
+ */
+static int gtp_boardsize = -1;
+
+/* Read stdin linewise and interpret as GTP commands. */
+void
+gtp_main_loop(struct gtp_command commands[])
+{
+ char line[GTP_BUFSIZE];
+ char command[GTP_BUFSIZE];
+ char *p;
+ int i;
+ int id;
+ int n;
+ int status = GTP_OK;
+
+ while (status == GTP_OK) {
+ /* Read a line from stdin. */
+ if (!fgets(line, GTP_BUFSIZE, stdin))
+ break; /* EOF or some error */
+
+ /* Remove comments. */
+ if ((p = strchr(line, '#')) != NULL)
+ *p = 0;
+
+ p = line;
+
+ /* Look for an identification number. */
+ if (sscanf(p, "%d%n", &id, &n) == 1)
+ p += n;
+ else
+ 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, id);
+ break;
+ }
+ }
+ if (commands[i].name == NULL)
+ gtp_failure(id, "unknown command: '%s'", command);
+
+ if (status == GTP_FATAL)
+ gtp_panic();
+ }
+}
+
+
+/* Set the board size used in coordinate conversions. */
+void
+gtp_internal_set_boardsize(int size)
+{
+ gtp_boardsize = size;
+}
+
+/*
+ * This function works like printf, except that it only understands
+ * very few of the standard formats, to be precise %c, %d, %f, %s.
+ * But it also accepts %m, which takes two integers and writes a move,
+ * and %C, which takes a color value and writes a color string.
+ */
+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, stdout);
+ break;
+ }
+ case 'd':
+ {
+ int d = va_arg(ap, int);
+ fprintf(stdout, "%d", d);
+ break;
+ }
+ case 'f':
+ {
+ double f = va_arg(ap, double); /* passed as double, not float */
+ fprintf(stdout, "%f", f);
+ break;
+ }
+ case 's':
+ {
+ char *s = va_arg(ap, char*);
+ fputs(s, stdout);
+ break;
+ }
+ case 'm':
+ {
+ int m = va_arg(ap, int);
+ int n = va_arg(ap, int);
+ if (m == -1 && n == -1)
+ fputs("PASS", stdout);
+ else if ((m<0) || (n<0) || (m>=gtp_boardsize) || (n>=gtp_boardsize))
+ fprintf(stdout, "??");
+ else
+ fprintf(stdout, "%c%d", 'A' + n + (n >= 8), gtp_boardsize - m);
+ break;
+ }
+ case 'C':
+ {
+ int color = va_arg(ap, int);
+ if (color == WHITE)
+ fputs("white", stdout);
+ else if (color == BLACK)
+ fputs("black", stdout);
+ else
+ fputs("empty", stdout);
+ break;
+ }
+ default:
+ fprintf(stdout, "\n\nUnknown format character '%c'\n", *fmt);
+ break;
+ }
+ }
+ else
+ putc(*fmt, stdout);
+ }
+ va_end(ap);
+}
+
+
+/* This currently works exactly like printf. */
+void
+gtp_printf(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+}
+
+
+/* Write success or failure indication plus identity number if one was
+ * given.
+ */
+void
+gtp_printid(int id, int status)
+{
+ if (status == GTP_SUCCESS)
+ gtp_printf("=");
+ else
+ gtp_printf("?");
+
+ if (id < 0)
+ gtp_printf(" ");
+ else
+ gtp_printf("%d ", id);
+}
+
+
+/* Finish a GTP response by writing a double newline and returning GTP_OK. */
+int
+gtp_finish_response()
+{
+ 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(int id, const char *format, ...)
+{
+ va_list ap;
+ gtp_printid(id, GTP_SUCCESS);
+ va_start(ap, format);
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+ return gtp_finish_response();
+}
+
+
+/* Write a full failure response. The call is identical to gtp_success. */
+int
+gtp_failure(int id, const char *format, ...)
+{
+ va_list ap;
+ gtp_printid(id, GTP_FAILURE);
+ va_start(ap, format);
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+ return gtp_finish_response();
+}
+
+
+/* Write a panic message. */
+void
+gtp_panic()
+{
+ 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)
+{
+ 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)
+{
+ char column;
+ int row;
+ int n;
+
+ 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;
+
+ *i = gtp_boardsize - row;
+
+ if (*i < 0 || *i >= gtp_boardsize || *j < 0 || *j >= gtp_boardsize)
+ return 0;
+
+ 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.
+ */
+int
+gtp_decode_move(char *s, int *color, int *i, int *j)
+{
+ int n1, n2;
+
+ 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)
+ return 0;
+
+ return n1 + n2;
+}
+
+/* This a bubble sort. Given the expected size of the sets to
+ * sort, it's probably not worth the overhead to set up a call to
+ * qsort.
+ */
+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;
+ }
+ }
+ }
+}
+
+/* Write a number of space separated vertices. The moves are sorted
+ * before being written.
+ */
+void
+gtp_print_vertices(int n, int movei[], int movej[])
+{
+ int k;
+
+ 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)
+ || (movei[k] == gtp_boardsize && movej[k] == gtp_boardsize))
+ gtp_printf("PASS");
+ else if (movei[k] < 0 || movei[k] >= gtp_boardsize
+ || movej[k] < 0 || movej[k] >= gtp_boardsize) {
+ gtp_printf("?? %d %d", movei[k], movej[k]);
+ }
+ else
+ gtp_printf("%c%d", 'A' + movej[k] + (movej[k] >= 8),
+ gtp_boardsize - movei[k]);
+ }
+}
+
+/* Write a single move. */
+void
+gtp_print_vertex(int i, int j)
+{
+ gtp_print_vertices(1, &i, &j);
+}
+
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * c-basic-offset: 2
+ * End:
+ */
diff -u -N -r -x *\.orig -x *\.info* ./interface/gtp.h ../gnugo-2.6.1/gnugo-2.6.1/interface/gtp.h
--- ./interface/gtp.h Thu Jan 1 00:00:00 1970
+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/gtp.h Sat Aug 4 00:10:58 2001
@@ -0,0 +1,83 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
+ * http://www.gnu.org/software/gnugo/ for more information. *
+ * *
+ * To facilitate development of the Go Text Protocol, the two *
+ * files gtp.c and gtp.h are licensed under less restrictive *
+ * terms than the rest of GNU Go. *
+ * *
+ * Copyright 2001 by the Free Software Foundation. *
+ * *
+ * Permission is hereby granted, free of charge, to any person *
+ * obtaining a copy of this file gtp.h, to deal in the Software *
+ * without restriction, including without limitation the rights *
+ * to use, copy, modify, merge, publish, distribute, and/or *
+ * sell copies of the Software, and to permit persons to whom *
+ * the Software is furnished to do so, provided that the above *
+ * copyright notice(s) and this permission notice appear in all *
+ * copies of the Software and that both the above copyright *
+ * notice(s) and this permission notice appear in supporting *
+ * documentation. *
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY *
+ * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR *
+ * PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO *
+ * EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS *
+ * NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR *
+ * CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING *
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF *
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT *
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS *
+ * SOFTWARE. *
+ * *
+ * Except as contained in this notice, the name of a copyright *
+ * holder shall not be used in advertising or otherwise to *
+ * promote the sale, use or other dealings in this Software *
+ * without prior written authorization of the copyright holder. *
+\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdarg.h>
+
+/* Maximum allowed line length in GTP. */
+#define GTP_BUFSIZE 1000
+
+/* Status returned from callback functions. */
+#define GTP_QUIT -1
+#define GTP_OK 0
+#define GTP_FATAL 1
+
+/* Whether the GTP command was successful. */
+#define GTP_SUCCESS 0
+#define GTP_FAILURE 1
+
+/* Function pointer for callback functions. */
+typedef int (*gtp_fn_ptr)(char *s, int id);
+
+/* Elements in the array of commands required by gtp_main_loop. */
+struct gtp_command {
+ const char *name;
+ gtp_fn_ptr function;
+};
+
+void gtp_main_loop(struct gtp_command commands[]);
+void gtp_internal_set_boardsize(int size);
+void gtp_mprintf(const char *format, ...);
+void gtp_printf(const char *format, ...);
+void gtp_printid(int id, int status);
+int gtp_finish_response(void);
+int gtp_success(int id, const char *format, ...);
+int gtp_failure(int id, const char *format, ...);
+void gtp_panic(void);
+int gtp_decode_color(char *s, int *color);
+int gtp_decode_coord(char *s, int *m, int *n);
+int gtp_decode_move(char *s, int *color, int *i, int *j);
+void gtp_print_vertices(int n, int movei[], int movej[]);
+void gtp_print_vertex(int i, int j);
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * c-basic-offset: 2
+ * End:
+ */
diff -u -N -r -x *\.orig -x *\.info* ./interface/interface.c ../gnugo-2.6.1/gnugo-2.6.1/interface/interface.c
--- ./interface/interface.c Sat Feb 5 06:03:19 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/interface.c Tue Aug 14 00:49:58 2001
@@ -326,14 +326,14 @@
int
clear_board(board_t **board)
{
- if(board==NULL)
- {
+ if (board==NULL) {
memset(p,EMPTY,sizeof(p));
- }
- else
- {
- memset(board,EMPTY,MAX_BOARD*MAX_BOARD*sizeof(board_t));
- }
+ }
+ else {
+ memset(board,EMPTY,MAX_BOARD*MAX_BOARD*sizeof(board_t));
+ }
+ white_captured = 0;
+ black_captured = 0;
return 1;
}
diff -u -N -r -x *\.orig -x *\.info* ./interface/interface.h ../gnugo-2.6.1/gnugo-2.6.1/interface/interface.h
--- ./interface/interface.h Sat Feb 5 06:03:25 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/interface.h Sat Aug 4 00:10:58 2001
@@ -42,6 +42,7 @@
void play_ascii(char * filename);
void play_ascii_emacs(char * filename);
void play_gmp(void);
+void play_gtp(void);
void play_solo(int);
void play_test(struct SGFNode *, enum testmode);
int load_sgf_file(struct SGFNode *, const char *untilstr);
diff -u -N -r -x *\.orig -x *\.info* ./interface/main.c ../gnugo-2.6.1/gnugo-2.6.1/interface/main.c
--- ./interface/main.c Sat Feb 12 04:37:42 2000
+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/main.c Sat Aug 4 00:10:58 2001
@@ -79,7 +79,7 @@
Usage : gnugo [-opts]\n\
\n\
Main Options:\n\
- --mode <mode> Force the playing mode ('ascii', 'test' or 'gmp').\n\
+ --mode <mode> Select mode ('ascii', 'test, 'gmp', 'gtp').\n\
Default is ASCII.\n\
If no terminal is detected GMP (Go Modem Protocol)\n\
will be assumed.\n\
@@ -185,6 +185,7 @@
MODE_ASCII,
MODE_ASCII_EMACS,
MODE_GMP,
+ MODE_GTP,
MODE_SGF,
MODE_LOAD_AND_ANALYZE,
MODE_LOAD_AND_SCORE,
@@ -482,6 +483,7 @@
if (strcmp(optarg,"ascii")==0) playmode = MODE_ASCII;
else if (strcmp(optarg,"emacs")==0) playmode = MODE_ASCII_EMACS;
else if (strcmp(optarg,"gmp")==0) playmode = MODE_GMP;
+ else if (strcmp(optarg,"gtp")==0) playmode = MODE_GTP;
else if (strcmp(optarg,"test")==0) playmode = MODE_TEST;
else {
fprintf(stderr,"Invalid mode selection: %s\n",optarg);
@@ -718,6 +720,10 @@
set_computer_player(NONE);
}
play_ascii_emacs(infile);
+ break;
+
+ case MODE_GTP:
+ play_gtp();
break;
case MODE_ASCII :
diff -u -N -r -x *\.orig -x *\.info* ./interface/play_gtp.c ../gnugo-2.6.1/gnugo-2.6.1/interface/play_gtp.c
--- ./interface/play_gtp.c Thu Jan 1 00:00:00 1970
+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/play_gtp.c Tue Aug 14 01:16:03 2001
@@ -0,0 +1,377 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
+ * http://www.gnu.org/software/gnugo/ for more information. *
+ * *
+ * Copyright 1999, 2000, 2001 by the Free Software Foundation. *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation - version 3. *
+ * *
+ * This program is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied *
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *
+ * PURPOSE. See the GNU General Public License in file COPYING *
+ * for more details. *
+ * *
+ * You should have received a copy of the GNU General Public *
+ * License along with this program; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02111, USA. *
+\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "liberty.h"
+#include "interface.h"
+#include "gtp.h"
+
+#define MAXLIBS (2*(MAX_BOARD*MAX_BOARD + 1)/3)
+#define UNUSED(x) x=x
+
+/* Internal state that's not part of the engine. */
+int color_to_move;
+float komi;
+int handicap;
+
+#define DECLARE(func) static int func(char *s, int id)
+
+DECLARE(gtp_fixed_handicap);
+DECLARE(gtp_genmove_black);
+DECLARE(gtp_genmove_white);
+DECLARE(gtp_name);
+DECLARE(gtp_estimate_score);
+DECLARE(gtp_playblack);
+DECLARE(gtp_playwhite);
+DECLARE(gtp_quit);
+DECLARE(gtp_set_boardsize);
+DECLARE(gtp_set_komi);
+DECLARE(gtp_showboard);
+DECLARE(gtp_version);
+DECLARE(gtp_help);
+float estimate_score(float komi);
+
+void play_gtp(void);
+
+/* List of known commands. */
+static struct gtp_command commands[] = {
+ {"black", gtp_playblack},
+ {"boardsize", gtp_set_boardsize},
+ {"fixed_handicap", gtp_fixed_handicap},
+ {"genmove_black", gtp_genmove_black},
+ {"genmove_white", gtp_genmove_white},
+ {"help", gtp_help},
+ {"komi", gtp_set_komi},
+ {"name", gtp_name},
+ {"estimate_score", gtp_estimate_score},
+ {"quit", gtp_quit},
+ {"showboard", gtp_showboard},
+ {"version", gtp_version},
+ {"white", gtp_playwhite},
+ {NULL, NULL}
+};
+
+
+/* Start playing using the Go Text Protocol. */
+void
+play_gtp(void)
+{
+ /* Try to make sure that we have a useful level of buffering of stdout. */
+#ifdef HAVE_SETLINEBUF
+ setlinebuf(stdout);
+#else
+ setbuf(stdout, NULL);
+#endif
+
+ gtp_internal_set_boardsize(19);
+
+ gtp_main_loop(commands);
+}
+
+
+/* Function: Quit
+ * Arguments: none
+ * Fails: never
+ * Returns: nothing
+ */
+static int
+gtp_quit(char *s, int id)
+{
+ UNUSED(s);
+ gtp_success(id, "");
+ return GTP_QUIT;
+}
+
+
+/****************************
+ * Program identity. *
+ ****************************/
+
+/* Function: Report the name of the program.
+ * Arguments: none
+ * Fails: never
+ * Returns: program name
+ */
+static int
+gtp_name(char *s, int id)
+{
+ UNUSED(s);
+ return gtp_success(id, "GNU Go");
+}
+
+
+/* Function: Report the version number of the program.
+ * Arguments: none
+ * Fails: never
+ * Returns: version number
+ */
+static int
+gtp_version(char *s, int id)
+{
+ UNUSED(s);
+ return gtp_success(id, VERSION);
+}
+
+
+/* Function: Set the board size to NxN and clear the board.
+ * Arguments: integer
+ * Fails: board size outside engine's limits
+ * Returns: nothing
+ */
+static int
+gtp_set_boardsize(char *s, int id)
+{
+ int boardsize;
+ if (sscanf(s, "%d", &boardsize) < 1)
+ return gtp_failure(id, "boardsize not an integer");
+
+ if (boardsize < MIN_BOARD || boardsize > MAX_BOARD)
+ return gtp_failure(id, "unacceptable boardsize");
+
+ set_boardsize(boardsize);
+ clear_board(NULL);
+ gtp_internal_set_boardsize(boardsize);
+ return gtp_success(id, "");
+}
+
+
+/* Function: Set the komi.
+ * Arguments: float
+ * Fails: incorrect argument
+ * Returns: nothing
+ */
+static int
+gtp_set_komi(char *s, int id)
+{
+ if (sscanf(s, "%f", &komi) < 1)
+ return gtp_failure(id, "komi not a float");
+
+ return gtp_success(id, "");
+}
+
+
+/* Function: Play a black stone at the given vertex.
+ * Arguments: vertex
+ * Fails: invalid vertex, illegal move
+ * Returns: nothing
+ */
+static int
+gtp_playblack(char *s, int id)
+{
+ int i, j;
+ char *c;
+
+ for (c = s; *c; c++)
+ *c = tolower(*c);
+
+ if (strncmp(s, "pass", 4) == 0) {
+ i = get_boardsize();
+ j = get_boardsize();
+ }
+ else if (!gtp_decode_coord(s, &i, &j))
+ return gtp_failure(id, "invalid coordinate");
+
+ if (!legal(i, j, BLACK))
+ return gtp_failure(id, "illegal move");
+
+ updateboard(i, j, BLACK);
+ return gtp_success(id, "");
+}
+
+
+/* Function: Play a white stone at the given vertex.
+ * Arguments: vertex
+ * Fails: invalid vertex, illegal move
+ * Returns: nothing
+ */
+static int
+gtp_playwhite(char *s, int id)
+{
+ int i, j;
+ char *c;
+
+ for (c = s; *c; c++)
+ *c = tolower(*c);
+
+ if (strncmp(s, "pass", 4) == 0) {
+ i = get_boardsize();
+ j = get_boardsize();
+ }
+ else if (!gtp_decode_coord(s, &i, &j))
+ return gtp_failure(id, "invalid coordinate");
+
+ if (!legal(i, j, WHITE))
+ return gtp_failure(id, "illegal move");
+
+ updateboard(i, j, WHITE);
+ return gtp_success(id, "");
+}
+
+
+/* Function: Set up fixed placement handicap stones.
+ * Arguments: number of handicap stones
+ * Fails: invalid number of stones for the current boardsize
+ * Returns: list of vertices with handicap stones
+ */
+static int
+gtp_fixed_handicap(char *s, int id)
+{
+ int m, n;
+ int first = 1;
+ int handicap;
+ if (sscanf(s, "%d", &handicap) < 1)
+ return gtp_failure(id, "handicap not an integer");
+
+ clear_board(NULL);
+ if (sethand(handicap) != handicap)
+ return gtp_failure(id, "invalid handicap");
+
+ gtp_printid(id, GTP_SUCCESS);
+
+ for (m = 0; m < board_size; m++)
+ for (n = 0; n < board_size; n++)
+ if (p[m][n] != EMPTY) {
+ if (!first)
+ gtp_printf(" ");
+ else
+ first = 0;
+ gtp_mprintf("%m", m, n);
+ }
+
+ return gtp_finish_response();
+}
+
+
+/* Function: Generate and play the supposedly best black move.
+ * Arguments: none
+ * Fails: never
+ * Returns: a move coordinate (or "PASS")
+ */
+static int
+gtp_genmove_black(char *s, int id)
+{
+ int i, j;
+ UNUSED(s);
+
+ if (genmove(&i, &j, BLACK) >= 0)
+ updateboard(i, j, BLACK);
+
+ gtp_printid(id, GTP_SUCCESS);
+ gtp_print_vertex(i, j);
+ return gtp_finish_response();
+}
+
+
+
+
+/* Function: Generate and play the supposedly best white move.
+ * Arguments: none
+ * Fails: never
+ * Returns: a move coordinate (or "PASS")
+ */
+static int
+gtp_genmove_white(char *s, int id)
+{
+ int i, j;
+ UNUSED(s);
+ if (genmove(&i, &j, WHITE) >= 0)
+ updateboard(i, j, WHITE);
+
+ gtp_printid(id, GTP_SUCCESS);
+ gtp_print_vertex(i, j);
+ return gtp_finish_response();
+}
+
+static int
+gtp_estimate_score(char *s, int id)
+{
+ int i, j;
+ float score;
+ UNUSED(s);
+
+ genmove(&i, &j, BLACK);
+ score = estimate_score(komi);
+
+ gtp_printid(id, GTP_SUCCESS);
+ if (score > 0.0)
+ gtp_printf("W+%3.1f (upper bound: %3.1f, lower: %3.1f)",
+ score, score, score);
+ else if (score < 0.0)
+ gtp_printf("B+%3.1f (upper bound: %3.1f, lower: %3.1f)",
+ -score, score, score);
+ else
+ gtp_printf("0");
+ return gtp_finish_response();
+}
+
+
+/* Function: Write the position to stderr.
+ * Arguments: none
+ * Fails: never
+ * Returns: nothing
+ */
+static int
+gtp_showboard(char *s, int id)
+{
+ UNUSED(s);
+ showboard(1);
+ return gtp_success(id, "");
+}
+
+
+/* Function: List all known commands
+ * Arguments: none
+ * Fails: never
+ * Returns: list of known commands, one per line
+ */
+static int
+gtp_help(char *s, int id)
+{
+ int k;
+ UNUSED(s);
+
+ gtp_printid(id, GTP_SUCCESS);
+
+ for (k = 0; commands[k].name != NULL; k++)
+ gtp_printf("%s\n", commands[k].name);
+
+ gtp_printf("\n");
+ return GTP_OK;
+}
+
+
+
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * c-basic-offset: 2
+ * End:
+ */