Commit | Line | Data |
---|---|---|
7eeb782e AT |
1 | This patch to GNU Go 2.6 allows it to play with the Go Text Protocol. |
2 | ||
3 | ||
4 | ||
5 | ||
6 | diff -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 | ||
18 | diff -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 | ||
47 | diff -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 | |
71 | diff -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 | ||
95 | diff -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 | } | |
131 | diff -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 | } | |
142 | diff -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 | ||
157 | diff -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 | |
204 | diff -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 | + */ | |
625 | diff -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 | + */ | |
712 | diff -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 | ||
737 | diff -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); | |
748 | diff -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 : | |
787 | diff -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 | + */ |