Initial commit of GNU Go v3.8.
[sgk-go] / interface / gtp_examples / gtp2_6
CommitLineData
7eeb782e
AT
1This patch to GNU Go 2.6 allows it to play with the Go Text Protocol.
2
3
4
5
6diff -u -N -r -x *\.orig -x *\.info* ./configure.in ../gnugo-2.6.1/gnugo-2.6.1/configure.in
7--- ./configure.in Sun Feb 13 03:02:11 2000
8+++ ../gnugo-2.6.1/gnugo-2.6.1/configure.in Sat Aug 4 00:10:58 2001
9@@ -8,7 +8,7 @@
10 AC_PREREQ(2.12)dnl dnl Minimum Autoconf version required.
11
12 dnl this defines VERSION and PACKAGE
13-AM_INIT_AUTOMAKE([gnugo], [2.6])
14+AM_INIT_AUTOMAKE([gnugo], [2.6.1])
15 GNU_PACKAGE="GNU $PACKAGE"
16 AC_DEFINE_UNQUOTED(GNU_PACKAGE, "$GNU_PACKAGE")
17
18diff -u -N -r -x *\.orig -x *\.info* ./engine/liberty.h ../gnugo-2.6.1/gnugo-2.6.1/engine/liberty.h
19--- ./engine/liberty.h Tue Feb 8 19:59:07 2000
20+++ ../gnugo-2.6.1/gnugo-2.6.1/engine/liberty.h Fri Aug 10 16:20:09 2001
21@@ -53,6 +53,7 @@
22 #define WHITE 1
23 #define BLACK 2
24 #define GRAY_BORDER 3
25+#define GRAY 3
26 #define WHITE_BORDER 4
27 #define BLACK_BORDER 5
28 #define NONE 6 /* for use with is_computer_player */
29@@ -138,8 +139,7 @@
30 void restore_state(void);
31 int dragon_status(int i, int j);
32 void change_dragon_status(int x, int y, int status);
33-
34-void who_wins(int color, float fkomi, FILE* stdwhat);
35+void who_wins(int color, float fkomi, FILE * stdwhat);
36
37 /* data concerning a dragon. A copy is kept at each stone of the string */
38
39@@ -362,6 +362,7 @@
40 void find_cuts(void);
41 void find_connections(void);
42 void endgame(void);
43+float estimate_score(float komi);
44
45 /* various different strategies for finding a move */
46
47diff -u -N -r -x *\.orig -x *\.info* ./engine/moyo.c ../gnugo-2.6.1/gnugo-2.6.1/engine/moyo.c
48--- ./engine/moyo.c Tue Feb 8 19:59:07 2000
49+++ ../gnugo-2.6.1/gnugo-2.6.1/engine/moyo.c Fri Aug 10 16:21:10 2001
50@@ -2489,6 +2489,20 @@
51 fprintf(stdwhat, "%c says \"I lost!\"\n", (color == WHITE) ? 'W' : 'B');
52 }
53
54+float
55+estimate_score(float fkomi)
56+{
57+ float white_score;
58+ float black_score;
59+ float result;
60+
61+ make_moyo(BLACK);
62+ white_score = (float) terri_eval[WHITE] + fkomi;
63+ black_score = (float) terri_eval[BLACK];
64+ result = white_score - black_score;
65+ return result;
66+}
67+
68
69
70 void
71diff -u -N -r -x *\.orig -x *\.info* ./engine/reading.c ../gnugo-2.6.1/gnugo-2.6.1/engine/reading.c
72--- ./engine/reading.c Tue Feb 8 19:59:07 2000
73+++ ../gnugo-2.6.1/gnugo-2.6.1/engine/reading.c Sat Aug 4 00:10:58 2001
74@@ -2732,9 +2732,6 @@
75 {
76 int safe=0;
77
78- if (stackp == 0 && safe_move_cache_when[i][j][color==BLACK] == movenum)
79- return safe_move_cache[i][j][color==BLACK];
80-
81 if (trymove(i, j, color, "safe_move", -1, -1)) {
82 int acode = attack(i, j, NULL, NULL);
83 if (acode != 1)
84@@ -2742,10 +2739,6 @@
85 popgo();
86 }
87
88- if (stackp == 0) {
89- safe_move_cache_when[i][j][color==BLACK] = movenum;
90- safe_move_cache[i][j][color==BLACK] = safe;
91- }
92 return safe;
93 }
94
95diff -u -N -r -x *\.orig -x *\.info* ./engine/sethand.c ../gnugo-2.6.1/gnugo-2.6.1/engine/sethand.c
96--- ./engine/sethand.c Sat Feb 5 05:59:53 2000
97+++ ../gnugo-2.6.1/gnugo-2.6.1/engine/sethand.c Sat Aug 4 00:10:58 2001
98@@ -158,13 +158,16 @@
99 if (handicap > maxhand)
100 handicap = maxhand;
101
102- sgfAddPropertyInt(sgf_root,"HA",handicap);
103+ if (sgf_root)
104+ sgfAddPropertyInt(sgf_root,"HA",handicap);
105 /* special cases: 5 and 7 */
106 if (handicap == 5 || handicap == 7) {
107 p[mid][mid] = BLACK;
108 handicap--;
109- sgfAddStone(sgf_root,BLACK,mid,mid);
110- sgf_set_stone(mid,mid,BLACK);
111+ if (sgf_root) {
112+ sgfAddStone(sgf_root,BLACK,mid,mid);
113+ sgf_set_stone(mid,mid,BLACK);
114+ }
115 }
116
117 for (x=0; x<handicap; ++x) {
118@@ -185,8 +188,10 @@
119 if ( j < 0) j += board_size-1;
120
121 p[i][j] = BLACK;
122- sgfAddStone(sgf_root,BLACK,i,j);
123- sgf_set_stone(i,j,BLACK);
124+ if (sgf_root) {
125+ sgfAddStone(sgf_root,BLACK,i,j);
126+ sgf_set_stone(i,j,BLACK);
127+ }
128 }
129 return handicap;
130 }
131diff -u -N -r -x *\.orig -x *\.info* ./engine/utils.c ../gnugo-2.6.1/gnugo-2.6.1/engine/utils.c
132--- ./engine/utils.c Tue Feb 8 19:59:07 2000
133+++ ../gnugo-2.6.1/gnugo-2.6.1/engine/utils.c Sat Aug 4 00:10:58 2001
134@@ -349,7 +349,6 @@
135 case 's':
136 {
137 char *s = va_arg(ap, char*);
138- assert( (int)*s >= board_size ); /* in case %s used in place of %m */
139 fputs(s, outputfile);
140 break;
141 }
142diff -u -N -r -x *\.orig -x *\.info* ./interface/Makefile.am ../gnugo-2.6.1/gnugo-2.6.1/interface/Makefile.am
143--- ./interface/Makefile.am Thu Feb 3 20:48:50 2000
144+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/Makefile.am Sat Aug 4 00:10:58 2001
145@@ -26,7 +26,10 @@
146 play_gmp.c \
147 play_solo.c \
148 play_test.c \
149- gmp.c
150+ play_gtp.c \
151+ gmp.c \
152+ gtp.c \
153+ gtp.h
154
155 AIXOPTS=-O -qmaxmem=16384 -qro -qroconst -qinfo
156
157diff -u -N -r -x *\.orig -x *\.info* ./interface/Makefile.in ../gnugo-2.6.1/gnugo-2.6.1/interface/Makefile.in
158--- ./interface/Makefile.in Mon Feb 14 07:10:44 2000
159+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/Makefile.in Tue Aug 14 01:17:57 2001
160@@ -88,7 +88,7 @@
161 LDADD = ../engine/libengine.a ../patterns/libpatterns.a ../sgf/libsgf.a ../utils/libutils.a
162
163
164-gnugo_SOURCES = main.c interface.c play_ascii.c play_gmp.c play_solo.c play_test.c gmp.c
165+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
166
167
168 AIXOPTS = -O -qmaxmem=16384 -qro -qroconst -qinfo
169@@ -104,7 +104,7 @@
170 LDFLAGS = @LDFLAGS@
171 LIBS = @LIBS@
172 gnugo_OBJECTS = main.o interface.o play_ascii.o play_gmp.o play_solo.o \
173-play_test.o gmp.o
174+play_test.o play_gtp.o gmp.o gtp.o
175 gnugo_LDADD = $(LDADD)
176 gnugo_DEPENDENCIES = ../engine/libengine.a ../patterns/libpatterns.a \
177 ../sgf/libsgf.a ../utils/libutils.a
178@@ -120,7 +120,7 @@
179
180 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
181
182-TAR = tar
183+TAR = gtar
184 GZIP_ENV = --best
185 SOURCES = $(gnugo_SOURCES)
186 OBJECTS = $(gnugo_OBJECTS)
187@@ -229,6 +229,7 @@
188 fi; \
189 done
190 gmp.o: gmp.c ../config.h gmp.h
191+gtp.o: gtp.c gtp.h
192 interface.o: interface.c ../config.h ../sgf/sgf.h ../engine/liberty.h \
193 ../engine/hash.h interface.h ../engine/main.h
194 main.o: main.c ../config.h ../utils/getopt.h ../engine/main.h \
195@@ -241,6 +242,8 @@
196 play_gmp.o: play_gmp.c interface.h ../engine/liberty.h ../config.h \
197 ../engine/hash.h gmp.h ../sgf/sgf.h ../sgf/ttsgf.h \
198 ../sgf/ttsgf_write.h ../sgf/sgfana.h
199+play_gtp.o: play_gtp.c ../config.h ../engine/liberty.h ../engine/hash.h \
200+ interface.h gtp.h
201 play_solo.o: play_solo.c ../config.h interface.h ../engine/liberty.h \
202 ../engine/hash.h ../sgf/sgf.h ../sgf/sgf_properties.h \
203 ../sgf/ttsgf_read.h ../sgf/ttsgf.h ../sgf/sgfana.h
204diff -u -N -r -x *\.orig -x *\.info* ./interface/gtp.c ../gnugo-2.6.1/gnugo-2.6.1/interface/gtp.c
205--- ./interface/gtp.c Thu Jan 1 00:00:00 1970
206+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/gtp.c Tue Aug 14 00:50:36 2001
207@@ -0,0 +1,417 @@
208+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
209+ * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
210+ * http://www.gnu.org/software/gnugo/ for more information. *
211+ * *
212+ * To facilitate development of the Go Text Protocol, the two *
213+ * files gtp.c and gtp.h are licensed under less restrictive *
214+ * terms than the rest of GNU Go. *
215+ * *
216+ * Copyright 2001 by the Free Software Foundation. *
217+ * *
218+ * Permission is hereby granted, free of charge, to any person *
219+ * obtaining a copy of this file gtp.c, to deal in the Software *
220+ * without restriction, including without limitation the rights *
221+ * to use, copy, modify, merge, publish, distribute, and/or *
222+ * sell copies of the Software, and to permit persons to whom *
223+ * the Software is furnished to do so, provided that the above *
224+ * copyright notice(s) and this permission notice appear in all *
225+ * copies of the Software and that both the above copyright *
226+ * notice(s) and this permission notice appear in supporting *
227+ * documentation. *
228+ * *
229+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY *
230+ * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
231+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR *
232+ * PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO *
233+ * EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS *
234+ * NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR *
235+ * CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING *
236+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF *
237+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT *
238+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS *
239+ * SOFTWARE. *
240+ * *
241+ * Except as contained in this notice, the name of a copyright *
242+ * holder shall not be used in advertising or otherwise to *
243+ * promote the sale, use or other dealings in this Software *
244+ * without prior written authorization of the copyright holder. *
245+\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
246+
247+#include <stdio.h>
248+#include <string.h>
249+#include <ctype.h>
250+#include <assert.h>
251+
252+#include "gtp.h"
253+
254+/* These are copied from gnugo.h. We don't include this file in order
255+ * to remain as independent as possible of GNU Go internals.
256+ */
257+#define EMPTY 0
258+#define WHITE 1
259+#define BLACK 2
260+
261+/* We need to keep track of the board size in order to be able to
262+ * convert between coordinate descriptions. We could also have passed
263+ * the board size in all calls needing it, but that would be
264+ * unnecessarily inconvenient.
265+ */
266+static int gtp_boardsize = -1;
267+
268+/* Read stdin linewise and interpret as GTP commands. */
269+void
270+gtp_main_loop(struct gtp_command commands[])
271+{
272+ char line[GTP_BUFSIZE];
273+ char command[GTP_BUFSIZE];
274+ char *p;
275+ int i;
276+ int id;
277+ int n;
278+ int status = GTP_OK;
279+
280+ while (status == GTP_OK) {
281+ /* Read a line from stdin. */
282+ if (!fgets(line, GTP_BUFSIZE, stdin))
283+ break; /* EOF or some error */
284+
285+ /* Remove comments. */
286+ if ((p = strchr(line, '#')) != NULL)
287+ *p = 0;
288+
289+ p = line;
290+
291+ /* Look for an identification number. */
292+ if (sscanf(p, "%d%n", &id, &n) == 1)
293+ p += n;
294+ else
295+ id = -1; /* No identification number. */
296+
297+ /* Look for command name. */
298+ if (sscanf(p, " %s %n", command, &n) < 1)
299+ continue; /* Whitespace only on this line, ignore. */
300+ p += n;
301+
302+ /* Search the list of commands and call the corresponding function
303+ * if it's found.
304+ */
305+ for (i = 0; commands[i].name != NULL; i++) {
306+ if (strcmp(command, commands[i].name) == 0) {
307+ status = (*commands[i].function)(p, id);
308+ break;
309+ }
310+ }
311+ if (commands[i].name == NULL)
312+ gtp_failure(id, "unknown command: '%s'", command);
313+
314+ if (status == GTP_FATAL)
315+ gtp_panic();
316+ }
317+}
318+
319+
320+/* Set the board size used in coordinate conversions. */
321+void
322+gtp_internal_set_boardsize(int size)
323+{
324+ gtp_boardsize = size;
325+}
326+
327+/*
328+ * This function works like printf, except that it only understands
329+ * very few of the standard formats, to be precise %c, %d, %f, %s.
330+ * But it also accepts %m, which takes two integers and writes a move,
331+ * and %C, which takes a color value and writes a color string.
332+ */
333+void
334+gtp_mprintf(const char *fmt, ...)
335+{
336+ va_list ap;
337+ va_start(ap, fmt);
338+
339+ for ( ; *fmt ; ++fmt ) {
340+ if (*fmt == '%') {
341+ switch (*++fmt) {
342+ case 'c':
343+ {
344+ /* rules of promotion => passed as int, not char */
345+ int c = va_arg(ap, int);
346+ putc(c, stdout);
347+ break;
348+ }
349+ case 'd':
350+ {
351+ int d = va_arg(ap, int);
352+ fprintf(stdout, "%d", d);
353+ break;
354+ }
355+ case 'f':
356+ {
357+ double f = va_arg(ap, double); /* passed as double, not float */
358+ fprintf(stdout, "%f", f);
359+ break;
360+ }
361+ case 's':
362+ {
363+ char *s = va_arg(ap, char*);
364+ fputs(s, stdout);
365+ break;
366+ }
367+ case 'm':
368+ {
369+ int m = va_arg(ap, int);
370+ int n = va_arg(ap, int);
371+ if (m == -1 && n == -1)
372+ fputs("PASS", stdout);
373+ else if ((m<0) || (n<0) || (m>=gtp_boardsize) || (n>=gtp_boardsize))
374+ fprintf(stdout, "??");
375+ else
376+ fprintf(stdout, "%c%d", 'A' + n + (n >= 8), gtp_boardsize - m);
377+ break;
378+ }
379+ case 'C':
380+ {
381+ int color = va_arg(ap, int);
382+ if (color == WHITE)
383+ fputs("white", stdout);
384+ else if (color == BLACK)
385+ fputs("black", stdout);
386+ else
387+ fputs("empty", stdout);
388+ break;
389+ }
390+ default:
391+ fprintf(stdout, "\n\nUnknown format character '%c'\n", *fmt);
392+ break;
393+ }
394+ }
395+ else
396+ putc(*fmt, stdout);
397+ }
398+ va_end(ap);
399+}
400+
401+
402+/* This currently works exactly like printf. */
403+void
404+gtp_printf(const char *format, ...)
405+{
406+ va_list ap;
407+ va_start(ap, format);
408+ vfprintf(stdout, format, ap);
409+ va_end(ap);
410+}
411+
412+
413+/* Write success or failure indication plus identity number if one was
414+ * given.
415+ */
416+void
417+gtp_printid(int id, int status)
418+{
419+ if (status == GTP_SUCCESS)
420+ gtp_printf("=");
421+ else
422+ gtp_printf("?");
423+
424+ if (id < 0)
425+ gtp_printf(" ");
426+ else
427+ gtp_printf("%d ", id);
428+}
429+
430+
431+/* Finish a GTP response by writing a double newline and returning GTP_OK. */
432+int
433+gtp_finish_response()
434+{
435+ gtp_printf("\n\n");
436+ return GTP_OK;
437+}
438+
439+
440+/* Write a full success response. Except for the id number, the call
441+ * is just like one to printf.
442+ */
443+int
444+gtp_success(int id, const char *format, ...)
445+{
446+ va_list ap;
447+ gtp_printid(id, GTP_SUCCESS);
448+ va_start(ap, format);
449+ vfprintf(stdout, format, ap);
450+ va_end(ap);
451+ return gtp_finish_response();
452+}
453+
454+
455+/* Write a full failure response. The call is identical to gtp_success. */
456+int
457+gtp_failure(int id, const char *format, ...)
458+{
459+ va_list ap;
460+ gtp_printid(id, GTP_FAILURE);
461+ va_start(ap, format);
462+ vfprintf(stdout, format, ap);
463+ va_end(ap);
464+ return gtp_finish_response();
465+}
466+
467+
468+/* Write a panic message. */
469+void
470+gtp_panic()
471+{
472+ gtp_printf("! panic\n\n");
473+}
474+
475+
476+/* Convert a string describing a color, "b", "black", "w", or "white",
477+ * to GNU Go's integer representation of colors. Return the number of
478+ * characters read from the string s.
479+ */
480+int
481+gtp_decode_color(char *s, int *color)
482+{
483+ char color_string[7];
484+ int i;
485+ int n;
486+
487+ assert(gtp_boardsize > 0);
488+
489+ if (sscanf(s, "%6s%n", color_string, &n) != 1)
490+ return 0;
491+
492+ for (i = 0; i < (int) strlen(color_string); i++)
493+ color_string[i] = tolower((int) color_string[i]);
494+
495+ if (strcmp(color_string, "b") == 0
496+ || strcmp(color_string, "black") == 0)
497+ *color = BLACK;
498+ else if (strcmp(color_string, "w") == 0
499+ || strcmp(color_string, "white") == 0)
500+ *color = WHITE;
501+ else
502+ return 0;
503+
504+ return n;
505+}
506+
507+
508+/* Convert an intersection given by a string to two coordinates
509+ * according to GNU Go's convention. Return the number of characters
510+ * read from the string s.
511+ */
512+int
513+gtp_decode_coord(char *s, int *i, int *j)
514+{
515+ char column;
516+ int row;
517+ int n;
518+
519+ assert(gtp_boardsize > 0);
520+
521+ if (sscanf(s, " %c%d%n", &column, &row, &n) != 2)
522+ return 0;
523+
524+ if (tolower((int) column) == 'i')
525+ return 0;
526+ *j = tolower((int) column) - 'a';
527+ if (tolower((int) column) > 'i')
528+ --*j;
529+
530+ *i = gtp_boardsize - row;
531+
532+ if (*i < 0 || *i >= gtp_boardsize || *j < 0 || *j >= gtp_boardsize)
533+ return 0;
534+
535+ return n;
536+}
537+
538+/* Convert a move, i.e. "b" or "w" followed by a vertex to a color and
539+ * coordinates. Return the number of characters read from the string
540+ * s.
541+ */
542+int
543+gtp_decode_move(char *s, int *color, int *i, int *j)
544+{
545+ int n1, n2;
546+
547+ assert(gtp_boardsize > 0);
548+
549+ n1 = gtp_decode_color(s, color);
550+ if (n1 == 0)
551+ return 0;
552+
553+ n2 = gtp_decode_coord(s + n1, i, j);
554+ if (n2 == 0)
555+ return 0;
556+
557+ return n1 + n2;
558+}
559+
560+/* This a bubble sort. Given the expected size of the sets to
561+ * sort, it's probably not worth the overhead to set up a call to
562+ * qsort.
563+ */
564+static void
565+sort_moves(int n, int movei[], int movej[])
566+{
567+ int b, a;
568+ for (b = n-1; b > 0; b--) {
569+ for (a = 0; a < b; a++) {
570+ if (movei[a] > movei[b]
571+ || (movei[a] == movei[b] && movej[a] > movej[b])) {
572+ int tmp;
573+ tmp = movei[b];
574+ movei[b] = movei[a];
575+ movei[a] = tmp;
576+ tmp = movej[b];
577+ movej[b] = movej[a];
578+ movej[a] = tmp;
579+ }
580+ }
581+ }
582+}
583+
584+/* Write a number of space separated vertices. The moves are sorted
585+ * before being written.
586+ */
587+void
588+gtp_print_vertices(int n, int movei[], int movej[])
589+{
590+ int k;
591+
592+ assert(gtp_boardsize > 0);
593+
594+ sort_moves(n, movei, movej);
595+ for (k = 0; k < n; k++) {
596+ if (k > 0)
597+ gtp_printf(" ");
598+ if ((movei[k] == -1 && movej[k] == -1)
599+ || (movei[k] == gtp_boardsize && movej[k] == gtp_boardsize))
600+ gtp_printf("PASS");
601+ else if (movei[k] < 0 || movei[k] >= gtp_boardsize
602+ || movej[k] < 0 || movej[k] >= gtp_boardsize) {
603+ gtp_printf("?? %d %d", movei[k], movej[k]);
604+ }
605+ else
606+ gtp_printf("%c%d", 'A' + movej[k] + (movej[k] >= 8),
607+ gtp_boardsize - movei[k]);
608+ }
609+}
610+
611+/* Write a single move. */
612+void
613+gtp_print_vertex(int i, int j)
614+{
615+ gtp_print_vertices(1, &i, &j);
616+}
617+
618+
619+/*
620+ * Local Variables:
621+ * tab-width: 8
622+ * c-basic-offset: 2
623+ * End:
624+ */
625diff -u -N -r -x *\.orig -x *\.info* ./interface/gtp.h ../gnugo-2.6.1/gnugo-2.6.1/interface/gtp.h
626--- ./interface/gtp.h Thu Jan 1 00:00:00 1970
627+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/gtp.h Sat Aug 4 00:10:58 2001
628@@ -0,0 +1,83 @@
629+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
630+ * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
631+ * http://www.gnu.org/software/gnugo/ for more information. *
632+ * *
633+ * To facilitate development of the Go Text Protocol, the two *
634+ * files gtp.c and gtp.h are licensed under less restrictive *
635+ * terms than the rest of GNU Go. *
636+ * *
637+ * Copyright 2001 by the Free Software Foundation. *
638+ * *
639+ * Permission is hereby granted, free of charge, to any person *
640+ * obtaining a copy of this file gtp.h, to deal in the Software *
641+ * without restriction, including without limitation the rights *
642+ * to use, copy, modify, merge, publish, distribute, and/or *
643+ * sell copies of the Software, and to permit persons to whom *
644+ * the Software is furnished to do so, provided that the above *
645+ * copyright notice(s) and this permission notice appear in all *
646+ * copies of the Software and that both the above copyright *
647+ * notice(s) and this permission notice appear in supporting *
648+ * documentation. *
649+ * *
650+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY *
651+ * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
652+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR *
653+ * PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO *
654+ * EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS *
655+ * NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR *
656+ * CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING *
657+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF *
658+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT *
659+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS *
660+ * SOFTWARE. *
661+ * *
662+ * Except as contained in this notice, the name of a copyright *
663+ * holder shall not be used in advertising or otherwise to *
664+ * promote the sale, use or other dealings in this Software *
665+ * without prior written authorization of the copyright holder. *
666+\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
667+
668+#include <stdarg.h>
669+
670+/* Maximum allowed line length in GTP. */
671+#define GTP_BUFSIZE 1000
672+
673+/* Status returned from callback functions. */
674+#define GTP_QUIT -1
675+#define GTP_OK 0
676+#define GTP_FATAL 1
677+
678+/* Whether the GTP command was successful. */
679+#define GTP_SUCCESS 0
680+#define GTP_FAILURE 1
681+
682+/* Function pointer for callback functions. */
683+typedef int (*gtp_fn_ptr)(char *s, int id);
684+
685+/* Elements in the array of commands required by gtp_main_loop. */
686+struct gtp_command {
687+ const char *name;
688+ gtp_fn_ptr function;
689+};
690+
691+void gtp_main_loop(struct gtp_command commands[]);
692+void gtp_internal_set_boardsize(int size);
693+void gtp_mprintf(const char *format, ...);
694+void gtp_printf(const char *format, ...);
695+void gtp_printid(int id, int status);
696+int gtp_finish_response(void);
697+int gtp_success(int id, const char *format, ...);
698+int gtp_failure(int id, const char *format, ...);
699+void gtp_panic(void);
700+int gtp_decode_color(char *s, int *color);
701+int gtp_decode_coord(char *s, int *m, int *n);
702+int gtp_decode_move(char *s, int *color, int *i, int *j);
703+void gtp_print_vertices(int n, int movei[], int movej[]);
704+void gtp_print_vertex(int i, int j);
705+
706+/*
707+ * Local Variables:
708+ * tab-width: 8
709+ * c-basic-offset: 2
710+ * End:
711+ */
712diff -u -N -r -x *\.orig -x *\.info* ./interface/interface.c ../gnugo-2.6.1/gnugo-2.6.1/interface/interface.c
713--- ./interface/interface.c Sat Feb 5 06:03:19 2000
714+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/interface.c Tue Aug 14 00:49:58 2001
715@@ -326,14 +326,14 @@
716 int
717 clear_board(board_t **board)
718 {
719- if(board==NULL)
720- {
721+ if (board==NULL) {
722 memset(p,EMPTY,sizeof(p));
723- }
724- else
725- {
726- memset(board,EMPTY,MAX_BOARD*MAX_BOARD*sizeof(board_t));
727- }
728+ }
729+ else {
730+ memset(board,EMPTY,MAX_BOARD*MAX_BOARD*sizeof(board_t));
731+ }
732+ white_captured = 0;
733+ black_captured = 0;
734 return 1;
735 }
736
737diff -u -N -r -x *\.orig -x *\.info* ./interface/interface.h ../gnugo-2.6.1/gnugo-2.6.1/interface/interface.h
738--- ./interface/interface.h Sat Feb 5 06:03:25 2000
739+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/interface.h Sat Aug 4 00:10:58 2001
740@@ -42,6 +42,7 @@
741 void play_ascii(char * filename);
742 void play_ascii_emacs(char * filename);
743 void play_gmp(void);
744+void play_gtp(void);
745 void play_solo(int);
746 void play_test(struct SGFNode *, enum testmode);
747 int load_sgf_file(struct SGFNode *, const char *untilstr);
748diff -u -N -r -x *\.orig -x *\.info* ./interface/main.c ../gnugo-2.6.1/gnugo-2.6.1/interface/main.c
749--- ./interface/main.c Sat Feb 12 04:37:42 2000
750+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/main.c Sat Aug 4 00:10:58 2001
751@@ -79,7 +79,7 @@
752 Usage : gnugo [-opts]\n\
753 \n\
754 Main Options:\n\
755- --mode <mode> Force the playing mode ('ascii', 'test' or 'gmp').\n\
756+ --mode <mode> Select mode ('ascii', 'test, 'gmp', 'gtp').\n\
757 Default is ASCII.\n\
758 If no terminal is detected GMP (Go Modem Protocol)\n\
759 will be assumed.\n\
760@@ -185,6 +185,7 @@
761 MODE_ASCII,
762 MODE_ASCII_EMACS,
763 MODE_GMP,
764+ MODE_GTP,
765 MODE_SGF,
766 MODE_LOAD_AND_ANALYZE,
767 MODE_LOAD_AND_SCORE,
768@@ -482,6 +483,7 @@
769 if (strcmp(optarg,"ascii")==0) playmode = MODE_ASCII;
770 else if (strcmp(optarg,"emacs")==0) playmode = MODE_ASCII_EMACS;
771 else if (strcmp(optarg,"gmp")==0) playmode = MODE_GMP;
772+ else if (strcmp(optarg,"gtp")==0) playmode = MODE_GTP;
773 else if (strcmp(optarg,"test")==0) playmode = MODE_TEST;
774 else {
775 fprintf(stderr,"Invalid mode selection: %s\n",optarg);
776@@ -718,6 +720,10 @@
777 set_computer_player(NONE);
778 }
779 play_ascii_emacs(infile);
780+ break;
781+
782+ case MODE_GTP:
783+ play_gtp();
784 break;
785
786 case MODE_ASCII :
787diff -u -N -r -x *\.orig -x *\.info* ./interface/play_gtp.c ../gnugo-2.6.1/gnugo-2.6.1/interface/play_gtp.c
788--- ./interface/play_gtp.c Thu Jan 1 00:00:00 1970
789+++ ../gnugo-2.6.1/gnugo-2.6.1/interface/play_gtp.c Tue Aug 14 01:16:03 2001
790@@ -0,0 +1,377 @@
791+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
792+ * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
793+ * http://www.gnu.org/software/gnugo/ for more information. *
794+ * *
795+ * Copyright 1999, 2000, 2001 by the Free Software Foundation. *
796+ * *
797+ * This program is free software; you can redistribute it and/or *
798+ * modify it under the terms of the GNU General Public License *
799+ * as published by the Free Software Foundation - version 3. *
800+ * *
801+ * This program is distributed in the hope that it will be *
802+ * useful, but WITHOUT ANY WARRANTY; without even the implied *
803+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *
804+ * PURPOSE. See the GNU General Public License in file COPYING *
805+ * for more details. *
806+ * *
807+ * You should have received a copy of the GNU General Public *
808+ * License along with this program; if not, write to the Free *
809+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
810+ * Boston, MA 02111, USA. *
811+\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
812+
813+#ifdef HAVE_CONFIG_H
814+#include <config.h>
815+#endif
816+
817+#include <stdio.h>
818+#include <assert.h>
819+#include <ctype.h>
820+#include <string.h>
821+
822+#include "liberty.h"
823+#include "interface.h"
824+#include "gtp.h"
825+
826+#define MAXLIBS (2*(MAX_BOARD*MAX_BOARD + 1)/3)
827+#define UNUSED(x) x=x
828+
829+/* Internal state that's not part of the engine. */
830+int color_to_move;
831+float komi;
832+int handicap;
833+
834+#define DECLARE(func) static int func(char *s, int id)
835+
836+DECLARE(gtp_fixed_handicap);
837+DECLARE(gtp_genmove_black);
838+DECLARE(gtp_genmove_white);
839+DECLARE(gtp_name);
840+DECLARE(gtp_estimate_score);
841+DECLARE(gtp_playblack);
842+DECLARE(gtp_playwhite);
843+DECLARE(gtp_quit);
844+DECLARE(gtp_set_boardsize);
845+DECLARE(gtp_set_komi);
846+DECLARE(gtp_showboard);
847+DECLARE(gtp_version);
848+DECLARE(gtp_help);
849+float estimate_score(float komi);
850+
851+void play_gtp(void);
852+
853+/* List of known commands. */
854+static struct gtp_command commands[] = {
855+ {"black", gtp_playblack},
856+ {"boardsize", gtp_set_boardsize},
857+ {"fixed_handicap", gtp_fixed_handicap},
858+ {"genmove_black", gtp_genmove_black},
859+ {"genmove_white", gtp_genmove_white},
860+ {"help", gtp_help},
861+ {"komi", gtp_set_komi},
862+ {"name", gtp_name},
863+ {"estimate_score", gtp_estimate_score},
864+ {"quit", gtp_quit},
865+ {"showboard", gtp_showboard},
866+ {"version", gtp_version},
867+ {"white", gtp_playwhite},
868+ {NULL, NULL}
869+};
870+
871+
872+/* Start playing using the Go Text Protocol. */
873+void
874+play_gtp(void)
875+{
876+ /* Try to make sure that we have a useful level of buffering of stdout. */
877+#ifdef HAVE_SETLINEBUF
878+ setlinebuf(stdout);
879+#else
880+ setbuf(stdout, NULL);
881+#endif
882+
883+ gtp_internal_set_boardsize(19);
884+
885+ gtp_main_loop(commands);
886+}
887+
888+
889+/* Function: Quit
890+ * Arguments: none
891+ * Fails: never
892+ * Returns: nothing
893+ */
894+static int
895+gtp_quit(char *s, int id)
896+{
897+ UNUSED(s);
898+ gtp_success(id, "");
899+ return GTP_QUIT;
900+}
901+
902+
903+/****************************
904+ * Program identity. *
905+ ****************************/
906+
907+/* Function: Report the name of the program.
908+ * Arguments: none
909+ * Fails: never
910+ * Returns: program name
911+ */
912+static int
913+gtp_name(char *s, int id)
914+{
915+ UNUSED(s);
916+ return gtp_success(id, "GNU Go");
917+}
918+
919+
920+/* Function: Report the version number of the program.
921+ * Arguments: none
922+ * Fails: never
923+ * Returns: version number
924+ */
925+static int
926+gtp_version(char *s, int id)
927+{
928+ UNUSED(s);
929+ return gtp_success(id, VERSION);
930+}
931+
932+
933+/* Function: Set the board size to NxN and clear the board.
934+ * Arguments: integer
935+ * Fails: board size outside engine's limits
936+ * Returns: nothing
937+ */
938+static int
939+gtp_set_boardsize(char *s, int id)
940+{
941+ int boardsize;
942+ if (sscanf(s, "%d", &boardsize) < 1)
943+ return gtp_failure(id, "boardsize not an integer");
944+
945+ if (boardsize < MIN_BOARD || boardsize > MAX_BOARD)
946+ return gtp_failure(id, "unacceptable boardsize");
947+
948+ set_boardsize(boardsize);
949+ clear_board(NULL);
950+ gtp_internal_set_boardsize(boardsize);
951+ return gtp_success(id, "");
952+}
953+
954+
955+/* Function: Set the komi.
956+ * Arguments: float
957+ * Fails: incorrect argument
958+ * Returns: nothing
959+ */
960+static int
961+gtp_set_komi(char *s, int id)
962+{
963+ if (sscanf(s, "%f", &komi) < 1)
964+ return gtp_failure(id, "komi not a float");
965+
966+ return gtp_success(id, "");
967+}
968+
969+
970+/* Function: Play a black stone at the given vertex.
971+ * Arguments: vertex
972+ * Fails: invalid vertex, illegal move
973+ * Returns: nothing
974+ */
975+static int
976+gtp_playblack(char *s, int id)
977+{
978+ int i, j;
979+ char *c;
980+
981+ for (c = s; *c; c++)
982+ *c = tolower(*c);
983+
984+ if (strncmp(s, "pass", 4) == 0) {
985+ i = get_boardsize();
986+ j = get_boardsize();
987+ }
988+ else if (!gtp_decode_coord(s, &i, &j))
989+ return gtp_failure(id, "invalid coordinate");
990+
991+ if (!legal(i, j, BLACK))
992+ return gtp_failure(id, "illegal move");
993+
994+ updateboard(i, j, BLACK);
995+ return gtp_success(id, "");
996+}
997+
998+
999+/* Function: Play a white stone at the given vertex.
1000+ * Arguments: vertex
1001+ * Fails: invalid vertex, illegal move
1002+ * Returns: nothing
1003+ */
1004+static int
1005+gtp_playwhite(char *s, int id)
1006+{
1007+ int i, j;
1008+ char *c;
1009+
1010+ for (c = s; *c; c++)
1011+ *c = tolower(*c);
1012+
1013+ if (strncmp(s, "pass", 4) == 0) {
1014+ i = get_boardsize();
1015+ j = get_boardsize();
1016+ }
1017+ else if (!gtp_decode_coord(s, &i, &j))
1018+ return gtp_failure(id, "invalid coordinate");
1019+
1020+ if (!legal(i, j, WHITE))
1021+ return gtp_failure(id, "illegal move");
1022+
1023+ updateboard(i, j, WHITE);
1024+ return gtp_success(id, "");
1025+}
1026+
1027+
1028+/* Function: Set up fixed placement handicap stones.
1029+ * Arguments: number of handicap stones
1030+ * Fails: invalid number of stones for the current boardsize
1031+ * Returns: list of vertices with handicap stones
1032+ */
1033+static int
1034+gtp_fixed_handicap(char *s, int id)
1035+{
1036+ int m, n;
1037+ int first = 1;
1038+ int handicap;
1039+ if (sscanf(s, "%d", &handicap) < 1)
1040+ return gtp_failure(id, "handicap not an integer");
1041+
1042+ clear_board(NULL);
1043+ if (sethand(handicap) != handicap)
1044+ return gtp_failure(id, "invalid handicap");
1045+
1046+ gtp_printid(id, GTP_SUCCESS);
1047+
1048+ for (m = 0; m < board_size; m++)
1049+ for (n = 0; n < board_size; n++)
1050+ if (p[m][n] != EMPTY) {
1051+ if (!first)
1052+ gtp_printf(" ");
1053+ else
1054+ first = 0;
1055+ gtp_mprintf("%m", m, n);
1056+ }
1057+
1058+ return gtp_finish_response();
1059+}
1060+
1061+
1062+/* Function: Generate and play the supposedly best black move.
1063+ * Arguments: none
1064+ * Fails: never
1065+ * Returns: a move coordinate (or "PASS")
1066+ */
1067+static int
1068+gtp_genmove_black(char *s, int id)
1069+{
1070+ int i, j;
1071+ UNUSED(s);
1072+
1073+ if (genmove(&i, &j, BLACK) >= 0)
1074+ updateboard(i, j, BLACK);
1075+
1076+ gtp_printid(id, GTP_SUCCESS);
1077+ gtp_print_vertex(i, j);
1078+ return gtp_finish_response();
1079+}
1080+
1081+
1082+
1083+
1084+/* Function: Generate and play the supposedly best white move.
1085+ * Arguments: none
1086+ * Fails: never
1087+ * Returns: a move coordinate (or "PASS")
1088+ */
1089+static int
1090+gtp_genmove_white(char *s, int id)
1091+{
1092+ int i, j;
1093+ UNUSED(s);
1094+ if (genmove(&i, &j, WHITE) >= 0)
1095+ updateboard(i, j, WHITE);
1096+
1097+ gtp_printid(id, GTP_SUCCESS);
1098+ gtp_print_vertex(i, j);
1099+ return gtp_finish_response();
1100+}
1101+
1102+static int
1103+gtp_estimate_score(char *s, int id)
1104+{
1105+ int i, j;
1106+ float score;
1107+ UNUSED(s);
1108+
1109+ genmove(&i, &j, BLACK);
1110+ score = estimate_score(komi);
1111+
1112+ gtp_printid(id, GTP_SUCCESS);
1113+ if (score > 0.0)
1114+ gtp_printf("W+%3.1f (upper bound: %3.1f, lower: %3.1f)",
1115+ score, score, score);
1116+ else if (score < 0.0)
1117+ gtp_printf("B+%3.1f (upper bound: %3.1f, lower: %3.1f)",
1118+ -score, score, score);
1119+ else
1120+ gtp_printf("0");
1121+ return gtp_finish_response();
1122+}
1123+
1124+
1125+/* Function: Write the position to stderr.
1126+ * Arguments: none
1127+ * Fails: never
1128+ * Returns: nothing
1129+ */
1130+static int
1131+gtp_showboard(char *s, int id)
1132+{
1133+ UNUSED(s);
1134+ showboard(1);
1135+ return gtp_success(id, "");
1136+}
1137+
1138+
1139+/* Function: List all known commands
1140+ * Arguments: none
1141+ * Fails: never
1142+ * Returns: list of known commands, one per line
1143+ */
1144+static int
1145+gtp_help(char *s, int id)
1146+{
1147+ int k;
1148+ UNUSED(s);
1149+
1150+ gtp_printid(id, GTP_SUCCESS);
1151+
1152+ for (k = 0; commands[k].name != NULL; k++)
1153+ gtp_printf("%s\n", commands[k].name);
1154+
1155+ gtp_printf("\n");
1156+ return GTP_OK;
1157+}
1158+
1159+
1160+
1161+
1162+/*
1163+ * Local Variables:
1164+ * tab-width: 8
1165+ * c-basic-offset: 2
1166+ * End:
1167+ */