1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2  * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see       *
3  * http://www.gnu.org/software/gnugo/ for more information.          *
4  *                                                                   *
5  * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,   *
6  * 2008 and 2009 by the Free Software Foundation.                    *
7  *                                                                   *
8  * This program is free software; you can redistribute it and/or     *
9  * modify it under the terms of the GNU General Public License as    *
10  * published by the Free Software Foundation - version 3 or          *
11  * (at your option) any later version.                               *
12  *                                                                   *
13  * This program is distributed in the hope that it will be useful,   *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     *
16  * GNU General Public License in file COPYING for more details.      *
17  *                                                                   *
18  * You should have received a copy of the GNU General Public         *
19  * License along with this program; if not, write to the Free        *
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,       *
21  * Boston, MA 02111, USA.                                            *
22 \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23 
24 #include "gnugo.h"
25 
26 #include <stdio.h>
27 #include <assert.h>
28 #include <ctype.h>
29 #include <string.h>
30 #include <math.h>
31 
32 #include "interface.h"
33 #include "liberty.h"
34 #include "gtp.h"
35 #include "gg_utils.h"
36 
37 /* Internal state that's not part of the engine. */
38 static int report_uncertainty = 0;
39 static int gtp_orientation = 0;
40 
41 static void gtp_print_code(int c);
42 static void gtp_print_vertices2(int n, int *moves);
43 static void rotate_on_input(int ai, int aj, int *bi, int *bj);
44 static void rotate_on_output(int ai, int aj, int *bi, int *bj);
45 
46 
47 #define DECLARE(func) static int func(char *s)
48 
49 DECLARE(gtp_aa_confirm_safety);
50 DECLARE(gtp_accurate_approxlib);
51 DECLARE(gtp_accuratelib);
52 DECLARE(gtp_advance_random_seed);
53 DECLARE(gtp_all_legal);
54 DECLARE(gtp_all_move_values);
55 DECLARE(gtp_analyze_eyegraph);
56 DECLARE(gtp_analyze_semeai);
57 DECLARE(gtp_analyze_semeai_after_move);
58 DECLARE(gtp_attack);
59 DECLARE(gtp_attack_either);
60 DECLARE(gtp_block_off);
61 DECLARE(gtp_break_in);
62 DECLARE(gtp_captures);
63 DECLARE(gtp_clear_board);
64 DECLARE(gtp_clear_cache);
65 DECLARE(gtp_combination_attack);
66 DECLARE(gtp_combination_defend);
67 DECLARE(gtp_connect);
68 DECLARE(gtp_countlib);
69 DECLARE(gtp_cputime);
70 DECLARE(gtp_decrease_depths);
71 DECLARE(gtp_defend);
72 DECLARE(gtp_defend_both);
73 DECLARE(gtp_disconnect);
74 DECLARE(gtp_does_attack);
75 DECLARE(gtp_does_defend);
76 DECLARE(gtp_does_surround);
77 DECLARE(gtp_dragon_data);
78 DECLARE(gtp_dragon_status);
79 DECLARE(gtp_dragon_stones);
80 DECLARE(gtp_draw_search_area);
81 DECLARE(gtp_dump_stack);
82 DECLARE(gtp_echo);
83 DECLARE(gtp_echo_err);
84 DECLARE(gtp_estimate_score);
85 DECLARE(gtp_eval_eye);
86 DECLARE(gtp_experimental_score);
87 DECLARE(gtp_eye_data);
88 DECLARE(gtp_final_score);
89 DECLARE(gtp_final_status);
90 DECLARE(gtp_final_status_list);
91 DECLARE(gtp_findlib);
92 DECLARE(gtp_finish_sgftrace);
93 DECLARE(gtp_fixed_handicap);
94 DECLARE(gtp_followup_influence);
95 DECLARE(gtp_genmove);
96 DECLARE(gtp_genmove_black);
97 DECLARE(gtp_genmove_white);
98 DECLARE(gtp_get_connection_node_counter);
99 DECLARE(gtp_get_handicap);
100 DECLARE(gtp_get_komi);
101 DECLARE(gtp_get_life_node_counter);
102 DECLARE(gtp_get_owl_node_counter);
103 DECLARE(gtp_get_random_seed);
104 DECLARE(gtp_get_reading_node_counter);
105 DECLARE(gtp_get_trymove_counter);
106 DECLARE(gtp_gg_genmove);
107 DECLARE(gtp_gg_undo);
108 DECLARE(gtp_half_eye_data);
109 DECLARE(gtp_increase_depths);
110 DECLARE(gtp_initial_influence);
111 DECLARE(gtp_invariant_hash);
112 DECLARE(gtp_invariant_hash_for_moves);
113 DECLARE(gtp_is_legal);
114 DECLARE(gtp_is_surrounded);
115 DECLARE(gtp_kgs_genmove_cleanup);
116 DECLARE(gtp_known_command);
117 DECLARE(gtp_ladder_attack);
118 DECLARE(gtp_last_move);
119 DECLARE(gtp_limit_search);
120 DECLARE(gtp_list_commands);
121 DECLARE(gtp_list_stones);
122 DECLARE(gtp_loadsgf);
123 DECLARE(gtp_move_influence);
124 DECLARE(gtp_move_probabilities);
125 DECLARE(gtp_move_reasons);
126 DECLARE(gtp_move_uncertainty);
127 DECLARE(gtp_move_history);
128 DECLARE(gtp_name);
129 DECLARE(gtp_owl_attack);
130 DECLARE(gtp_owl_connection_defends);
131 DECLARE(gtp_owl_defend);
132 DECLARE(gtp_owl_does_attack);
133 DECLARE(gtp_owl_does_defend);
134 DECLARE(gtp_owl_substantial);
135 DECLARE(gtp_owl_threaten_attack);
136 DECLARE(gtp_owl_threaten_defense);
137 DECLARE(gtp_place_free_handicap);
138 DECLARE(gtp_play);
139 DECLARE(gtp_playblack);
140 DECLARE(gtp_playwhite);
141 DECLARE(gtp_popgo);
142 DECLARE(gtp_printsgf);
143 DECLARE(gtp_program_version);
144 DECLARE(gtp_protocol_version);
145 DECLARE(gtp_query_boardsize);
146 DECLARE(gtp_query_orientation);
147 DECLARE(gtp_quit);
148 DECLARE(gtp_reg_genmove);
149 DECLARE(gtp_report_uncertainty);
150 DECLARE(gtp_reset_connection_node_counter);
151 DECLARE(gtp_reset_life_node_counter);
152 DECLARE(gtp_reset_owl_node_counter);
153 DECLARE(gtp_reset_reading_node_counter);
154 DECLARE(gtp_reset_search_mask);
155 DECLARE(gtp_reset_trymove_counter);
156 DECLARE(gtp_restricted_genmove);
157 DECLARE(gtp_same_dragon);
158 DECLARE(gtp_set_boardsize);
159 DECLARE(gtp_set_free_handicap);
160 DECLARE(gtp_set_komi);
161 DECLARE(gtp_set_level);
162 DECLARE(gtp_set_orientation);
163 DECLARE(gtp_set_random_seed);
164 DECLARE(gtp_set_search_diamond);
165 DECLARE(gtp_set_search_limit);
166 DECLARE(gtp_showboard);
167 DECLARE(gtp_start_sgftrace);
168 DECLARE(gtp_surround_map);
169 DECLARE(gtp_tactical_analyze_semeai);
170 DECLARE(gtp_test_eyeshape);
171 DECLARE(gtp_time_left);
172 DECLARE(gtp_time_settings);
173 DECLARE(gtp_top_moves);
174 DECLARE(gtp_top_moves_black);
175 DECLARE(gtp_top_moves_white);
176 DECLARE(gtp_tryko);
177 DECLARE(gtp_trymove);
178 DECLARE(gtp_tune_move_ordering);
179 DECLARE(gtp_unconditional_status);
180 DECLARE(gtp_undo);
181 DECLARE(gtp_what_color);
182 DECLARE(gtp_worm_cutstone);
183 DECLARE(gtp_worm_data);
184 DECLARE(gtp_worm_stones);
185 
186 /* List of known commands. */
187 static struct gtp_command commands[] = {
188   {"aa_confirm_safety",       gtp_aa_confirm_safety},
189   {"accurate_approxlib",      gtp_accurate_approxlib},
190   {"accuratelib",             gtp_accuratelib},
191   {"advance_random_seed",     gtp_advance_random_seed},
192   {"all_legal",        	      gtp_all_legal},
193   {"all_move_values",         gtp_all_move_values},
194   {"analyze_eyegraph", 	      gtp_analyze_eyegraph},
195   {"analyze_semeai",          gtp_analyze_semeai},
196   {"analyze_semeai_after_move", gtp_analyze_semeai_after_move},
197   {"attack",           	      gtp_attack},
198   {"attack_either",           gtp_attack_either},
199   {"black",            	      gtp_playblack},
200   {"block_off",		      gtp_block_off},
201   {"boardsize",        	      gtp_set_boardsize},
202   {"break_in",		      gtp_break_in},
203   {"captures",        	      gtp_captures},
204   {"clear_board",      	      gtp_clear_board},
205   {"clear_cache",	      gtp_clear_cache},
206   {"color",            	      gtp_what_color},
207   {"combination_attack",      gtp_combination_attack},
208   {"combination_defend",      gtp_combination_defend},
209   {"connect",         	      gtp_connect},
210   {"countlib",         	      gtp_countlib},
211   {"cputime",		      gtp_cputime},
212   {"decrease_depths",  	      gtp_decrease_depths},
213   {"defend",           	      gtp_defend},
214   {"defend_both",	      gtp_defend_both},
215   {"disconnect",       	      gtp_disconnect},
216   {"does_attack",             gtp_does_attack},
217   {"does_defend",             gtp_does_defend},
218   {"does_surround",           gtp_does_surround},
219   {"dragon_data",             gtp_dragon_data},
220   {"dragon_status",    	      gtp_dragon_status},
221   {"dragon_stones",           gtp_dragon_stones},
222   {"draw_search_area",        gtp_draw_search_area},
223   {"dump_stack",       	      gtp_dump_stack},
224   {"echo" ,                   gtp_echo},
225   {"echo_err" ,               gtp_echo_err},
226   {"estimate_score",          gtp_estimate_score},
227   {"eval_eye",         	      gtp_eval_eye},
228   {"experimental_score",      gtp_experimental_score},
229   {"eye_data",                gtp_eye_data},
230   {"final_score",             gtp_final_score},
231   {"final_status",            gtp_final_status},
232   {"final_status_list",       gtp_final_status_list},
233   {"findlib",          	      gtp_findlib},
234   {"finish_sgftrace",  	      gtp_finish_sgftrace},
235   {"fixed_handicap",   	      gtp_fixed_handicap},
236   {"followup_influence",      gtp_followup_influence},
237   {"genmove",                 gtp_genmove},
238   {"genmove_black",           gtp_genmove_black},
239   {"genmove_white",           gtp_genmove_white},
240   {"get_connection_node_counter", gtp_get_connection_node_counter},
241   {"get_handicap",   	      gtp_get_handicap},
242   {"get_komi",        	      gtp_get_komi},
243   {"get_life_node_counter",   gtp_get_life_node_counter},
244   {"get_owl_node_counter",    gtp_get_owl_node_counter},
245   {"get_random_seed",  	      gtp_get_random_seed},
246   {"get_reading_node_counter", gtp_get_reading_node_counter},
247   {"get_trymove_counter",     gtp_get_trymove_counter},
248   {"gg-undo",                 gtp_gg_undo},
249   {"gg_genmove",              gtp_gg_genmove},
250   {"half_eye_data",           gtp_half_eye_data},
251   {"help",                    gtp_list_commands},
252   {"increase_depths",  	      gtp_increase_depths},
253   {"initial_influence",       gtp_initial_influence},
254   {"invariant_hash_for_moves",gtp_invariant_hash_for_moves},
255   {"invariant_hash",   	      gtp_invariant_hash},
256   {"is_legal",         	      gtp_is_legal},
257   {"is_surrounded",           gtp_is_surrounded},
258   {"kgs-genmove_cleanup",     gtp_kgs_genmove_cleanup},
259   {"known_command",    	      gtp_known_command},
260   {"komi",        	      gtp_set_komi},
261   {"ladder_attack",    	      gtp_ladder_attack},
262   {"last_move",    	      gtp_last_move},
263   {"level",        	      gtp_set_level},
264   {"limit_search",     	      gtp_limit_search},
265   {"list_commands",    	      gtp_list_commands},
266   {"list_stones",    	      gtp_list_stones},
267   {"loadsgf",          	      gtp_loadsgf},
268   {"move_influence",          gtp_move_influence},
269   {"move_probabilities",      gtp_move_probabilities},
270   {"move_reasons",            gtp_move_reasons},
271   {"move_uncertainty",	      gtp_move_uncertainty},
272   {"move_history",	      gtp_move_history},
273   {"name",                    gtp_name},
274   {"new_score",               gtp_estimate_score},
275   {"orientation",     	      gtp_set_orientation},
276   {"owl_attack",     	      gtp_owl_attack},
277   {"owl_connection_defends",  gtp_owl_connection_defends},
278   {"owl_defend",     	      gtp_owl_defend},
279   {"owl_does_attack", 	      gtp_owl_does_attack},
280   {"owl_does_defend", 	      gtp_owl_does_defend},
281   {"owl_substantial", 	      gtp_owl_substantial},
282   {"owl_threaten_attack",     gtp_owl_threaten_attack},
283   {"owl_threaten_defense",    gtp_owl_threaten_defense},
284   {"place_free_handicap",     gtp_place_free_handicap},
285   {"play",            	      gtp_play},
286   {"popgo",            	      gtp_popgo},
287   {"printsgf",         	      gtp_printsgf},
288   {"protocol_version",        gtp_protocol_version},
289   {"query_boardsize",         gtp_query_boardsize},
290   {"query_orientation",       gtp_query_orientation},
291   {"quit",             	      gtp_quit},
292   {"reg_genmove",             gtp_reg_genmove},
293   {"report_uncertainty",      gtp_report_uncertainty},
294   {"reset_connection_node_counter", gtp_reset_connection_node_counter},
295   {"reset_life_node_counter", gtp_reset_life_node_counter},
296   {"reset_owl_node_counter",  gtp_reset_owl_node_counter},
297   {"reset_reading_node_counter", gtp_reset_reading_node_counter},
298   {"reset_search_mask",       gtp_reset_search_mask},
299   {"reset_trymove_counter",   gtp_reset_trymove_counter},
300   {"restricted_genmove",      gtp_restricted_genmove},
301   {"same_dragon",    	      gtp_same_dragon},
302   {"set_free_handicap",       gtp_set_free_handicap},
303   {"set_random_seed",  	      gtp_set_random_seed},
304   {"set_search_diamond",      gtp_set_search_diamond},
305   {"set_search_limit",        gtp_set_search_limit},
306   {"showboard",        	      gtp_showboard},
307   {"start_sgftrace",  	      gtp_start_sgftrace},
308   {"surround_map",            gtp_surround_map},
309   {"tactical_analyze_semeai", gtp_tactical_analyze_semeai},
310   {"test_eyeshape",           gtp_test_eyeshape},
311   {"time_left",               gtp_time_left},
312   {"time_settings",           gtp_time_settings},
313   {"top_moves",               gtp_top_moves},
314   {"top_moves_black",         gtp_top_moves_black},
315   {"top_moves_white",         gtp_top_moves_white},
316   {"tryko",          	      gtp_tryko},
317   {"trymove",          	      gtp_trymove},
318   {"tune_move_ordering",      gtp_tune_move_ordering},
319   {"unconditional_status",    gtp_unconditional_status},
320   {"undo",                    gtp_undo},
321   {"version",                 gtp_program_version},
322   {"white",            	      gtp_playwhite},
323   {"worm_cutstone",           gtp_worm_cutstone},
324   {"worm_data",               gtp_worm_data},
325   {"worm_stones",             gtp_worm_stones},
326   {NULL,                      NULL}
327 };
328 
329 
330 /* Start playing using the Go Text Protocol. */
331 void
play_gtp(FILE * gtp_input,FILE * gtp_output,FILE * gtp_dump_commands,int gtp_initial_orientation)332 play_gtp(FILE *gtp_input, FILE *gtp_output, FILE *gtp_dump_commands,
333 	 int gtp_initial_orientation)
334 {
335   /* Make sure `gtp_output' is unbuffered. (Line buffering is also
336    * okay but not necessary. Block buffering breaks GTP mode.)
337    *
338    * FIXME: Maybe should go to `gtp.c'?
339    */
340   setbuf(gtp_output, NULL);
341 
342   /* Inform the GTP utility functions about the board size. */
343   gtp_internal_set_boardsize(board_size);
344   gtp_orientation = gtp_initial_orientation;
345   gtp_set_vertex_transform_hooks(rotate_on_input, rotate_on_output);
346 
347   /* Initialize time handling. */
348   init_timers();
349 
350   /* Prepare pattern matcher and reading code. */
351   reset_engine();
352   clearstats();
353   gtp_main_loop(commands, gtp_input, gtp_output, gtp_dump_commands);
354   if (showstatistics)
355     showstats();
356 }
357 
358 
359 /****************************
360  * Administrative commands. *
361  ****************************/
362 
363 /* Function:  Quit
364  * Arguments: none
365  * Fails:     never
366  * Returns:   nothing
367  *
368  * Status:    GTP version 2 standard command.
369  */
370 static int
gtp_quit(char * s)371 gtp_quit(char *s)
372 {
373   UNUSED(s);
374   gtp_success("");
375   return GTP_QUIT;
376 }
377 
378 
379 /* Function:  Report protocol version.
380  * Arguments: none
381  * Fails:     never
382  * Returns:   protocol version number
383  *
384  * Status:    GTP version 2 standard command.
385  */
386 static int
gtp_protocol_version(char * s)387 gtp_protocol_version(char *s)
388 {
389   UNUSED(s);
390   return gtp_success("%d", gtp_version);
391 }
392 
393 
394 /****************************
395  * Program identity.        *
396  ****************************/
397 
398 /* Function:  Report the name of the program.
399  * Arguments: none
400  * Fails:     never
401  * Returns:   program name
402  *
403  * Status:    GTP version 2 standard command.
404  */
405 static int
gtp_name(char * s)406 gtp_name(char *s)
407 {
408   UNUSED(s);
409   return gtp_success("GNU Go");
410 }
411 
412 
413 
414 
415 /* Function:  Report the version number of the program.
416  * Arguments: none
417  * Fails:     never
418  * Returns:   version number
419  *
420  * Status:    GTP version 2 standard command.
421  */
422 static int
gtp_program_version(char * s)423 gtp_program_version(char *s)
424 {
425   UNUSED(s);
426   return gtp_success(VERSION);
427 }
428 
429 
430 /***************************
431  * Setting the board size. *
432  ***************************/
433 
434 /* Function:  Set the board size to NxN and clear the board.
435  * Arguments: integer
436  * Fails:     board size outside engine's limits
437  * Returns:   nothing
438  *
439  * Status:    GTP version 2 standard command.
440  */
441 static int
gtp_set_boardsize(char * s)442 gtp_set_boardsize(char *s)
443 {
444   int boardsize;
445 
446   if (sscanf(s, "%d", &boardsize) < 1)
447     return gtp_failure("boardsize not an integer");
448 
449   if (!check_boardsize(boardsize, NULL)) {
450     if (gtp_version == 1)
451       return gtp_failure("unacceptable boardsize");
452     else
453       return gtp_failure("unacceptable size");
454   }
455 
456   /* If this is called with a non-empty board, we assume that a new
457    * game will be started, for which we want a new random seed.
458    */
459   if (stones_on_board(BLACK | WHITE) > 0)
460     update_random_seed();
461 
462   board_size = boardsize;
463   clear_board();
464   gtp_internal_set_boardsize(boardsize);
465   reset_engine();
466   return gtp_success("");
467 }
468 
469 /* Function:  Find the current boardsize
470  * Arguments: none
471  * Fails:     never
472  * Returns:   board_size
473  */
474 static int
gtp_query_boardsize(char * s)475 gtp_query_boardsize(char *s)
476 {
477   UNUSED(s);
478 
479   return gtp_success("%d", board_size);
480 }
481 
482 /***********************
483  * Clearing the board. *
484  ***********************/
485 
486 /* Function:  Clear the board.
487  * Arguments: none
488  * Fails:     never
489  * Returns:   nothing
490  *
491  * Status:    GTP version 2 standard command.
492  */
493 static int
gtp_clear_board(char * s)494 gtp_clear_board(char *s)
495 {
496   UNUSED(s);
497 
498   /* If this is called with a non-empty board, we assume that a new
499    * game will be started, for which we want a new random seed.
500    */
501   if (stones_on_board(BLACK | WHITE) > 0)
502     update_random_seed();
503 
504   clear_board();
505   init_timers();
506 
507   return gtp_success("");
508 }
509 
510 /****************************
511  * Setting the orientation. *
512  ****************************/
513 
514 /* Function:  Set the orienation to N and clear the board
515  * Arguments: integer
516  * Fails:     illegal orientation
517  * Returns:   nothing
518  */
519 static int
gtp_set_orientation(char * s)520 gtp_set_orientation(char *s)
521 {
522   int orientation;
523   if (sscanf(s, "%d", &orientation) < 1)
524     return gtp_failure("orientation not an integer");
525 
526   if (orientation < 0 || orientation > 7)
527     return gtp_failure("unacceptable orientation");
528 
529   clear_board();
530   gtp_orientation = orientation;
531   gtp_set_vertex_transform_hooks(rotate_on_input, rotate_on_output);
532   return gtp_success("");
533 }
534 
535 /* Function:  Find the current orientation
536  * Arguments: none
537  * Fails:     never
538  * Returns:   orientation
539  */
540 static int
gtp_query_orientation(char * s)541 gtp_query_orientation(char *s)
542 {
543   UNUSED(s);
544 
545   return gtp_success("%d", gtp_orientation);
546 }
547 
548 /***************************
549  * Setting komi.           *
550  ***************************/
551 
552 /* Function:  Set the komi.
553  * Arguments: float
554  * Fails:     incorrect argument
555  * Returns:   nothing
556  *
557  * Status:    GTP version 2 standard command.
558  */
559 static int
gtp_set_komi(char * s)560 gtp_set_komi(char *s)
561 {
562   if (sscanf(s, "%f", &komi) < 1)
563     return gtp_failure("komi not a float");
564 
565   return gtp_success("");
566 }
567 
568 
569 /***************************
570  * Getting komi            *
571  ***************************/
572 
573 /* Function:  Get the komi
574  * Arguments: none
575  * Fails:     never
576  * Returns:   Komi
577  */
578 static int
gtp_get_komi(char * s)579 gtp_get_komi(char *s)
580 {
581   UNUSED(s);
582   return gtp_success("%4.1f", komi);
583 }
584 
585 
586 /******************
587  * Playing moves. *
588  ******************/
589 
590 /* Function:  Play a black stone at the given vertex.
591  * Arguments: vertex
592  * Fails:     invalid vertex, illegal move
593  * Returns:   nothing
594  *
595  * Status:    Obsolete GTP version 1 command.
596  */
597 static int
gtp_playblack(char * s)598 gtp_playblack(char *s)
599 {
600   int i, j;
601   char *c;
602 
603   for (c = s; *c; c++)
604     *c = tolower((int)*c);
605 
606   if (strncmp(s, "pass", 4) == 0) {
607     i = -1;
608     j = -1;
609   }
610   else if (!gtp_decode_coord(s, &i, &j))
611     return gtp_failure("invalid coordinate");
612 
613   if (!is_allowed_move(POS(i, j), BLACK))
614     return gtp_failure("illegal move");
615 
616   gnugo_play_move(POS(i, j), BLACK);
617   return gtp_success("");
618 }
619 
620 
621 /* Function:  Play a white stone at the given vertex.
622  * Arguments: vertex
623  * Fails:     invalid vertex, illegal move
624  * Returns:   nothing
625  *
626  * Status:    Obsolete GTP version 1 command.
627  */
628 static int
gtp_playwhite(char * s)629 gtp_playwhite(char *s)
630 {
631   int i, j;
632   char *c;
633 
634   for (c = s; *c; c++)
635     *c = tolower((int)*c);
636 
637   if (strncmp(s, "pass", 4) == 0) {
638     i = -1;
639     j = -1;
640   }
641   else if (!gtp_decode_coord(s, &i, &j))
642     return gtp_failure("invalid coordinate");
643 
644   if (!is_allowed_move(POS(i, j), WHITE))
645     return gtp_failure("illegal move");
646 
647   gnugo_play_move(POS(i, j), WHITE);
648   return gtp_success("");
649 }
650 
651 
652 /* Function:  Play a stone of the given color at the given vertex.
653  * Arguments: color, vertex
654  * Fails:     invalid vertex, illegal move
655  * Returns:   nothing
656  *
657  * Status:    GTP version 2 standard command.
658  */
659 static int
gtp_play(char * s)660 gtp_play(char *s)
661 {
662   int i, j;
663   int color;
664 
665   if (!gtp_decode_move(s, &color, &i, &j))
666     return gtp_failure("invalid color or coordinate");
667 
668   if (!is_allowed_move(POS(i, j), color))
669     return gtp_failure("illegal move");
670 
671   gnugo_play_move(POS(i, j), color);
672   return gtp_success("");
673 }
674 
675 
676 /* Function:  Set up fixed placement handicap stones.
677  * Arguments: number of handicap stones
678  * Fails:     invalid number of stones for the current boardsize
679  * Returns:   list of vertices with handicap stones
680  *
681  * Status:    GTP version 2 standard command.
682  */
683 static int
gtp_fixed_handicap(char * s)684 gtp_fixed_handicap(char *s)
685 {
686   int m, n;
687   int first = 1;
688   int this_handicap;
689 
690   if (gtp_version == 1)
691     clear_board();
692   else if (stones_on_board(BLACK | WHITE) > 0)
693     return gtp_failure("board not empty");
694 
695   if (sscanf(s, "%d", &this_handicap) < 1)
696     return gtp_failure("handicap not an integer");
697 
698   if (this_handicap < 2 && (gtp_version > 1 || this_handicap != 0))
699     return gtp_failure("invalid handicap");
700 
701   if (place_fixed_handicap(this_handicap) != this_handicap) {
702     clear_board();
703     return gtp_failure("invalid handicap");
704   }
705 
706   handicap = this_handicap;
707 
708   gtp_start_response(GTP_SUCCESS);
709 
710   for (m = 0; m < board_size; m++)
711     for (n = 0; n < board_size; n++)
712       if (BOARD(m, n) != EMPTY) {
713 	if (!first)
714 	  gtp_printf(" ");
715 	else
716 	  first = 0;
717 	gtp_mprintf("%m", m, n);
718       }
719 
720   return gtp_finish_response();
721 }
722 
723 
724 /* Function:  Choose free placement handicap stones and put them on the board.
725  * Arguments: number of handicap stones
726  * Fails:     invalid number of stones
727  * Returns:   list of vertices with handicap stones
728  *
729  * Status:    GTP version 2 standard command.
730  */
731 static int
gtp_place_free_handicap(char * s)732 gtp_place_free_handicap(char *s)
733 {
734   int m, n;
735   int first = 1;
736   int this_handicap;
737   if (sscanf(s, "%d", &this_handicap) < 1)
738     return gtp_failure("handicap not an integer");
739 
740   if (stones_on_board(BLACK | WHITE) > 0)
741     return gtp_failure("board not empty");
742 
743   if (this_handicap < 2)
744     return gtp_failure("invalid handicap");
745 
746   handicap = place_free_handicap(this_handicap);
747 
748   gtp_start_response(GTP_SUCCESS);
749 
750   for (m = 0; m < board_size; m++)
751     for (n = 0; n < board_size; n++)
752       if (BOARD(m, n) != EMPTY) {
753 	if (!first)
754 	  gtp_printf(" ");
755 	else
756 	  first = 0;
757 	gtp_mprintf("%m", m, n);
758       }
759 
760   return gtp_finish_response();
761 }
762 
763 
764 /* Function:  Put free placement handicap stones on the board.
765  * Arguments: list of vertices with handicap stones
766  * Fails:     board not empty, bad list of vertices
767  * Returns:   nothing
768  *
769  * Status:    GTP version 2 standard command.
770  */
771 static int
gtp_set_free_handicap(char * s)772 gtp_set_free_handicap(char *s)
773 {
774   int n;
775   int i, j;
776   int k;
777 
778   if (stones_on_board(BLACK | WHITE) > 0)
779     return gtp_failure("board not empty");
780 
781   for (k = 0; k < MAX_BOARD * MAX_BOARD; k++) {
782     n = gtp_decode_coord(s, &i, &j);
783     if (n > 0) {
784       if (board[POS(i, j)] != EMPTY) {
785 	clear_board();
786 	return gtp_failure("repeated vertex");
787       }
788       add_stone(POS(i, j), BLACK);
789       s += n;
790     }
791     else if (sscanf(s, "%*s") != EOF)
792       return gtp_failure("invalid coordinate");
793     else
794       break;
795   }
796 
797   if (k < 2) {
798     clear_board();
799     return gtp_failure("invalid handicap");
800   }
801 
802   handicap = k;
803 
804   return gtp_success("");
805 }
806 
807 
808 /* Function:  Get the handicap
809  * Arguments: none
810  * Fails:     never
811  * Returns:   handicap
812  */
813 static int
gtp_get_handicap(char * s)814 gtp_get_handicap(char *s)
815 {
816   UNUSED(s);
817   return gtp_success("%d", handicap);
818 }
819 
820 
821 /* Function:  Load an sgf file, possibly up to a move number or the first
822  *            occurence of a move.
823  * Arguments: filename + move number, vertex, or nothing
824  * Fails:     missing filename or failure to open or parse file
825  * Returns:   color to play
826  *
827  * Status:    GTP version 2 standard command.
828  */
829 static int
gtp_loadsgf(char * s)830 gtp_loadsgf(char *s)
831 {
832   char filename[GTP_BUFSIZE];
833   char untilstring[GTP_BUFSIZE];
834   SGFTree sgftree;
835   Gameinfo gameinfo;
836   int nread;
837   int color_to_move;
838 
839   nread = sscanf(s, "%s %s", filename, untilstring);
840   if (nread < 1)
841     return gtp_failure("missing filename");
842 
843   sgftree_clear(&sgftree);
844   if (!sgftree_readfile(&sgftree, filename))
845     return gtp_failure("cannot open or parse '%s'", filename);
846 
847   if (nread == 1)
848     color_to_move = gameinfo_play_sgftree_rot(&gameinfo, &sgftree, NULL,
849 					      gtp_orientation);
850   else
851     color_to_move = gameinfo_play_sgftree_rot(&gameinfo, &sgftree, untilstring,
852                                               gtp_orientation);
853 
854   if (color_to_move == EMPTY)
855     return gtp_failure("cannot load '%s'", filename);
856 
857   gtp_internal_set_boardsize(board_size);
858   reset_engine();
859   init_timers();
860 
861   sgfFreeNode(sgftree.root);
862 
863   gtp_start_response(GTP_SUCCESS);
864   gtp_mprintf("%C", color_to_move);
865   return gtp_finish_response();
866 }
867 
868 
869 /*****************
870  * Board status. *
871  *****************/
872 
873 /* Function:  Return the color at a vertex.
874  * Arguments: vertex
875  * Fails:     invalid vertex
876  * Returns:   "black", "white", or "empty"
877  */
878 static int
gtp_what_color(char * s)879 gtp_what_color(char *s)
880 {
881   int i, j;
882   if (!gtp_decode_coord(s, &i, &j))
883     return gtp_failure("invalid coordinate");
884 
885   return gtp_success(color_to_string(BOARD(i, j)));
886 }
887 
888 
889 /* Function:  List vertices with either black or white stones.
890  * Arguments: color
891  * Fails:     invalid color
892  * Returns:   list of vertices
893  */
894 static int
gtp_list_stones(char * s)895 gtp_list_stones(char *s)
896 {
897   int i, j;
898   int color = EMPTY;
899   int vertexi[MAX_BOARD * MAX_BOARD];
900   int vertexj[MAX_BOARD * MAX_BOARD];
901   int vertices = 0;
902 
903   if (!gtp_decode_color(s, &color))
904     return gtp_failure("invalid color");
905 
906   for (i = 0; i < board_size; i++)
907     for (j = 0; j < board_size; j++)
908       if (BOARD(i, j) == color) {
909 	vertexi[vertices] = i;
910 	vertexj[vertices++] = j;
911       }
912 
913   gtp_start_response(GTP_SUCCESS);
914   gtp_print_vertices(vertices, vertexi, vertexj);
915   return gtp_finish_response();
916 }
917 
918 
919 /* Function:  Count number of liberties for the string at a vertex.
920  * Arguments: vertex
921  * Fails:     invalid vertex, empty vertex
922  * Returns:   Number of liberties.
923  */
924 static int
gtp_countlib(char * s)925 gtp_countlib(char *s)
926 {
927   int i, j;
928   if (!gtp_decode_coord(s, &i, &j))
929     return gtp_failure("invalid coordinate");
930 
931   if (BOARD(i, j) == EMPTY)
932     return gtp_failure("vertex must not be empty");
933 
934   return gtp_success("%d", countlib(POS(i, j)));
935 }
936 
937 
938 /* Function:  Return the positions of the liberties for the string at a vertex.
939  * Arguments: vertex
940  * Fails:     invalid vertex, empty vertex
941  * Returns:   Sorted space separated list of vertices.
942  */
943 static int
gtp_findlib(char * s)944 gtp_findlib(char *s)
945 {
946   int i, j;
947   int libs[MAXLIBS];
948   int liberties;
949 
950   if (!gtp_decode_coord(s, &i, &j))
951     return gtp_failure("invalid coordinate");
952 
953   if (BOARD(i, j) == EMPTY)
954     return gtp_failure("vertex must not be empty");
955 
956   liberties = findlib(POS(i, j), MAXLIBS, libs);
957   gtp_start_response(GTP_SUCCESS);
958   gtp_print_vertices2(liberties, libs);
959   return gtp_finish_response();
960 }
961 
962 
963 /* Function:  Determine which liberties a stone of given color
964  *            will get if played at given vertex.
965  * Arguments: move (color + vertex)
966  * Fails:     invalid color, invalid vertex, occupied vertex
967  * Returns:   Sorted space separated list of liberties
968  */
969 static int
gtp_accuratelib(char * s)970 gtp_accuratelib(char *s)
971 {
972   int i, j;
973   int color;
974   int libs[MAXLIBS];
975   int liberties;
976 
977   if (!gtp_decode_move(s, &color, &i, &j))
978     return gtp_failure("invalid color or coordinate");
979 
980   if (BOARD(i, j) != EMPTY)
981     return gtp_failure("vertex must be empty");
982 
983   liberties = accuratelib(POS(i, j), color, MAXLIBS, libs);
984 
985   gtp_start_response(GTP_SUCCESS);
986   gtp_print_vertices2(liberties, libs);
987   return gtp_finish_response();
988 }
989 
990 
991 /* Function:  Determine which liberties a stone of given color
992  *            will get if played at given vertex.
993  * Arguments: move (color + vertex)
994  * Fails:     invalid color, invalid vertex, occupied vertex
995  * Returns:   Sorted space separated list of liberties
996  *
997  * Supposedly identical in behavior to the above function and
998  * can be retired when this is confirmed.
999  */
1000 static int
gtp_accurate_approxlib(char * s)1001 gtp_accurate_approxlib(char *s)
1002 {
1003   int i, j;
1004   int color;
1005   int libs[MAXLIBS];
1006   int liberties;
1007 
1008   if (!gtp_decode_move(s, &color, &i, &j))
1009     return gtp_failure("invalid color or coordinate");
1010 
1011   if (BOARD(i, j) != EMPTY)
1012     return gtp_failure("vertex must be empty");
1013 
1014   liberties = accuratelib(POS(i, j), color, MAXLIBS, libs);
1015 
1016   gtp_start_response(GTP_SUCCESS);
1017   gtp_print_vertices2(liberties, libs);
1018   return gtp_finish_response();
1019 }
1020 
1021 
1022 /* Function:  Tell whether a move is legal.
1023  * Arguments: move
1024  * Fails:     invalid move
1025  * Returns:   1 if the move is legal, 0 if it is not.
1026  */
1027 static int
gtp_is_legal(char * s)1028 gtp_is_legal(char *s)
1029 {
1030   int i, j;
1031   int color;
1032 
1033   if (!gtp_decode_move(s, &color, &i, &j))
1034     return gtp_failure("invalid color or coordinate");
1035 
1036   return gtp_success("%d", is_allowed_move(POS(i, j), color));
1037 }
1038 
1039 
1040 /* Function:  List all legal moves for either color.
1041  * Arguments: color
1042  * Fails:     invalid color
1043  * Returns:   Sorted space separated list of vertices.
1044  */
1045 static int
gtp_all_legal(char * s)1046 gtp_all_legal(char *s)
1047 {
1048   int i, j;
1049   int color;
1050   int movei[MAX_BOARD * MAX_BOARD];
1051   int movej[MAX_BOARD * MAX_BOARD];
1052   int moves = 0;
1053 
1054   if (!gtp_decode_color(s, &color))
1055     return gtp_failure("invalid color");
1056 
1057   for (i = 0; i < board_size; i++)
1058     for (j = 0; j < board_size; j++)
1059       if (BOARD(i, j) == EMPTY && is_allowed_move(POS(i, j), color)) {
1060 	movei[moves] = i;
1061 	movej[moves++] = j;
1062       }
1063 
1064   gtp_start_response(GTP_SUCCESS);
1065   gtp_print_vertices(moves, movei, movej);
1066   return gtp_finish_response();
1067 }
1068 
1069 
1070 /* Function:  List the number of captures taken by either color.
1071  * Arguments: color
1072  * Fails:     invalid color
1073  * Returns:   Number of captures.
1074  */
1075 static int
gtp_captures(char * s)1076 gtp_captures(char *s)
1077 {
1078   int color;
1079 
1080   if (!gtp_decode_color(s, &color))
1081     return gtp_failure("invalid color");
1082 
1083   if (color == BLACK)
1084     return gtp_success("%d", white_captured);
1085   else
1086     return gtp_success("%d", black_captured);
1087 }
1088 
1089 
1090 /* Function:  Return the last move.
1091  * Arguments: none
1092  * Fails:     no previous move known
1093  * Returns:   Color and vertex of last move.
1094  */
1095 static int
gtp_last_move(char * s)1096 gtp_last_move(char *s)
1097 {
1098   int pos;
1099   int color;
1100   UNUSED(s);
1101 
1102   if (move_history_pointer <= 0)
1103     return gtp_failure("no previous move known");
1104 
1105   pos = move_history_pos[move_history_pointer - 1];
1106   color = move_history_color[move_history_pointer - 1];
1107 
1108   gtp_start_response(GTP_SUCCESS);
1109   gtp_mprintf("%C %m", color, I(pos), J(pos));
1110   return gtp_finish_response();
1111 }
1112 
1113 /* Function:  Print the move history in reverse order
1114  * Arguments: none
1115  * Fails:     never
1116  * Returns:   List of moves played in reverse order in format:
1117  *            color move (one move per line)
1118  */
1119 static int
gtp_move_history(char * s)1120 gtp_move_history(char *s)
1121 {
1122   int k, pos, color;
1123   UNUSED(s);
1124 
1125   gtp_start_response(GTP_SUCCESS);
1126   if (move_history_pointer > 0)
1127     for (k = move_history_pointer-1; k >= 0; k--) {
1128       color = move_history_color[k];
1129       pos = move_history_pos[k];
1130       gtp_mprintf("%C %m\n", color, I(pos), J(pos));
1131     }
1132   else
1133     gtp_printf("\n");
1134   gtp_printf("\n");
1135   return GTP_OK;
1136 }
1137 
1138 
1139 /* Function:  Return the rotation/reflection invariant board hash.
1140  * Arguments: none
1141  * Fails:     never
1142  * Returns:   Invariant hash for the board as a hexadecimal number.
1143  */
1144 static int
gtp_invariant_hash(char * s)1145 gtp_invariant_hash(char *s)
1146 {
1147   Hash_data hash;
1148   UNUSED(s);
1149   hashdata_calc_orientation_invariant(&hash, board, board_ko_pos);
1150   return gtp_success("%s", hashdata_to_string(&hash));
1151 }
1152 
1153 
1154 /* Function:  Return the rotation/reflection invariant board hash
1155  *            obtained by playing all the possible moves for the
1156  *            given color.
1157  * Arguments: color
1158  * Fails:     invalid color
1159  * Returns:   List of moves + invariant hash as a hexadecimal number,
1160  *            one pair of move + hash per line.
1161  */
1162 static int
gtp_invariant_hash_for_moves(char * s)1163 gtp_invariant_hash_for_moves(char *s)
1164 {
1165   Hash_data hash;
1166   int color;
1167   int pos;
1168   int move_found = 0;
1169 
1170   if (!gtp_decode_color(s, &color))
1171     return gtp_failure("invalid color");
1172 
1173   gtp_start_response(GTP_SUCCESS);
1174 
1175   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
1176     if (board[pos] == EMPTY
1177 	&& trymove(pos, color, "gtp_invariant_hash_for_moves", NO_MOVE)) {
1178       hashdata_calc_orientation_invariant(&hash, board, board_ko_pos);
1179       gtp_mprintf("%m %s\n", I(pos), J(pos), hashdata_to_string(&hash));
1180       popgo();
1181       move_found = 1;
1182     }
1183   }
1184 
1185   if (!move_found)
1186     gtp_printf("\n");
1187 
1188   gtp_printf("\n");
1189   return GTP_OK;
1190 }
1191 
1192 
1193 
1194 /**********************
1195  * Retractable moves. *
1196  **********************/
1197 
1198 /* Function:  Play a stone of the given color at the given vertex.
1199  * Arguments: move (color + vertex)
1200  * Fails:     invalid color, invalid vertex, illegal move
1201  * Returns:   nothing
1202  */
1203 static int
gtp_trymove(char * s)1204 gtp_trymove(char *s)
1205 {
1206   int i, j;
1207   int color;
1208   if (!gtp_decode_move(s, &color, &i, &j))
1209     return gtp_failure("invalid color or coordinate");
1210 
1211   if (!trymove(POS(i, j), color, "gtp_trymove", NO_MOVE))
1212     return gtp_failure("illegal move");
1213 
1214   return gtp_success("");
1215 }
1216 
1217 /* Function:  Play a stone of the given color at the given vertex,
1218  *            allowing illegal ko capture.
1219  * Arguments: move (color + vertex)
1220  * Fails:     invalid color, invalid vertex, illegal move
1221  * Returns:   nothing
1222  */
1223 static int
gtp_tryko(char * s)1224 gtp_tryko(char *s)
1225 {
1226   int i, j;
1227   int color;
1228   if (!gtp_decode_move(s, &color, &i, &j) || POS(i, j) == PASS_MOVE)
1229     return gtp_failure("invalid color or coordinate");
1230 
1231   if (!tryko(POS(i, j), color, "gtp_tryko"))
1232     return gtp_failure("illegal move");
1233 
1234   return gtp_success("");
1235 }
1236 
1237 
1238 /* Function:  Undo a trymove or tryko.
1239  * Arguments: none
1240  * Fails:     stack empty
1241  * Returns:   nothing
1242  */
1243 static int
gtp_popgo(char * s)1244 gtp_popgo(char *s)
1245 {
1246   UNUSED(s);
1247 
1248   if (stackp == 0)
1249     return gtp_failure("Stack empty.");
1250 
1251   popgo();
1252   return gtp_success("");
1253 }
1254 
1255 /*********************
1256  * Caching	     *
1257  *********************/
1258 
1259 /* Function:  clear the caches.
1260  * Arguments: none.
1261  * Fails:     never.
1262  * Returns:   nothing.
1263  */
1264 
1265 static int
gtp_clear_cache(char * s)1266 gtp_clear_cache(char *s)
1267 {
1268   UNUSED(s);
1269   clear_persistent_caches();
1270   reading_cache_clear();
1271   return gtp_success("");
1272 }
1273 
1274 /*********************
1275  * Tactical reading. *
1276  *********************/
1277 
1278 /* Function:  Try to attack a string.
1279  * Arguments: vertex
1280  * Fails:     invalid vertex, empty vertex
1281  * Returns:   attack code followed by attack point if attack code nonzero.
1282  */
1283 static int
gtp_attack(char * s)1284 gtp_attack(char *s)
1285 {
1286   int i, j;
1287   int apos;
1288   int attack_code;
1289 
1290   if (!gtp_decode_coord(s, &i, &j))
1291     return gtp_failure("invalid coordinate");
1292 
1293   if (BOARD(i, j) == EMPTY)
1294     return gtp_failure("vertex must not be empty");
1295 
1296   attack_code = attack(POS(i, j), &apos);
1297   gtp_start_response(GTP_SUCCESS);
1298   gtp_print_code(attack_code);
1299   if (attack_code > 0) {
1300     gtp_printf(" ");
1301     gtp_print_vertex(I(apos), J(apos));
1302   }
1303   return gtp_finish_response();
1304 }
1305 
1306 
1307 /* Function:  Try to attack either of two strings
1308  * Arguments: two vertices
1309  * Fails:     invalid vertex, empty vertex
1310  * Returns:   attack code against the strings.  Guarantees there
1311  *            exists a move which will attack one of the two
1312  *            with attack_code, but does not return the move.
1313  */
1314 static int
gtp_attack_either(char * s)1315 gtp_attack_either(char *s)
1316 {
1317   int ai, aj;
1318   int bi, bj;
1319   int n;
1320   int acode;
1321 
1322   n = gtp_decode_coord(s, &ai, &aj);
1323   if (n == 0)
1324     return gtp_failure("invalid coordinate");
1325 
1326   if (BOARD(ai, aj) == EMPTY)
1327     return gtp_failure("string vertex must be empty");
1328 
1329   n = gtp_decode_coord(s + n, &bi, &bj);
1330   if (n == 0)
1331     return gtp_failure("invalid coordinate");
1332 
1333   if (BOARD(bi, bj) == EMPTY)
1334     return gtp_failure("string vertex must not be empty");
1335 
1336   acode = attack_either(POS(ai, aj), POS(bi, bj));
1337 
1338   gtp_start_response(GTP_SUCCESS);
1339   gtp_print_code(acode);
1340   return gtp_finish_response();
1341 }
1342 
1343 
1344 /* Function:  Try to defend a string.
1345  * Arguments: vertex
1346  * Fails:     invalid vertex, empty vertex
1347  * Returns:   defense code followed by defense point if defense code nonzero.
1348  */
1349 static int
gtp_defend(char * s)1350 gtp_defend(char *s)
1351 {
1352   int i, j;
1353   int dpos;
1354   int defend_code;
1355 
1356   if (!gtp_decode_coord(s, &i, &j))
1357     return gtp_failure("invalid coordinate");
1358 
1359   if (BOARD(i, j) == EMPTY)
1360     return gtp_failure("vertex must not be empty");
1361 
1362   defend_code = find_defense(POS(i, j), &dpos);
1363   gtp_start_response(GTP_SUCCESS);
1364   gtp_print_code(defend_code);
1365   if (defend_code > 0) {
1366     gtp_printf(" ");
1367     gtp_print_vertex(I(dpos), J(dpos));
1368   }
1369   return gtp_finish_response();
1370 }
1371 
1372 
1373 /* Function:  Examine whether a specific move attacks a string tactically.
1374  * Arguments: vertex (move), vertex (dragon)
1375  * Fails:     invalid vertex, empty vertex
1376  * Returns:   attack code
1377  */
1378 static int
gtp_does_attack(char * s)1379 gtp_does_attack(char *s)
1380 {
1381   int i, j;
1382   int ti, tj;
1383   int attack_code;
1384   int n;
1385 
1386   n = gtp_decode_coord(s, &ti, &tj);
1387   if (n == 0)
1388     return gtp_failure("invalid coordinate");
1389 
1390   if (BOARD(ti, tj) != EMPTY)
1391     return gtp_failure("move vertex must be empty");
1392 
1393   n = gtp_decode_coord(s + n, &i, &j);
1394   if (n == 0)
1395     return gtp_failure("invalid coordinate");
1396 
1397   if (BOARD(i, j) == EMPTY)
1398     return gtp_failure("string vertex must not be empty");
1399 
1400   /* to get the variations into the sgf file, clear the reading cache */
1401   if (sgf_dumptree)
1402     reading_cache_clear();
1403 
1404   attack_code = does_attack(POS(ti, tj), POS(i, j));
1405   gtp_start_response(GTP_SUCCESS);
1406   gtp_print_code(attack_code);
1407   return gtp_finish_response();
1408 }
1409 
1410 
1411 /* Function:  Examine whether a specific move defends a string tactically.
1412  * Arguments: vertex (move), vertex (dragon)
1413  * Fails:     invalid vertex, empty vertex
1414  * Returns:   attack code
1415  */
1416 static int
gtp_does_defend(char * s)1417 gtp_does_defend(char *s)
1418 {
1419   int i, j;
1420   int ti, tj;
1421   int defense_code;
1422   int n;
1423 
1424   n = gtp_decode_coord(s, &ti, &tj);
1425   if (n == 0)
1426     return gtp_failure("invalid coordinate");
1427 
1428   if (BOARD(ti, tj) != EMPTY)
1429     return gtp_failure("move vertex must be empty");
1430 
1431   n = gtp_decode_coord(s + n, &i, &j);
1432   if (n == 0)
1433     return gtp_failure("invalid coordinate");
1434 
1435   if (BOARD(i, j) == EMPTY)
1436     return gtp_failure("string vertex must not be empty");
1437 
1438   /* to get the variations into the sgf file, clear the reading cache */
1439   if (sgf_dumptree)
1440     reading_cache_clear();
1441 
1442   defense_code = does_defend(POS(ti, tj), POS(i, j));
1443   gtp_start_response(GTP_SUCCESS);
1444   gtp_print_code(defense_code);
1445   return gtp_finish_response();
1446 }
1447 
1448 
1449 /* Function:  Try to attack a string strictly in a ladder.
1450  * Arguments: vertex
1451  * Fails:     invalid vertex, empty vertex
1452  * Returns:   attack code followed by attack point if attack code nonzero.
1453  */
1454 static int
gtp_ladder_attack(char * s)1455 gtp_ladder_attack(char *s)
1456 {
1457   int i, j;
1458   int apos;
1459   int attack_code;
1460 
1461   if (!gtp_decode_coord(s, &i, &j))
1462     return gtp_failure("invalid coordinate");
1463 
1464   if (BOARD(i, j) == EMPTY)
1465     return gtp_failure("vertex must not be empty");
1466 
1467   if (countlib(POS(i, j)) != 2)
1468     return gtp_failure("string must have exactly 2 liberties");
1469 
1470   attack_code = simple_ladder(POS(i, j), &apos);
1471   gtp_start_response(GTP_SUCCESS);
1472   gtp_print_code(attack_code);
1473   if (attack_code > 0) {
1474     gtp_printf(" ");
1475     gtp_print_vertex(I(apos), J(apos));
1476   }
1477   return gtp_finish_response();
1478 }
1479 
1480 
1481 /* Function:  Increase depth values by one.
1482  * Arguments: none
1483  * Fails:     never
1484  * Returns:   nothing
1485  */
1486 static int
gtp_increase_depths(char * s)1487 gtp_increase_depths(char *s)
1488 {
1489   UNUSED(s);
1490   increase_depth_values();
1491   return gtp_success("");
1492 }
1493 
1494 
1495 /* Function:  Decrease depth values by one.
1496  * Arguments: none
1497  * Fails:     never
1498  * Returns:   nothing
1499  */
1500 static int
gtp_decrease_depths(char * s)1501 gtp_decrease_depths(char *s)
1502 {
1503   UNUSED(s);
1504   decrease_depth_values();
1505   return gtp_success("");
1506 }
1507 
1508 
1509 /******************
1510  * owl reading. *
1511  ******************/
1512 
1513 /* Function:  Try to attack a dragon.
1514  * Arguments: vertex
1515  * Fails:     invalid vertex, empty vertex
1516  * Returns:   attack code followed by attack point if attack code nonzero.
1517  */
1518 static int
gtp_owl_attack(char * s)1519 gtp_owl_attack(char *s)
1520 {
1521   int i, j;
1522   int attack_point;
1523   int attack_code;
1524   int result_certain;
1525   int kworm;
1526 
1527   if (!gtp_decode_coord(s, &i, &j))
1528     return gtp_failure("invalid coordinate");
1529 
1530   if (BOARD(i, j) == EMPTY)
1531     return gtp_failure("vertex must not be empty");
1532 
1533   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1534 
1535   /* to get the variations into the sgf file, clear the reading cache */
1536   if (sgf_dumptree)
1537     reading_cache_clear();
1538 
1539   attack_code = owl_attack(POS(i, j), &attack_point, &result_certain, &kworm);
1540   gtp_start_response(GTP_SUCCESS);
1541   gtp_print_code(attack_code);
1542   if (attack_code > 0) {
1543     gtp_printf(" ");
1544     gtp_print_vertex(I(attack_point), J(attack_point));
1545   }
1546   if (!result_certain && report_uncertainty)
1547     gtp_printf(" uncertain");
1548   return gtp_finish_response();
1549 }
1550 
1551 
1552 /* Function:  Try to defend a dragon.
1553  * Arguments: vertex
1554  * Fails:     invalid vertex, empty vertex
1555  * Returns:   defense code followed by defense point if defense code nonzero.
1556  */
1557 static int
gtp_owl_defend(char * s)1558 gtp_owl_defend(char *s)
1559 {
1560   int i, j;
1561   int defense_point;
1562   int defend_code;
1563   int result_certain;
1564   int kworm;
1565 
1566   if (!gtp_decode_coord(s, &i, &j))
1567     return gtp_failure("invalid coordinate");
1568 
1569   if (BOARD(i, j) == EMPTY)
1570     return gtp_failure("vertex must not be empty");
1571 
1572   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1573 
1574   /* to get the variations into the sgf file, clear the reading cache */
1575   if (sgf_dumptree)
1576     reading_cache_clear();
1577 
1578   defend_code = owl_defend(POS(i, j), &defense_point, &result_certain, &kworm);
1579   gtp_start_response(GTP_SUCCESS);
1580   gtp_print_code(defend_code);
1581   if (defend_code > 0) {
1582     gtp_printf(" ");
1583     gtp_print_vertex(I(defense_point), J(defense_point));
1584   }
1585   if (!result_certain && report_uncertainty)
1586     gtp_printf(" uncertain");
1587   return gtp_finish_response();
1588 }
1589 
1590 /* Function:  Try to attack a dragon in 2 moves.
1591  * Arguments: vertex
1592  * Fails:     invalid vertex, empty vertex
1593  * Returns:   attack code followed by the two attack points if
1594  *            attack code nonzero.
1595  */
1596 static int
gtp_owl_threaten_attack(char * s)1597 gtp_owl_threaten_attack(char *s)
1598 {
1599   int i, j;
1600   int attack_point1;
1601   int attack_point2;
1602   int attack_code;
1603 
1604   if (!gtp_decode_coord(s, &i, &j))
1605     return gtp_failure("invalid coordinate");
1606 
1607   if (BOARD(i, j) == EMPTY)
1608     return gtp_failure("vertex must not be empty");
1609 
1610   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1611 
1612   /* to get the variations into the sgf file, clear the reading cache */
1613   if (sgf_dumptree)
1614     reading_cache_clear();
1615 
1616   attack_code = owl_threaten_attack(POS(i, j), &attack_point1, &attack_point2);
1617   gtp_start_response(GTP_SUCCESS);
1618   gtp_print_code(attack_code);
1619   if (attack_code > 0) {
1620     gtp_printf(" ");
1621     gtp_print_vertex(I(attack_point1), J(attack_point1));
1622     gtp_printf(" ");
1623     gtp_print_vertex(I(attack_point2), J(attack_point2));
1624   }
1625   return gtp_finish_response();
1626 }
1627 
1628 
1629 /* Function:  Try to defend a dragon with 2 moves.
1630  * Arguments: vertex
1631  * Fails:     invalid vertex, empty vertex
1632  * Returns:   defense code followed by the 2 defense points if
1633  *            defense code nonzero.
1634  */
1635 static int
gtp_owl_threaten_defense(char * s)1636 gtp_owl_threaten_defense(char *s)
1637 {
1638   int i, j;
1639   int defense_point1;
1640   int defense_point2;
1641   int defend_code;
1642 
1643   if (!gtp_decode_coord(s, &i, &j))
1644     return gtp_failure("invalid coordinate");
1645 
1646   if (BOARD(i, j) == EMPTY)
1647     return gtp_failure("vertex must not be empty");
1648 
1649   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1650 
1651   /* to get the variations into the sgf file, clear the reading cache */
1652   if (sgf_dumptree)
1653     reading_cache_clear();
1654 
1655   defend_code = owl_threaten_defense(POS(i, j), &defense_point1,
1656 				     &defense_point2);
1657   gtp_start_response(GTP_SUCCESS);
1658   gtp_print_code(defend_code);
1659   if (defend_code > 0) {
1660     gtp_printf(" ");
1661     gtp_print_vertex(I(defense_point1), J(defense_point1));
1662     gtp_printf(" ");
1663     gtp_print_vertex(I(defense_point2), J(defense_point2));
1664   }
1665   return gtp_finish_response();
1666 }
1667 
1668 
1669 /* Function:  Examine whether a specific move attacks a dragon.
1670  * Arguments: vertex (move), vertex (dragon)
1671  * Fails:     invalid vertex, empty vertex
1672  * Returns:   attack code
1673  */
1674 static int
gtp_owl_does_attack(char * s)1675 gtp_owl_does_attack(char *s)
1676 {
1677   int i, j;
1678   int ti, tj;
1679   int attack_code;
1680   int kworm;
1681   int n;
1682 
1683   n = gtp_decode_coord(s, &ti, &tj);
1684   if (n == 0)
1685     return gtp_failure("invalid coordinate");
1686 
1687   if (BOARD(ti, tj) != EMPTY)
1688     return gtp_failure("move vertex must be empty");
1689 
1690   n = gtp_decode_coord(s + n, &i, &j);
1691   if (n == 0)
1692     return gtp_failure("invalid coordinate");
1693 
1694   if (BOARD(i, j) == EMPTY)
1695     return gtp_failure("dragon vertex must not be empty");
1696 
1697   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1698 
1699   /* to get the variations into the sgf file, clear the reading cache */
1700   if (sgf_dumptree)
1701     reading_cache_clear();
1702 
1703   attack_code = owl_does_attack(POS(ti, tj), POS(i, j), &kworm);
1704   gtp_start_response(GTP_SUCCESS);
1705   gtp_print_code(attack_code);
1706   return gtp_finish_response();
1707 }
1708 
1709 
1710 /* Function:  Examine whether a specific move defends a dragon.
1711  * Arguments: vertex (move), vertex (dragon)
1712  * Fails:     invalid vertex, empty vertex
1713  * Returns:   defense code
1714  */
1715 static int
gtp_owl_does_defend(char * s)1716 gtp_owl_does_defend(char *s)
1717 {
1718   int i, j;
1719   int ti, tj;
1720   int defense_code;
1721   int kworm;
1722   int n;
1723 
1724   n = gtp_decode_coord(s, &ti, &tj);
1725   if (n == 0)
1726     return gtp_failure("invalid coordinate");
1727 
1728   if (BOARD(ti, tj) != EMPTY)
1729     return gtp_failure("move vertex must be empty");
1730 
1731   n = gtp_decode_coord(s + n, &i, &j);
1732   if (n == 0)
1733     return gtp_failure("invalid coordinate");
1734 
1735   if (BOARD(i, j) == EMPTY)
1736     return gtp_failure("dragon vertex must not be empty");
1737 
1738   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1739 
1740   /* to get the variations into the sgf file, clear the reading cache */
1741   if (sgf_dumptree)
1742     reading_cache_clear();
1743 
1744   defense_code = owl_does_defend(POS(ti, tj), POS(i, j), &kworm);
1745   gtp_start_response(GTP_SUCCESS);
1746   gtp_print_code(defense_code);
1747   return gtp_finish_response();
1748 }
1749 
1750 
1751 /* Function:  Examine whether a connection defends involved dragons.
1752  * Arguments: vertex (move), vertex (dragon1), vertex (dragon2)
1753  * Fails:     invalid vertex, empty vertex
1754  * Returns:   defense code
1755  */
1756 static int
gtp_owl_connection_defends(char * s)1757 gtp_owl_connection_defends(char *s)
1758 {
1759   int ai, aj;
1760   int bi, bj;
1761   int ti, tj;
1762   int defense_code;
1763   int n;
1764 
1765   n = gtp_decode_coord(s, &ti, &tj);
1766   if (n == 0)
1767     return gtp_failure("invalid coordinate");
1768 
1769   if (BOARD(ti, tj) != EMPTY)
1770     return gtp_failure("move vertex must be empty");
1771 
1772   s += n;
1773   n = gtp_decode_coord(s, &ai, &aj);
1774   if (n == 0)
1775     return gtp_failure("invalid coordinate");
1776 
1777   s += n;
1778   n = gtp_decode_coord(s, &bi, &bj);
1779   if (n == 0)
1780     return gtp_failure("invalid coordinate");
1781 
1782   if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY)
1783     return gtp_failure("dragon vertex must not be empty");
1784 
1785   if (BOARD(ai, aj) != BOARD(bi, bj))
1786     return gtp_failure("dragon vertices must have the same color");
1787 
1788   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1789 
1790   /* to get the variations into the sgf file, clear the reading cache */
1791   if (sgf_dumptree)
1792     reading_cache_clear();
1793 
1794   defense_code = owl_connection_defends(POS(ti, tj), POS(ai, aj), POS(bi, bj));
1795   gtp_start_response(GTP_SUCCESS);
1796   gtp_print_code(defense_code);
1797   return gtp_finish_response();
1798 }
1799 
1800 
1801 /* Function:  Try to defend both of two strings
1802  * Arguments: two vertices
1803  * Fails:     invalid vertex, empty vertex
1804  * Returns:   defend code for the strings.  Guarantees there
1805  *            exists a move which will defend both of the two
1806  *            with defend_code, but does not return the move.
1807  */
1808 static int
gtp_defend_both(char * s)1809 gtp_defend_both(char *s)
1810 {
1811   int ai, aj;
1812   int bi, bj;
1813   int n;
1814   int dcode;
1815 
1816   n = gtp_decode_coord(s, &ai, &aj);
1817   if (n == 0)
1818     return gtp_failure("invalid coordinate");
1819 
1820   if (BOARD(ai, aj) == EMPTY)
1821     return gtp_failure("string vertex must be empty");
1822 
1823   n = gtp_decode_coord(s + n, &bi, &bj);
1824   if (n == 0)
1825     return gtp_failure("invalid coordinate");
1826 
1827   if (BOARD(bi, bj) == EMPTY)
1828     return gtp_failure("string vertex must not be empty");
1829 
1830   dcode = defend_both(POS(ai, aj), POS(bi, bj));
1831 
1832   gtp_start_response(GTP_SUCCESS);
1833   gtp_print_code(dcode);
1834   return gtp_finish_response();
1835 }
1836 
1837 
1838 
1839 /* Function:  Determine whether capturing a string gives a living dragon
1840  * Arguments: vertex
1841  * Fails:     invalid vertex, empty vertex
1842  * Returns:   1 if dragon can live, 0 otherwise
1843  */
1844 static int
gtp_owl_substantial(char * s)1845 gtp_owl_substantial(char *s)
1846 {
1847   int i, j;
1848   int result;
1849 
1850   if (!gtp_decode_coord(s, &i, &j))
1851     return gtp_failure("invalid coordinate");
1852 
1853   if (BOARD(i, j) == EMPTY)
1854     return gtp_failure("vertex must not be empty");
1855 
1856   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1857 
1858   /* to get the variations into the sgf file, clear the reading cache */
1859   if (sgf_dumptree)
1860     reading_cache_clear();
1861 
1862   result = owl_substantial(POS(i, j));
1863   return gtp_success("%d", result);
1864 }
1865 
1866 
1867 /* Function:  Analyze a semeai
1868  * Arguments: dragona, dragonb
1869  * Fails:     invalid vertices, empty vertices
1870  * Returns:   semeai defense result, semeai attack result, semeai move
1871  */
1872 static int
gtp_analyze_semeai(char * s)1873 gtp_analyze_semeai(char *s)
1874 {
1875   int i, j;
1876   int k;
1877   int dragona, dragonb;
1878   int resulta, resultb, move, result_certain;
1879 
1880   k = gtp_decode_coord(s, &i, &j);
1881 
1882   if (k == 0)
1883     return gtp_failure("invalid coordinate");
1884   dragona = POS(i, j);
1885   if (BOARD(i, j) == EMPTY)
1886     return gtp_failure("vertex must not be empty");
1887 
1888   if (!gtp_decode_coord(s+k, &i, &j))
1889     return gtp_failure("invalid coordinate");
1890   dragonb = POS(i, j);
1891   if (BOARD(i, j) == EMPTY)
1892     return gtp_failure("vertex must not be empty");
1893 
1894   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1895   /* to get the variations into the sgf file, clear the reading cache */
1896   if (sgf_dumptree)
1897     reading_cache_clear();
1898 
1899   owl_analyze_semeai(dragona, dragonb, &resulta, &resultb, &move, 1,
1900   		     &result_certain);
1901   gtp_start_response(GTP_SUCCESS);
1902   gtp_print_code(resulta);
1903   gtp_printf(" ");
1904   gtp_print_code(resultb);
1905   gtp_mprintf(" %m", I(move), J(move));
1906   if (!result_certain && report_uncertainty)
1907     gtp_printf(" uncertain");
1908 
1909   return gtp_finish_response();
1910 }
1911 
1912 
1913 /* Function:  Analyze a semeai after a move have been made.
1914  * Arguments: color, vertex, dragona, dragonb
1915  * Fails:     invalid vertices
1916  * Returns:   semeai defense result, semeai attack result, semeai move
1917  */
1918 static int
gtp_analyze_semeai_after_move(char * s)1919 gtp_analyze_semeai_after_move(char *s)
1920 {
1921   int i, j;
1922   int color;
1923   int move;
1924   int k;
1925   int dragona, dragonb;
1926   int resulta, resultb, semeai_move, result_certain;
1927 
1928   k = gtp_decode_move(s, &color, &i, &j);
1929   move = POS(i, j);
1930   if (k == 0 || move == NO_MOVE)
1931     return gtp_failure("invalid color or coordinate");
1932   if (board[move] != EMPTY)
1933     return gtp_failure("move vertex is not empty");
1934   s += k;
1935 
1936   k = gtp_decode_coord(s, &i, &j);
1937   if (k == 0)
1938     return gtp_failure("invalid coordinate");
1939   dragona = POS(i, j);
1940   if (board[dragona] == EMPTY)
1941     return gtp_failure("dragon vertex must not be empty");
1942   s += k;
1943 
1944   if (!gtp_decode_coord(s, &i, &j))
1945     return gtp_failure("invalid coordinate");
1946   dragonb = POS(i, j);
1947   if (board[dragonb] == EMPTY)
1948     return gtp_failure("dragon vertex must not be empty");
1949 
1950   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1951   /* to get the variations into the sgf file, clear the reading cache */
1952   if (sgf_dumptree)
1953     reading_cache_clear();
1954 
1955   owl_analyze_semeai_after_move(move, color, dragona, dragonb,
1956 				&resulta, &resultb, &semeai_move, 1,
1957 				&result_certain, 0);
1958   gtp_start_response(GTP_SUCCESS);
1959   gtp_print_code(resulta);
1960   gtp_printf(" ");
1961   gtp_print_code(resultb);
1962   gtp_mprintf(" %m", I(semeai_move), J(semeai_move));
1963   if (!result_certain && report_uncertainty)
1964     gtp_printf(" uncertain");
1965 
1966   return gtp_finish_response();
1967 }
1968 
1969 
1970 /* Function:  Analyze a semeai, not using owl
1971  * Arguments: dragona, dragonb
1972  * Fails:     invalid vertices, empty vertices
1973  * Returns:   status of dragona, dragonb assuming dragona moves first
1974  */
1975 static int
gtp_tactical_analyze_semeai(char * s)1976 gtp_tactical_analyze_semeai(char *s)
1977 {
1978   int i, j;
1979   int k;
1980   int dragona, dragonb;
1981   int resulta, resultb, move, result_certain;
1982 
1983   k = gtp_decode_coord(s, &i, &j);
1984 
1985   if (k == 0)
1986     return gtp_failure("invalid coordinate");
1987   dragona = POS(i, j);
1988   if (BOARD(i, j) == EMPTY)
1989     return gtp_failure("vertex must not be empty");
1990 
1991   if (!gtp_decode_coord(s+k, &i, &j))
1992     return gtp_failure("invalid coordinate");
1993   dragonb = POS(i, j);
1994   if (BOARD(i, j) == EMPTY)
1995     return gtp_failure("vertex must not be empty");
1996 
1997   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
1998   /* to get the variations into the sgf file, clear the reading cache */
1999   if (sgf_dumptree)
2000     reading_cache_clear();
2001 
2002   owl_analyze_semeai(dragona, dragonb, &resulta, &resultb, &move, 0,
2003                      &result_certain);
2004   gtp_start_response(GTP_SUCCESS);
2005   gtp_print_code(resulta);
2006   gtp_printf(" ");
2007   gtp_print_code(resultb);
2008   gtp_mprintf(" %m", I(move), J(move));
2009   if (!result_certain && report_uncertainty)
2010     gtp_printf(" uncertain");
2011 
2012   return gtp_finish_response();
2013 }
2014 
2015 
2016 /***********************
2017  * Connection reading. *
2018  ***********************/
2019 
2020 /* Function:  Try to connect two strings.
2021  * Arguments: vertex, vertex
2022  * Fails:     invalid vertex, empty vertex, vertices of different colors
2023  * Returns:   connect result followed by connect point if successful.
2024  */
2025 static int
gtp_connect(char * s)2026 gtp_connect(char *s)
2027 {
2028   int ai, aj;
2029   int bi, bj;
2030   int connect_move = PASS_MOVE;
2031   int result;
2032   int n;
2033 
2034   n = gtp_decode_coord(s, &ai, &aj);
2035   if (n == 0)
2036     return gtp_failure("invalid coordinate");
2037 
2038   if (!gtp_decode_coord(s + n, &bi, &bj))
2039     return gtp_failure("invalid coordinate");
2040 
2041   if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY)
2042     return gtp_failure("vertex must not be empty");
2043 
2044   if (BOARD(ai, aj) != BOARD(bi, bj))
2045     return gtp_failure("vertices must have same color");
2046 
2047   result = string_connect(POS(ai, aj), POS(bi, bj), &connect_move);
2048   gtp_start_response(GTP_SUCCESS);
2049   gtp_print_code(result);
2050   if (result != 0)
2051     gtp_mprintf(" %m", I(connect_move), J(connect_move));
2052 
2053   return gtp_finish_response();
2054 }
2055 
2056 
2057 /* Function:  Try to disconnect two strings.
2058  * Arguments: vertex, vertex
2059  * Fails:     invalid vertex, empty vertex, vertices of different colors
2060  * Returns:   disconnect result followed by disconnect point if successful.
2061  */
2062 static int
gtp_disconnect(char * s)2063 gtp_disconnect(char *s)
2064 {
2065   int ai, aj;
2066   int bi, bj;
2067   int disconnect_move = PASS_MOVE;
2068   int result;
2069   int n;
2070 
2071   n = gtp_decode_coord(s, &ai, &aj);
2072   if (n == 0)
2073     return gtp_failure("invalid coordinate");
2074 
2075   if (!gtp_decode_coord(s + n, &bi, &bj))
2076     return gtp_failure("invalid coordinate");
2077 
2078   if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY)
2079     return gtp_failure("vertex must not be empty");
2080 
2081   if (BOARD(ai, aj) != BOARD(bi, bj))
2082     return gtp_failure("vertices must have same color");
2083 
2084   result = disconnect(POS(ai, aj), POS(bi, bj), &disconnect_move);
2085   gtp_start_response(GTP_SUCCESS);
2086   gtp_print_code(result);
2087   if (result != 0)
2088     gtp_mprintf(" %m", I(disconnect_move), J(disconnect_move));
2089 
2090   return gtp_finish_response();
2091 }
2092 
2093 
2094 /* Function:  Try to break from string into area.
2095  * Arguments: vertex, vertices
2096  * Fails:     invalid vertex, empty vertex.
2097  * Returns:   result followed by break in point if successful.
2098  */
2099 static int
gtp_break_in(char * s)2100 gtp_break_in(char *s)
2101 {
2102   int ai, aj;
2103   int i, j;
2104   signed char goal[BOARDMAX];
2105   int break_move = PASS_MOVE;
2106   int result;
2107   int n;
2108   int k;
2109 
2110   n = gtp_decode_coord(s, &ai, &aj);
2111   if (n == 0)
2112     return gtp_failure("invalid coordinate");
2113 
2114   memset(goal, 0, BOARDMAX);
2115   s += n;
2116 
2117   for (k = 0; k < MAX_BOARD * MAX_BOARD; k++) {
2118     n = gtp_decode_coord(s, &i, &j);
2119     if (n > 0) {
2120       goal[POS(i, j)] = 1;
2121       s += n;
2122     }
2123     else if (sscanf(s, "%*s") != EOF)
2124       return gtp_failure("invalid coordinate");
2125     else
2126       break;
2127   }
2128 
2129   if (BOARD(ai, aj) == EMPTY)
2130     return gtp_failure("vertex must not be empty");
2131 
2132   result = break_in(POS(ai, aj), goal, &break_move);
2133   gtp_start_response(GTP_SUCCESS);
2134   gtp_print_code(result);
2135   if (result != 0)
2136     gtp_mprintf(" %m", I(break_move), J(break_move));
2137 
2138   return gtp_finish_response();
2139 }
2140 
2141 /* Function:  Try to block string from area.
2142  * Arguments: vertex, vertices
2143  * Fails:     invalid vertex, empty vertex.
2144  * Returns:   result followed by block point if successful.
2145  */
2146 static int
gtp_block_off(char * s)2147 gtp_block_off(char *s)
2148 {
2149   int ai, aj;
2150   int i, j;
2151   signed char goal[BOARDMAX];
2152   int block_move = PASS_MOVE;
2153   int result;
2154   int n;
2155   int k;
2156 
2157   n = gtp_decode_coord(s, &ai, &aj);
2158   if (n == 0)
2159     return gtp_failure("invalid coordinate");
2160 
2161   memset(goal, 0, BOARDMAX);
2162   s += n;
2163 
2164   for (k = 0; k < MAX_BOARD * MAX_BOARD; k++) {
2165     n = gtp_decode_coord(s, &i, &j);
2166     if (n > 0) {
2167       goal[POS(i, j)] = 1;
2168       s += n;
2169     }
2170     else if (sscanf(s, "%*s") != EOF)
2171       return gtp_failure("invalid coordinate");
2172     else
2173       break;
2174   }
2175 
2176   if (BOARD(ai, aj) == EMPTY)
2177     return gtp_failure("vertex must not be empty");
2178 
2179   result = block_off(POS(ai, aj), goal, &block_move);
2180   gtp_start_response(GTP_SUCCESS);
2181   gtp_print_code(result);
2182   if (result != 0)
2183     gtp_mprintf(" %m", I(block_move), J(block_move));
2184 
2185   return gtp_finish_response();
2186 }
2187 
2188 
2189 
2190 /********
2191  * eyes *
2192  ********/
2193 
2194 /* Function:  Evaluate an eye space
2195  * Arguments: vertex
2196  * Fails:     invalid vertex
2197  * Returns:   Minimum and maximum number of eyes. If these differ an
2198  *            attack and a defense point are additionally returned.
2199  *            If the vertex is not an eye space or not of unique color,
2200  *            a single -1 is returned.
2201  */
2202 
2203 static int
gtp_eval_eye(char * s)2204 gtp_eval_eye(char *s)
2205 {
2206   int m, n;
2207   struct eyevalue value;
2208   int attack_point;
2209   int defense_point;
2210   int pos;
2211 
2212   if (!gtp_decode_coord(s, &m, &n))
2213     return gtp_failure("invalid coordinate");
2214 
2215   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
2216 
2217   if (black_eye[POS(m, n)].color == BLACK) {
2218     pos = black_eye[POS(m, n)].origin;
2219     compute_eyes(pos, &value, &attack_point, &defense_point,
2220 		 black_eye, half_eye, 0);
2221   }
2222   else if (white_eye[POS(m, n)].color == WHITE) {
2223     pos = white_eye[POS(m, n)].origin;
2224     compute_eyes(pos, &value, &attack_point, &defense_point,
2225 		 white_eye, half_eye, 0);
2226   }
2227   else
2228     /* Not an eye or not of unique color. */
2229     return gtp_success("-1");
2230 
2231   gtp_start_response(GTP_SUCCESS);
2232   gtp_printf("%d %d", min_eyes(&value), max_eyes(&value));
2233   if (eye_move_urgency(&value) > 0) {
2234     gtp_printf(" ");
2235     gtp_print_vertex(I(attack_point), J(attack_point));
2236     gtp_printf(" ");
2237     gtp_print_vertex(I(defense_point), J(defense_point));
2238   }
2239   return gtp_finish_response();
2240 }
2241 
2242 
2243 /*****************
2244  * dragon status *
2245  *****************/
2246 
2247 /* Function:  Determine status of a dragon.
2248  * Arguments: optional vertex
2249  * Fails:     invalid vertex, empty vertex
2250  * Returns:   status ("alive", "critical", "dead", or "unknown"),
2251  *            attack point, defense point. Points of attack and
2252  *            defense are only given if the status is critical.
2253  *            If no vertex is given, the status is listed for all
2254  *            dragons, one per row in the format "A4: alive".
2255  *
2256  * FIXME: Should be able to distinguish between life in seki
2257  *        and independent life. Should also be able to identify ko.
2258  */
2259 
2260 static int
gtp_dragon_status(char * s)2261 gtp_dragon_status(char *s)
2262 {
2263   int i, j;
2264   int str = NO_MOVE;
2265   int pos;
2266   int empty_response = 1;
2267 
2268   if (gtp_decode_coord(s, &i, &j)) {
2269     str = POS(i, j);
2270     if (board[str] == EMPTY)
2271       return gtp_failure("vertex must not be empty");
2272   }
2273   else if (sscanf(s, "%*s") != EOF)
2274     return gtp_failure("invalid coordinate");
2275 
2276   silent_examine_position(EXAMINE_DRAGONS);
2277 
2278   gtp_start_response(GTP_SUCCESS);
2279 
2280   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
2281     if (ON_BOARD(pos)
2282 	&& (pos == str
2283 	    || (str == NO_MOVE
2284 		&& board[pos] != EMPTY
2285 		&& dragon[pos].origin == pos))) {
2286       if (str == NO_MOVE)
2287 	gtp_mprintf("%m: ", I(pos), J(pos));
2288 
2289       if (dragon[pos].status == ALIVE)
2290 	gtp_printf("alive\n");
2291       else if (dragon[pos].status == DEAD)
2292 	gtp_printf("dead\n");
2293       else if (dragon[pos].status == UNKNOWN)
2294 	gtp_printf("unknown\n");
2295       else {
2296 	/* Only remaining possibility. */
2297 	assert(dragon[pos].status == CRITICAL);
2298 	/* Status critical, need to return attack and defense point as well. */
2299 	gtp_mprintf("critical %m %m\n",
2300 		    I(DRAGON2(pos).owl_attack_point),
2301 		    J(DRAGON2(pos).owl_attack_point),
2302 		    I(DRAGON2(pos).owl_defense_point),
2303 		    J(DRAGON2(pos).owl_defense_point));
2304       }
2305       empty_response = 0;
2306     }
2307   }
2308 
2309   if (empty_response)
2310     gtp_printf("\n");
2311 
2312   gtp_printf("\n");
2313   return GTP_OK;
2314 }
2315 
2316 
2317 /* Function:  Determine whether two stones belong to the same dragon.
2318  * Arguments: vertex, vertex
2319  * Fails:     invalid vertex, empty vertex
2320  * Returns:   1 if the vertices belong to the same dragon, 0 otherwise
2321  */
2322 
2323 static int
gtp_same_dragon(char * s)2324 gtp_same_dragon(char *s)
2325 {
2326   int ai, aj;
2327   int bi, bj;
2328   int n;
2329 
2330   n = gtp_decode_coord(s, &ai, &aj);
2331   if (n == 0)
2332     return gtp_failure("invalid coordinate");
2333 
2334   if (!gtp_decode_coord(s + n, &bi, &bj))
2335     return gtp_failure("invalid coordinate");
2336 
2337   if (BOARD(ai, aj) == EMPTY || BOARD(bi, bj) == EMPTY)
2338     return gtp_failure("vertex must not be empty");
2339 
2340   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
2341 
2342   return gtp_success("%d", dragon[POS(ai, aj)].id == dragon[POS(bi, bj)].id);
2343 }
2344 
2345 
2346 /************************
2347  * Unconditional status *
2348  ************************/
2349 
2350 /* Function:  Determine the unconditional status of a vertex.
2351  * Arguments: vertex
2352  * Fails:     invalid vertex
2353  * Returns:   unconditional status ("undecided", "alive", "dead",
2354  *            "white_territory", "black_territory"). Occupied vertices can
2355  *            be undecided, alive, or dead. Empty vertices can be
2356  *            undecided, white territory, or black territory.
2357  */
2358 
2359 static int
gtp_unconditional_status(char * s)2360 gtp_unconditional_status(char *s)
2361 {
2362   int i, j;
2363   enum dragon_status status;
2364 
2365   if (!gtp_decode_coord(s, &i, &j))
2366     return gtp_failure("invalid coordinate");
2367 
2368   silent_examine_position(EXAMINE_WORMS);
2369 
2370   status = worm[POS(i, j)].unconditional_status;
2371   if (status == UNKNOWN)
2372     return gtp_success("undecided");
2373   return gtp_success("%s", status_to_string(status));
2374 }
2375 
2376 
2377 /***********************
2378  * combination attacks *
2379  ***********************/
2380 
2381 /* Function:  Find a move by color capturing something through a
2382  *            combination attack.
2383  * Arguments: color
2384  * Fails:     invalid color
2385  * Returns:   Recommended move, PASS if no move found
2386  */
2387 
2388 static int
gtp_combination_attack(char * s)2389 gtp_combination_attack(char *s)
2390 {
2391   int color;
2392   int attack_point;
2393   int n;
2394 
2395   n = gtp_decode_color(s, &color);
2396   if (!n)
2397     return gtp_failure("invalid color");
2398 
2399   silent_examine_position(EXAMINE_ALL);
2400 
2401   if (!atari_atari(color, &attack_point, NULL, verbose))
2402     attack_point = NO_MOVE;
2403 
2404   gtp_start_response(GTP_SUCCESS);
2405   gtp_print_vertex(I(attack_point), J(attack_point));
2406   return gtp_finish_response();
2407 }
2408 
2409 /* Function:  If color can capture something through a
2410  *            combination attack, list moves by the opponent of color
2411  *            to defend against this attack.
2412  * Arguments: color
2413  * Fails:     invalid color
2414  * Returns:   Recommended moves, PASS if no combination attack found.
2415  */
2416 
2417 static int
gtp_combination_defend(char * s)2418 gtp_combination_defend(char *s)
2419 {
2420   int color;
2421   signed char defense_points[BOARDMAX];
2422   int pos;
2423   int first = 1;
2424   int n;
2425 
2426   n = gtp_decode_color(s, &color);
2427   if (!n)
2428     return gtp_failure("invalid color");
2429 
2430   silent_examine_position(EXAMINE_ALL);
2431 
2432   memset(defense_points, 0, sizeof(defense_points));
2433   if (!atari_atari(color, NULL, defense_points, verbose))
2434     return gtp_success("PASS");
2435 
2436   gtp_start_response(GTP_SUCCESS);
2437   for (pos = BOARDMIN; pos < BOARDMAX; pos++)
2438     if (ON_BOARD(pos) && defense_points[pos]) {
2439       if (!first)
2440 	gtp_printf(" ");
2441       else
2442 	first = 0;
2443       gtp_print_vertex(I(pos), J(pos));
2444     }
2445 
2446   return gtp_finish_response();
2447 }
2448 
2449 /* Function:  Run atari_atari_confirm_safety().
2450  * Arguments: move, optional int
2451  * Fails:     invalid move
2452  * Returns:   success code, if failure also defending move
2453  */
2454 
2455 static int
gtp_aa_confirm_safety(char * s)2456 gtp_aa_confirm_safety(char *s)
2457 {
2458   int color;
2459   int i, j;
2460   int n;
2461   int minsize = 0;
2462   int result;
2463   int defense_point = NO_MOVE;
2464   signed char saved_dragons[BOARDMAX];
2465   signed char saved_worms[BOARDMAX];
2466 
2467   n = gtp_decode_move(s, &color, &i, &j);
2468   if (n == 0 || POS(i, j) == NO_MOVE)
2469     return gtp_failure("invalid color or coordinate");
2470 
2471   sscanf(s + n, "%d", &minsize);
2472 
2473   genmove(color, NULL, NULL);
2474   get_saved_dragons(POS(i, j), saved_dragons);
2475   get_saved_worms(POS(i, j), saved_worms);
2476 
2477   result = atari_atari_confirm_safety(color, POS(i, j),
2478 				      &defense_point, minsize,
2479 				      saved_dragons, saved_worms);
2480 
2481   gtp_start_response(GTP_SUCCESS);
2482   gtp_mprintf("%d", result);
2483   if (result == 0)
2484     gtp_mprintf(" %m", I(defense_point), J(defense_point));
2485 
2486   return gtp_finish_response();
2487 }
2488 
2489 
2490 /********************
2491  * generating moves *
2492  ********************/
2493 
2494 /* Function:  Generate and play the supposedly best black move.
2495  * Arguments: none
2496  * Fails:     never
2497  * Returns:   a move coordinate or "PASS"
2498  *
2499  * Status:    Obsolete GTP version 1 command.
2500  */
2501 static int
gtp_genmove_black(char * s)2502 gtp_genmove_black(char *s)
2503 {
2504   int move;
2505   UNUSED(s);
2506 
2507   if (stackp > 0)
2508     return gtp_failure("genmove cannot be called when stackp > 0");
2509 
2510   move = genmove(BLACK, NULL, NULL);
2511 
2512   gnugo_play_move(move, BLACK);
2513 
2514   gtp_start_response(GTP_SUCCESS);
2515   gtp_print_vertex(I(move), J(move));
2516   return gtp_finish_response();
2517 }
2518 
2519 /* Function:  Generate and play the supposedly best white move.
2520  * Arguments: none
2521  * Fails:     never
2522  * Returns:   a move coordinate or "PASS"
2523  *
2524  * Status:    Obsolete GTP version 1 command.
2525  */
2526 static int
gtp_genmove_white(char * s)2527 gtp_genmove_white(char *s)
2528 {
2529   int move;
2530   UNUSED(s);
2531 
2532   if (stackp > 0)
2533     return gtp_failure("genmove cannot be called when stackp > 0");
2534 
2535   move = genmove(WHITE, NULL, NULL);
2536 
2537   gnugo_play_move(move, WHITE);
2538 
2539   gtp_start_response(GTP_SUCCESS);
2540   gtp_print_vertex(I(move), J(move));
2541   return gtp_finish_response();
2542 }
2543 
2544 /* Function:  Generate and play the supposedly best move for either color.
2545  * Arguments: color to move
2546  * Fails:     invalid color
2547  * Returns:   a move coordinate or "PASS" (or "resign" if resignation_allowed)
2548  *
2549  * Status:    GTP version 2 standard command.
2550  */
2551 static int
gtp_genmove(char * s)2552 gtp_genmove(char *s)
2553 {
2554   int move;
2555   int resign;
2556   int color;
2557   int n;
2558 
2559   n = gtp_decode_color(s, &color);
2560   if (!n)
2561     return gtp_failure("invalid color");
2562 
2563   if (stackp > 0)
2564     return gtp_failure("genmove cannot be called when stackp > 0");
2565 
2566   adjust_level_offset(color);
2567   move = genmove(color, NULL, &resign);
2568 
2569   if (resign)
2570     return gtp_success("resign");
2571 
2572   gnugo_play_move(move, color);
2573 
2574   gtp_start_response(GTP_SUCCESS);
2575   gtp_print_vertex(I(move), J(move));
2576   return gtp_finish_response();
2577 }
2578 
2579 
2580 /* Function:  Generate the supposedly best move for either color.
2581  * Arguments: color to move
2582  * Fails:     invalid color
2583  * Returns:   a move coordinate (or "PASS")
2584  *
2585  * Status:    GTP version 2 standard command.
2586  */
2587 static int
gtp_reg_genmove(char * s)2588 gtp_reg_genmove(char *s)
2589 {
2590   int move;
2591   int color;
2592   int n;
2593   unsigned int saved_random_seed = get_random_seed();
2594 
2595   n = gtp_decode_color(s, &color);
2596   if (!n)
2597     return gtp_failure("invalid color");
2598 
2599   if (stackp > 0)
2600     return gtp_failure("genmove cannot be called when stackp > 0");
2601 
2602   /* This is intended for regression purposes and should therefore be
2603    * deterministic. The best way to ensure this is to reset the random
2604    * number generator before calling genmove(). It is always seeded by
2605    * 0.
2606    */
2607   set_random_seed(0);
2608 
2609   move = genmove_conservative(color, NULL);
2610 
2611   set_random_seed(saved_random_seed);
2612   gtp_start_response(GTP_SUCCESS);
2613   gtp_print_vertex(I(move), J(move));
2614   return gtp_finish_response();
2615 }
2616 
2617 /* Function:  Generate the supposedly best move for either color.
2618  * Arguments: color to move, optionally a random seed
2619  * Fails:     invalid color
2620  * Returns:   a move coordinate (or "PASS")
2621  *
2622  * This differs from reg_genmove in the optional random seed.
2623  */
2624 static int
gtp_gg_genmove(char * s)2625 gtp_gg_genmove(char *s)
2626 {
2627   int move;
2628   int color;
2629   int n;
2630   unsigned int saved_random_seed = get_random_seed();
2631   unsigned int seed;
2632 
2633   n = gtp_decode_color(s, &color);
2634   if (!n)
2635     return gtp_failure("invalid color");
2636 
2637   if (stackp > 0)
2638     return gtp_failure("genmove cannot be called when stackp > 0");
2639 
2640   /* This is intended for regression purposes and should therefore be
2641    * deterministic. The best way to ensure this is to reset the random
2642    * number generator before calling genmove(). By default it is
2643    * seeded with 0, but if an optional unsigned integer is given in
2644    * the command after the color, this is used as seed instead.
2645    */
2646   seed = 0;
2647   sscanf(s+n, "%u", &seed);
2648   set_random_seed(seed);
2649 
2650   move = genmove_conservative(color, NULL);
2651   set_random_seed(saved_random_seed);
2652   gtp_start_response(GTP_SUCCESS);
2653   gtp_print_vertex(I(move), J(move));
2654   return gtp_finish_response();
2655 }
2656 
2657 
2658 /* Function:  Generate the supposedly best move for either color from a
2659  *            choice of allowed vertices.
2660  * Arguments: color to move, allowed vertices
2661  * Fails:     invalid color, invalid vertex, no vertex listed
2662  * Returns:   a move coordinate (or "PASS")
2663  */
2664 static int
gtp_restricted_genmove(char * s)2665 gtp_restricted_genmove(char *s)
2666 {
2667   int move;
2668   int i, j;
2669   int color;
2670   int n;
2671   unsigned int saved_random_seed = get_random_seed();
2672   int allowed_moves[BOARDMAX];
2673   int number_allowed_moves = 0;
2674   memset(allowed_moves, 0, sizeof(allowed_moves));
2675 
2676   n = gtp_decode_color(s, &color);
2677   if (!n)
2678     return gtp_failure("invalid color");
2679 
2680   s += n;
2681   while (1) {
2682     n = gtp_decode_coord(s, &i, &j);
2683     if (n > 0) {
2684       allowed_moves[POS(i, j)] = 1;
2685       number_allowed_moves++;
2686       s += n;
2687     }
2688     else if (sscanf(s, "%*s") != EOF)
2689       return gtp_failure("invalid coordinate");
2690     else
2691       break;
2692   }
2693 
2694   if (number_allowed_moves == 0)
2695     return gtp_failure("no allowed vertex");
2696 
2697   if (stackp > 0)
2698     return gtp_failure("genmove cannot be called when stackp > 0");
2699 
2700   /* This is intended for regression purposes and should therefore be
2701    * deterministic. The best way to ensure this is to reset the random
2702    * number generator before calling genmove(). It is always seeded by
2703    * 0.
2704    */
2705   set_random_seed(0);
2706 
2707   move = genmove_restricted(color, allowed_moves);
2708   set_random_seed(saved_random_seed);
2709   gtp_start_response(GTP_SUCCESS);
2710   gtp_print_vertex(I(move), J(move));
2711   return gtp_finish_response();
2712 }
2713 
2714 
2715 /* Function:  Generate and play the supposedly best move for either color,
2716  *            not passing until all dead opponent stones have been removed.
2717  * Arguments: color to move
2718  * Fails:     invalid color
2719  * Returns:   a move coordinate (or "PASS")
2720  *
2721  * Status:    KGS specific command.
2722  *
2723  * A similar command, but possibly somewhat different, will likely be added
2724  * to GTP version 3 at a later time.
2725  */
2726 static int
gtp_kgs_genmove_cleanup(char * s)2727 gtp_kgs_genmove_cleanup(char *s)
2728 {
2729   int move;
2730   int color;
2731   int n;
2732   int save_capture_all_dead = capture_all_dead;
2733 
2734   n = gtp_decode_color(s, &color);
2735   if (!n)
2736     return gtp_failure("invalid color");
2737 
2738   if (stackp > 0)
2739     return gtp_failure("kgs-genmove_cleanup cannot be called when stackp > 0");
2740 
2741   /* Turn on the capture_all_dead option to force removal of dead
2742    * opponent stones.
2743    */
2744   capture_all_dead = 1;
2745 
2746   adjust_level_offset(color);
2747   move = genmove(color, NULL, NULL);
2748 
2749   capture_all_dead = save_capture_all_dead;
2750 
2751   gnugo_play_move(move, color);
2752 
2753   gtp_start_response(GTP_SUCCESS);
2754   gtp_print_vertex(I(move), J(move));
2755   return gtp_finish_response();
2756 }
2757 
2758 
2759 /* Function : List the move reasons for a move.
2760  * Arguments: vertex
2761  * Fails:   : invalid vertex, occupied vertex
2762  * Returns  : list of move reasons (may be empty)
2763  */
2764 
2765 static int
gtp_move_reasons(char * s)2766 gtp_move_reasons(char *s)
2767 {
2768   int i, j;
2769   if (!gtp_decode_coord(s, &i, &j))
2770     return gtp_failure("invalid coordinate");
2771 
2772   if (BOARD(i, j) != EMPTY)
2773     return gtp_failure("vertex must not be occupied");
2774 
2775   gtp_start_response(GTP_SUCCESS);
2776   if (list_move_reasons(gtp_output_file, POS(i, j)) == 0)
2777     gtp_printf("\n");
2778   gtp_printf("\n");
2779   return GTP_OK;
2780 }
2781 
2782 /* Function : Generate a list of all moves with values larger than zero in
2783  *            the previous genmove command.
2784  *            If no previous genmove command has been issued, the result
2785  *            of this command will be meaningless.
2786  * Arguments: none
2787  * Fails:   : never
2788  * Returns  : list of moves with values
2789  */
2790 
2791 static int
gtp_all_move_values(char * s)2792 gtp_all_move_values(char *s)
2793 {
2794   UNUSED(s);
2795   gtp_start_response(GTP_SUCCESS);
2796   print_all_move_values(gtp_output_file);
2797   gtp_printf("\n");
2798   return GTP_OK;
2799 }
2800 
2801 /* Function : Generate a sorted list of the best moves in the previous genmove
2802  *            command.
2803  *            If no previous genmove command has been issued, the result
2804  *            of this command will be meaningless.
2805  * Arguments: none
2806  * Fails:   : never
2807  * Returns  : list of moves with weights
2808  */
2809 
2810 /* FIXME: Don't we want the moves one per row? */
2811 static int
gtp_top_moves(char * s)2812 gtp_top_moves(char *s)
2813 {
2814   int k;
2815   UNUSED(s);
2816   gtp_start_response(GTP_SUCCESS);
2817   for (k = 0; k < 10; k++)
2818     if (best_move_values[k] > 0.0) {
2819       gtp_print_vertex(I(best_moves[k]), J(best_moves[k]));
2820       gtp_printf(" %.2f ", best_move_values[k]);
2821     }
2822   gtp_printf("\n\n");
2823   return GTP_OK;
2824 }
2825 
2826 /* Function : Generate a list of the best moves for white with weights
2827  * Arguments: none
2828  * Fails:   : never
2829  * Returns  : list of moves with weights
2830  */
2831 
2832 static int
gtp_top_moves_white(char * s)2833 gtp_top_moves_white(char *s)
2834 {
2835   int k;
2836   UNUSED(s);
2837   genmove(WHITE, NULL, NULL);
2838   gtp_start_response(GTP_SUCCESS);
2839   for (k = 0; k < 10; k++)
2840     if (best_move_values[k] > 0.0) {
2841       gtp_print_vertex(I(best_moves[k]), J(best_moves[k]));
2842       gtp_printf(" %.2f ", best_move_values[k]);
2843     }
2844   return gtp_finish_response();
2845 }
2846 
2847 /* Function : Generate a list of the best moves for black with weights
2848  * Arguments: none
2849  * Fails:   : never
2850  * Returns  : list of moves with weights
2851  */
2852 
2853 static int
gtp_top_moves_black(char * s)2854 gtp_top_moves_black(char *s)
2855 {
2856   int k;
2857   UNUSED(s);
2858   genmove(BLACK, NULL, NULL);
2859   gtp_start_response(GTP_SUCCESS);
2860   for (k = 0; k < 10; k++)
2861     if (best_move_values[k] > 0.0) {
2862       gtp_print_vertex(I(best_moves[k]), J(best_moves[k]));
2863       gtp_printf(" %.2f ", best_move_values[k]);
2864     }
2865   return gtp_finish_response();
2866 }
2867 
2868 
2869 
2870 /* Function:  Set the playing level.
2871  * Arguments: int
2872  * Fails:     incorrect argument
2873  * Returns:   nothing
2874  */
2875 static int
gtp_set_level(char * s)2876 gtp_set_level(char *s)
2877 {
2878   int new_level;
2879   if (sscanf(s, "%d", &new_level) < 1)
2880     return gtp_failure("level not an integer");
2881 
2882   set_level(new_level);
2883   return gtp_success("");
2884 }
2885 
2886 /* Function:  Undo one move
2887  * Arguments: none
2888  * Fails:     If move history is too short.
2889  * Returns:   nothing
2890  *
2891  * Status:    GTP version 2 standard command.
2892  */
2893 
2894 static int
gtp_undo(char * s)2895 gtp_undo(char *s)
2896 {
2897   UNUSED(s);
2898 
2899   if (stackp > 0 || !undo_move(1))
2900     return gtp_failure("cannot undo");
2901 
2902   reset_engine();
2903 
2904   return gtp_success("");
2905 }
2906 
2907 
2908 /* Function:  Undo a number of moves
2909  * Arguments: optional int
2910  * Fails:     If move history is too short.
2911  * Returns:   nothing
2912  */
2913 
2914 static int
gtp_gg_undo(char * s)2915 gtp_gg_undo(char *s)
2916 {
2917   int number_moves = 1;
2918 
2919   sscanf(s, "%d", &number_moves);
2920 
2921   if (number_moves < 0)
2922     return gtp_failure("can't undo a negative number of moves");
2923 
2924   if (stackp > 0 || !undo_move(number_moves))
2925     return gtp_failure("cannot undo");
2926 
2927   reset_engine();
2928 
2929   return gtp_success("");
2930 }
2931 
2932 
2933 /*****************
2934  * time handling *
2935  *****************/
2936 
2937 /* Function:  Set time allowance
2938  * Arguments: int main_time, int byo_yomi_time, int byo_yomi_stones
2939  * Fails:     syntax error
2940  * Returns:   nothing
2941  *
2942  * Status:    GTP version 2 standard command.
2943  */
2944 
2945 static int
gtp_time_settings(char * s)2946 gtp_time_settings(char *s)
2947 {
2948   int main_time, byoyomi_time, byoyomi_stones;
2949 
2950   if (sscanf(s, "%d %d %d", &main_time, &byoyomi_time, &byoyomi_stones) < 3)
2951     return gtp_failure("not three integers");
2952 
2953   clock_settings(main_time, byoyomi_time, byoyomi_stones);
2954   return gtp_success("");
2955 }
2956 
2957 
2958 /* Function:  Report remaining time
2959  * Arguments: color color, int time, int stones
2960  * Fails:     syntax error
2961  * Returns:   nothing
2962  *
2963  * Status:    GTP version 2 standard command.
2964  */
2965 
2966 static int
gtp_time_left(char * s)2967 gtp_time_left(char *s)
2968 {
2969   int color;
2970   int time;
2971   int stones;
2972   int n;
2973 
2974   n = gtp_decode_color(s, &color);
2975   if (!n)
2976     return gtp_failure("invalid color");
2977 
2978   if (sscanf(s+n, "%d %d", &time, &stones) < 2)
2979     return gtp_failure("time and stones not two integers");
2980 
2981   update_time_left(color, time, stones);
2982 
2983   return gtp_success("");
2984 }
2985 
2986 
2987 /***********
2988  * scoring *
2989  ***********/
2990 
2991 static float final_score;
2992 static enum dragon_status final_status[MAX_BOARD][MAX_BOARD];
2993 static enum dragon_status status_numbers[6] = {ALIVE, DEAD, ALIVE_IN_SEKI,
2994 					       WHITE_TERRITORY,
2995 					       BLACK_TERRITORY, DAME};
2996 static const char *status_names[6] = {"alive", "dead", "seki",
2997 				      "white_territory", "black_territory",
2998 				      "dame"};
2999 
3000 /* Helper function. */
3001 static void
finish_and_score_game(int seed)3002 finish_and_score_game(int seed)
3003 {
3004   int move;
3005   int i, j;
3006   int next;
3007   int pass = 0;
3008   int moves = 0;
3009   int saved_board[MAX_BOARD][MAX_BOARD];
3010   struct board_state saved_pos;
3011   static int current_board[MAX_BOARD][MAX_BOARD];
3012   static int current_seed = -1;
3013   int cached_board = 1;
3014 
3015   if (current_seed != seed) {
3016     current_seed = seed;
3017     cached_board = 0;
3018   }
3019 
3020   for (i = 0; i < board_size; i++)
3021     for (j = 0; j < board_size; j++)
3022       if (BOARD(i, j) != current_board[i][j]) {
3023 	current_board[i][j] = BOARD(i, j);
3024 	cached_board = 0;
3025       }
3026 
3027   /* If this is exactly the same position as the one we analyzed the
3028    * last time, the contents of final_score and final_status are up to date.
3029    */
3030   if (cached_board)
3031     return;
3032 
3033   doing_scoring = 1;
3034   store_board(&saved_pos);
3035 
3036   /* Let black start if we have no move history. Otherwise continue
3037    * alternation.
3038    */
3039   if (get_last_player() == EMPTY)
3040     next = BLACK;
3041   else
3042     next = OTHER_COLOR(get_last_player());
3043 
3044   do {
3045     move = genmove_conservative(next, NULL);
3046     gnugo_play_move(move, next);
3047     if (move != PASS_MOVE) {
3048       pass = 0;
3049       moves++;
3050     }
3051     else
3052       pass++;
3053 
3054     next = OTHER_COLOR(next);
3055   } while (pass < 2 && moves < board_size * board_size);
3056 
3057   final_score = aftermath_compute_score(next, NULL);
3058   for (i = 0; i < board_size; i++)
3059     for (j = 0; j < board_size; j++) {
3060       final_status[i][j] = aftermath_final_status(next, POS(i, j));
3061       saved_board[i][j] = BOARD(i, j);
3062     }
3063 
3064   restore_board(&saved_pos);
3065   doing_scoring = 0;
3066 
3067   /* Update the status for vertices which were changed while finishing
3068    * the game, up to filling dame.
3069    */
3070   for (i = 0; i < board_size; i++)
3071     for (j = 0; j < board_size; j++) {
3072       if (BOARD(i, j) == saved_board[i][j])
3073 	continue;
3074 
3075       if (BOARD(i, j) == EMPTY) {
3076 	if (final_status[i][j] == ALIVE
3077 	    || final_status[i][j] == ALIVE_IN_SEKI)
3078 	  final_status[i][j] = DAME;
3079 	else if (final_status[i][j] == DEAD) {
3080 	  if (saved_board[i][j] == BLACK)
3081 	    final_status[i][j] = WHITE_TERRITORY;
3082 	  else
3083 	    final_status[i][j] = BLACK_TERRITORY;
3084 	}
3085       }
3086       else if (BOARD(i, j) == BLACK) {
3087 	if (final_status[i][j] == WHITE_TERRITORY)
3088 	  final_status[i][j] = DEAD;
3089 	else if (final_status[i][j] == DAME)
3090 	  final_status[i][j] = ALIVE_IN_SEKI;
3091 	else if (final_status[i][j] == BLACK_TERRITORY)
3092 	  final_status[i][j] = ALIVE;
3093 	else
3094 	  final_status[i][j] = DEAD;
3095       }
3096       else if (BOARD(i, j) == WHITE) {
3097 	if (final_status[i][j] == BLACK_TERRITORY)
3098 	  final_status[i][j] = DEAD;
3099 	else if (final_status[i][j] == DAME)
3100 	  final_status[i][j] = ALIVE_IN_SEKI;
3101 	else if (final_status[i][j] == WHITE_TERRITORY)
3102 	  final_status[i][j] = ALIVE;
3103 	else
3104 	  final_status[i][j] = DEAD;
3105       }
3106     }
3107 }
3108 
3109 
3110 /* Function:  Compute the score of a finished game.
3111  * Arguments: Optional random seed
3112  * Fails:     never
3113  * Returns:   Score in SGF format (RE property).
3114  *
3115  * Status:    GTP version 2 standard command.
3116  */
3117 static int
gtp_final_score(char * s)3118 gtp_final_score(char *s)
3119 {
3120   unsigned int saved_random_seed = get_random_seed();
3121   int seed;
3122   /* This is intended for regression purposes and should therefore be
3123    * deterministic. The best way to ensure this is to reset the random
3124    * number generator before calling genmove(). By default it is
3125    * seeded with 0, but if an optional unsigned integer is given in
3126    * the command after the color, this is used as seed instead.
3127    */
3128   seed = 0;
3129   sscanf(s, "%d", &seed);
3130   set_random_seed(seed);
3131 
3132   finish_and_score_game(seed);
3133 
3134   set_random_seed(saved_random_seed);
3135 
3136   gtp_start_response(GTP_SUCCESS);
3137   if (final_score > 0.0)
3138     gtp_printf("W+%3.1f", final_score);
3139   else if (final_score < 0.0)
3140     gtp_printf("B+%3.1f", -final_score);
3141   else
3142     gtp_printf("0");
3143   return gtp_finish_response();
3144 }
3145 
3146 
3147 /* Function:  Report the final status of a vertex in a finished game.
3148  * Arguments: Vertex, optional random seed
3149  * Fails:     invalid vertex
3150  * Returns:   Status in the form of one of the strings "alive", "dead",
3151  *            "seki", "white_territory", "black_territory", or "dame".
3152  */
3153 static int
gtp_final_status(char * s)3154 gtp_final_status(char *s)
3155 {
3156   int seed;
3157   int n;
3158   int ai, aj;
3159   int k;
3160   unsigned int saved_random_seed = get_random_seed();
3161   const char *result = NULL;
3162 
3163   n = gtp_decode_coord(s, &ai, &aj);
3164   if (n == 0)
3165     return gtp_failure("invalid coordinate");
3166 
3167   /* This is intended for regression purposes and should therefore be
3168    * deterministic. The best way to ensure this is to reset the random
3169    * number generator before calling genmove(). By default it is
3170    * seeded with 0, but if an optional unsigned integer is given in
3171    * the command after the color, this is used as seed instead.
3172    */
3173   seed = 0;
3174   sscanf(s + n, "%d", &seed);
3175   set_random_seed(seed);
3176 
3177   finish_and_score_game(seed);
3178 
3179   set_random_seed(saved_random_seed);
3180   for (k = 0; k < 6; k++)
3181     if (final_status[ai][aj] == status_numbers[k]) {
3182       result = status_names[k];
3183       break;
3184     }
3185   assert(result != NULL);
3186 
3187   return gtp_success(result);
3188 }
3189 
3190 
3191 /* Function:  Report vertices with a specific final status in a finished game.
3192  * Arguments: Status in the form of one of the strings "alive", "dead",
3193  *            "seki", "white_territory", "black_territory", or "dame".
3194  *            An optional random seed can be added.
3195  * Fails:     missing or invalid status string
3196  * Returns:   Vertices having the specified status. These are split with
3197  *            one string on each line if the vertices are nonempty (i.e.
3198  *            for "alive", "dead", and "seki").
3199  *
3200  * Status:    GTP version 2 standard command.
3201  *            However, "dame", "white_territory", and "black_territory"
3202  *            are private extensions.
3203  */
3204 static int
gtp_final_status_list(char * s)3205 gtp_final_status_list(char *s)
3206 {
3207   int seed;
3208   int n;
3209   int i, j;
3210   enum dragon_status status = UNKNOWN;
3211   int k;
3212   char status_string[GTP_BUFSIZE];
3213   int first;
3214   unsigned int saved_random_seed = get_random_seed();
3215 
3216   if (sscanf(s, "%s %n", status_string, &n) != 1)
3217     return gtp_failure("missing status");
3218 
3219   for (k = 0; k < 6; k++) {
3220     if (strcmp(status_string, status_names[k]) == 0)
3221       status = status_numbers[k];
3222   }
3223 
3224   if (status == UNKNOWN)
3225     return gtp_failure("invalid status");
3226 
3227   /* This is intended for regression purposes and should therefore be
3228    * deterministic. The best way to ensure this is to reset the random
3229    * number generator before calling genmove(). By default it is
3230    * seeded with 0, but if an optional unsigned integer is given in
3231    * the command after the color, this is used as seed instead.
3232    */
3233   seed = 0;
3234   sscanf(s + n, "%d", &seed);
3235   set_random_seed(seed);
3236 
3237   finish_and_score_game(seed);
3238 
3239   set_random_seed(saved_random_seed);
3240 
3241   gtp_start_response(GTP_SUCCESS);
3242 
3243   first = 1;
3244   for (i = 0; i < board_size; i++)
3245     for (j = 0; j < board_size; j++) {
3246       if (final_status[i][j] != status)
3247 	continue;
3248       if (BOARD(i, j) == EMPTY) {
3249 	if (!first)
3250 	  gtp_printf(" ");
3251 	else
3252 	  first = 0;
3253 	gtp_print_vertex(i, j);
3254       }
3255       else {
3256 	int num_stones;
3257 	int stones[MAX_BOARD * MAX_BOARD];
3258 	if (find_origin(POS(i, j)) != POS(i, j))
3259 	  continue;
3260 	if (!first)
3261 	  gtp_printf("\n");
3262 	else
3263 	  first = 0;
3264 	num_stones = findstones(POS(i, j), board_size * board_size, stones);
3265 	gtp_print_vertices2(num_stones, stones);
3266       }
3267     }
3268 
3269   return gtp_finish_response();
3270 }
3271 
3272 /* Function:  Estimate the score
3273  * Arguments: None
3274  * Fails:     never
3275  * Returns:   upper and lower bounds for the score
3276  */
3277 
3278 static int
gtp_estimate_score(char * s)3279 gtp_estimate_score(char *s)
3280 {
3281   float score;
3282   float upper_bound, lower_bound;
3283   UNUSED(s);
3284 
3285   score = gnugo_estimate_score(&upper_bound, &lower_bound);
3286   gtp_start_response(GTP_SUCCESS);
3287   /* Traditionally W wins jigo */
3288   if (score >= 0.0)
3289     gtp_printf("W+%3.1f (upper bound: %3.1f, lower: %3.1f)",
3290 	       score, upper_bound, lower_bound);
3291   else if (score < 0.0)
3292     gtp_printf("B+%3.1f (upper bound: %3.1f, lower: %3.1f)",
3293 	       -score, upper_bound, lower_bound);
3294   return gtp_finish_response();
3295 }
3296 
3297 /* Function:  Estimate the score, taking into account which player moves next
3298  * Arguments: Color to play
3299  * Fails:     Invalid color
3300  * Returns:   Score.
3301  *
3302  * This function generates a move for color, then adds the
3303  * value of the move generated to the value of the position.
3304  * Critical dragons are awarded to the opponent since the
3305  * value of rescuing a critical dragon is taken into account
3306  * in the value of the move generated.
3307  */
3308 
3309 static int
gtp_experimental_score(char * s)3310 gtp_experimental_score(char *s)
3311 {
3312   float upper_bound, lower_bound, score;
3313   int color;
3314 
3315   if (!gtp_decode_color(s, &color)
3316       || (color != BLACK && color != WHITE))
3317     return gtp_failure("invalid color");
3318 
3319   genmove_conservative(color, NULL);
3320   gnugo_estimate_score(&upper_bound, &lower_bound);
3321 
3322   if (debug & DEBUG_SCORING)
3323     fprintf(stderr, "upper = %3.1f, lower = %3.1f, best = %3.1f\n",
3324 	    upper_bound, lower_bound, best_move_values[0]);
3325   if (color == WHITE)
3326     score = lower_bound + best_move_values[0];
3327   else
3328     score = upper_bound - best_move_values[0];
3329 
3330   return gtp_success("%3.1f", score);
3331 }
3332 
3333 
3334 /**************
3335  * statistics *
3336  **************/
3337 
3338 /* Function:  Reset the count of life nodes.
3339  * Arguments: none
3340  * Fails:     never
3341  * Returns:   nothing
3342  *
3343  * Note: This function is obsolete and only remains for backwards
3344  * compatibility.
3345  */
3346 static int
gtp_reset_life_node_counter(char * s)3347 gtp_reset_life_node_counter(char *s)
3348 {
3349   UNUSED(s);
3350   return gtp_success("");
3351 }
3352 
3353 
3354 /* Function:  Retrieve the count of life nodes.
3355  * Arguments: none
3356  * Fails:     never
3357  * Returns:   number of life nodes
3358  *
3359  * Note: This function is obsolete and only remains for backwards
3360  * compatibility.
3361  */
3362 static int
gtp_get_life_node_counter(char * s)3363 gtp_get_life_node_counter(char *s)
3364 {
3365   UNUSED(s);
3366   return gtp_success("0");
3367 }
3368 
3369 
3370 /* Function:  Reset the count of owl nodes.
3371  * Arguments: none
3372  * Fails:     never
3373  * Returns:   nothing
3374  */
3375 static int
gtp_reset_owl_node_counter(char * s)3376 gtp_reset_owl_node_counter(char *s)
3377 {
3378   UNUSED(s);
3379   reset_owl_node_counter();
3380   return gtp_success("");
3381 }
3382 
3383 
3384 /* Function:  Retrieve the count of owl nodes.
3385  * Arguments: none
3386  * Fails:     never
3387  * Returns:   number of owl nodes
3388  */
3389 static int
gtp_get_owl_node_counter(char * s)3390 gtp_get_owl_node_counter(char *s)
3391 {
3392   int nodes = get_owl_node_counter();
3393   UNUSED(s);
3394   return gtp_success("%d", nodes);
3395 }
3396 
3397 
3398 /* Function:  Reset the count of reading nodes.
3399  * Arguments: none
3400  * Fails:     never
3401  * Returns:   nothing
3402  */
3403 static int
gtp_reset_reading_node_counter(char * s)3404 gtp_reset_reading_node_counter(char *s)
3405 {
3406   UNUSED(s);
3407   reset_reading_node_counter();
3408   return gtp_success("");
3409 }
3410 
3411 
3412 /* Function:  Retrieve the count of reading nodes.
3413  * Arguments: none
3414  * Fails:     never
3415  * Returns:   number of reading nodes
3416  */
3417 static int
gtp_get_reading_node_counter(char * s)3418 gtp_get_reading_node_counter(char *s)
3419 {
3420   int nodes = get_reading_node_counter();
3421   UNUSED(s);
3422   return gtp_success("%d", nodes);
3423 }
3424 
3425 
3426 /* Function:  Reset the count of trymoves/trykos.
3427  * Arguments: none
3428  * Fails:     never
3429  * Returns:   nothing
3430  */
3431 static int
gtp_reset_trymove_counter(char * s)3432 gtp_reset_trymove_counter(char *s)
3433 {
3434   UNUSED(s);
3435   reset_trymove_counter();
3436   return gtp_success("");
3437 }
3438 
3439 
3440 /* Function:  Retrieve the count of trymoves/trykos.
3441  * Arguments: none
3442  * Fails:     never
3443  * Returns:   number of trymoves/trykos
3444  */
3445 static int
gtp_get_trymove_counter(char * s)3446 gtp_get_trymove_counter(char *s)
3447 {
3448   int nodes = get_trymove_counter();
3449   UNUSED(s);
3450   return gtp_success("%d", nodes);
3451 }
3452 
3453 
3454 /* Function:  Reset the count of connection nodes.
3455  * Arguments: none
3456  * Fails:     never
3457  * Returns:   nothing
3458  */
3459 static int
gtp_reset_connection_node_counter(char * s)3460 gtp_reset_connection_node_counter(char *s)
3461 {
3462   UNUSED(s);
3463   reset_connection_node_counter();
3464   return gtp_success("");
3465 }
3466 
3467 
3468 /* Function:  Retrieve the count of connection nodes.
3469  * Arguments: none
3470  * Fails:     never
3471  * Returns:   number of connection nodes
3472  */
3473 static int
gtp_get_connection_node_counter(char * s)3474 gtp_get_connection_node_counter(char *s)
3475 {
3476   int nodes = get_connection_node_counter();
3477   UNUSED(s);
3478   return gtp_success("%d", nodes);
3479 }
3480 
3481 
3482 
3483 /*********
3484  * debug *
3485  *********/
3486 
3487 
3488 /* Function:  Test an eyeshape for inconsistent evaluations
3489  * Arguments: Eyeshape vertices
3490  * Fails:     Bad vertices
3491  * Returns:   Failure reports on stderr.
3492  */
3493 static int
gtp_test_eyeshape(char * s)3494 gtp_test_eyeshape(char *s)
3495 {
3496   int n;
3497   int i, j;
3498   int eye_vertices[MAX_BOARD * MAX_BOARD];
3499   int eyesize = 0;
3500 
3501   n = gtp_decode_coord(s, &i, &j);
3502   while (n > 0) {
3503     eye_vertices[eyesize] = POS(i, j);
3504     eyesize++;
3505     s += n;
3506     n = gtp_decode_coord(s, &i, &j);
3507   }
3508 
3509   if (eyesize == 0)
3510     return gtp_failure("invalid coordinate");
3511 
3512   test_eyeshape(eyesize, eye_vertices);
3513 
3514   return gtp_success("");
3515 }
3516 
3517 
3518 /* Function:  Compute an eyevalue and vital points for an eye graph
3519  * Arguments: Eyeshape encoded in string
3520  * Fails:     Bad eyeshape, analysis failed
3521  * Returns:   Eyevalue, vital points
3522  */
3523 static int
gtp_analyze_eyegraph(char * s)3524 gtp_analyze_eyegraph(char *s)
3525 {
3526   struct eyevalue value;
3527   char analyzed_eyegraph[1024];
3528   int result = analyze_eyegraph(s, &value, analyzed_eyegraph);
3529 
3530   if (result == 0)
3531     return gtp_failure("failed to analyze");
3532 
3533   return gtp_success("%s\n%s", eyevalue_to_string(&value), analyzed_eyegraph);
3534 }
3535 
3536 
3537 
3538 /* Function:  Returns elapsed CPU time in seconds.
3539  * Arguments: none
3540  * Fails:     never
3541  * Returns:   Total elapsed (user + system) CPU time in seconds.
3542  */
3543 static int
gtp_cputime(char * s)3544 gtp_cputime(char *s)
3545 {
3546   UNUSED(s);
3547   return gtp_success("%.3f", gg_cputime());
3548 }
3549 
3550 
3551 
3552 /* Function:  Write the position to stdout.
3553  * Arguments: none
3554  * Fails:     never
3555  * Returns:   nothing
3556  *
3557  * Status:    GTP version 2 standard command.
3558  */
3559 static int
gtp_showboard(char * s)3560 gtp_showboard(char *s)
3561 {
3562   UNUSED(s);
3563 
3564   gtp_start_response(GTP_SUCCESS);
3565   gtp_printf("\n");
3566   simple_showboard(gtp_output_file);
3567   return gtp_finish_response();
3568 }
3569 
3570 
3571 /* Function:  Dump stack to stderr.
3572  * Arguments: none
3573  * Fails:     never
3574  * Returns:   nothing
3575  */
3576 static int
gtp_dump_stack(char * s)3577 gtp_dump_stack(char *s)
3578 {
3579   UNUSED(s);
3580   dump_stack();
3581   return gtp_success("");
3582 }
3583 
3584 /* Determine whether a string starts with a specific substring. */
3585 static int
has_prefix(const char * s,const char * prefix)3586 has_prefix(const char *s, const char *prefix)
3587 {
3588   return strncmp(s, prefix, strlen(prefix)) == 0;
3589 }
3590 
3591 static int
print_influence_data(struct influence_data * q,char * what_data)3592 print_influence_data(struct influence_data *q, char *what_data)
3593 {
3594   float white_influence[BOARDMAX];
3595   float black_influence[BOARDMAX];
3596   float white_strength[BOARDMAX];
3597   float black_strength[BOARDMAX];
3598   float white_attenuation[BOARDMAX];
3599   float black_attenuation[BOARDMAX];
3600   float white_permeability[BOARDMAX];
3601   float black_permeability[BOARDMAX];
3602   float territory_value[BOARDMAX];
3603   int influence_regions[BOARDMAX];
3604   int non_territory[BOARDMAX];
3605   int m, n;
3606 
3607   float *float_pointer = NULL;
3608   int *int_pointer = NULL;
3609 
3610   while (*what_data == ' ')
3611     what_data++;
3612 
3613   get_influence(q, white_influence, black_influence,
3614 		white_strength, black_strength,
3615 		white_attenuation, black_attenuation,
3616 		white_permeability, black_permeability,
3617 		territory_value, influence_regions, non_territory);
3618 
3619   if (has_prefix(what_data, "white_influence"))
3620     float_pointer = white_influence;
3621   else if (has_prefix(what_data, "black_influence"))
3622     float_pointer = black_influence;
3623   else if (has_prefix(what_data, "white_strength"))
3624     float_pointer = white_strength;
3625   else if (has_prefix(what_data, "black_strength"))
3626     float_pointer = black_strength;
3627   else if (has_prefix(what_data, "white_attenuation"))
3628     float_pointer = white_attenuation;
3629   else if (has_prefix(what_data, "black_attenuation"))
3630     float_pointer = black_attenuation;
3631   else if (has_prefix(what_data, "white_permeability"))
3632     float_pointer = white_permeability;
3633   else if (has_prefix(what_data, "black_permeability"))
3634     float_pointer = black_permeability;
3635   else if (has_prefix(what_data, "territory_value"))
3636     float_pointer = territory_value;
3637   else if (has_prefix(what_data, "influence_regions"))
3638     int_pointer = influence_regions;
3639   else if (has_prefix(what_data, "non_territory"))
3640     int_pointer = non_territory;
3641   else
3642     return gtp_failure("unknown influence data");
3643 
3644   gtp_start_response(GTP_SUCCESS);
3645   for (m = 0; m < board_size; m++) {
3646     for (n = 0; n < board_size; n++) {
3647       if (float_pointer)
3648 	gtp_printf("%6.2f ", float_pointer[POS(m, n)]);
3649       else
3650 	gtp_printf("%2d ", int_pointer[POS(m, n)]);
3651     }
3652     gtp_printf("\n");
3653   }
3654 
3655   /* We already have one newline and thus can't use gtp_finish_response(). */
3656   gtp_printf("\n");
3657   return GTP_OK;
3658 }
3659 
3660 /* Function:  Return information about the initial influence function.
3661  * Arguments: color to move, what information
3662  * Fails:     never
3663  * Returns:   Influence data formatted like:
3664  *
3665  *   0.51   1.34   3.20   6.60   9.09   8.06   1.96   0.00   0.00
3666  *   0.45   1.65   4.92  12.19  17.47  15.92   4.03   0.00   0.00
3667  *                   .
3668  *                   .
3669  *                   .
3670  *   0.00   0.00   0.00   0.00   0.00 100.00  75.53  41.47  23.41
3671  *
3672  * The available choices of information are:
3673  *
3674  * white_influence (float)
3675  * black_influence (float)
3676  * white_strength (float)
3677  * black_strength (float)
3678  * white_attenuation (float)
3679  * black_attenuation (float)
3680  * white_permeability (float)
3681  * black_permeability (float)
3682  * territory_value (float)
3683  * influence_regions (int)
3684  * non_territory (int)
3685  *
3686  * The encoding of influence_regions is as follows:
3687  *  4 white stone
3688  *  3 white territory
3689  *  2 white moyo
3690  *  1 white area
3691  *  0 neutral
3692  * -1 black area
3693  * -2 black moyo
3694  * -3 black territory
3695  * -4 black stone
3696  */
3697 static int
gtp_initial_influence(char * s)3698 gtp_initial_influence(char *s)
3699 {
3700   int color;
3701   struct influence_data *q;
3702   int n;
3703 
3704   n = gtp_decode_color(s, &color);
3705   if (n == 0)
3706     return gtp_failure("invalid color");
3707 
3708   q = INITIAL_INFLUENCE(color);
3709 
3710   silent_examine_position(EXAMINE_ALL);
3711 
3712   return print_influence_data(q, s + n);
3713 }
3714 
3715 
3716 /* Function:  Return information about the influence function after a move.
3717  * Arguments: move, what information
3718  * Fails:     never
3719  * Returns:   Influence data formatted like for initial_influence.
3720  */
3721 static int
gtp_move_influence(char * s)3722 gtp_move_influence(char *s)
3723 {
3724   int color;
3725   int i, j;
3726   int n;
3727 
3728   n = gtp_decode_move(s, &color, &i, &j);
3729   if (n == 0)
3730     return gtp_failure("invalid move");
3731 
3732   prepare_move_influence_debugging(POS(i, j), color);
3733 
3734   return print_influence_data(&move_influence, s + n);
3735 }
3736 
3737 
3738 /* Function:  List probabilities of each move being played (when non-zero).
3739  *            If no previous genmove command has been issued, the result
3740  *            of this command will be meaningless.
3741  * Arguments: none
3742  * Fails:     never
3743  * Returns:   Move, probabilty pairs, one per row.
3744  */
3745 static int
gtp_move_probabilities(char * s)3746 gtp_move_probabilities(char *s)
3747 {
3748   float probabilities[BOARDMAX];
3749   int pos;
3750   int any_moves_printed = 0;
3751 
3752   UNUSED(s);
3753 
3754   compute_move_probabilities(probabilities);
3755 
3756   gtp_start_response(GTP_SUCCESS);
3757   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
3758     if (ON_BOARD(pos) && probabilities[pos] != 0.0) {
3759       gtp_mprintf("%m ", I(pos), J(pos));
3760       gtp_printf("%.4f\n", probabilities[pos]);
3761       any_moves_printed = 1;
3762     }
3763   }
3764 
3765   if (!any_moves_printed)
3766     gtp_printf("\n");
3767   gtp_printf("\n");
3768 
3769   return GTP_OK;
3770 }
3771 
3772 
3773 /* Function:  Return the number of bits of uncertainty in the move.
3774  *            If no previous genmove command has been issued, the result
3775  *            of this command will be meaningless.
3776  * Arguments: none
3777  * Fails:     never
3778  * Returns:   bits of uncertainty
3779  */
3780 static int
gtp_move_uncertainty(char * s)3781 gtp_move_uncertainty(char *s)
3782 {
3783   float probabilities[BOARDMAX];
3784   int pos;
3785   double uncertainty = 0.0;
3786 
3787   UNUSED(s);
3788 
3789   compute_move_probabilities(probabilities);
3790 
3791   gtp_start_response(GTP_SUCCESS);
3792   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
3793     if (ON_BOARD(pos) && probabilities[pos] > 0.0) {
3794       /* Shannon's formula */
3795       uncertainty += -1 * ((double)probabilities[pos]) *
3796 	log((double)probabilities[pos]) / log(2.0);
3797     }
3798   }
3799 
3800   gtp_printf("%.4f\n\n", uncertainty);
3801 
3802   return GTP_OK;
3803 }
3804 
3805 
3806 
3807 /* Function:  Return information about the followup influence after a move.
3808  * Arguments: move, what information
3809  * Fails:     never
3810  * Returns:   Influence data formatted like for initial_influence.
3811  */
3812 static int
gtp_followup_influence(char * s)3813 gtp_followup_influence(char *s)
3814 {
3815   int color;
3816   int i, j;
3817   int n;
3818 
3819   n = gtp_decode_move(s, &color, &i, &j);
3820   if (n == 0)
3821     return gtp_failure("invalid move");
3822 
3823   prepare_move_influence_debugging(POS(i, j), color);
3824 
3825   return print_influence_data(&followup_influence, s + n);
3826 }
3827 
3828 
3829 /* Function:  Return the information in the worm data structure.
3830  * Arguments: optional vertex
3831  * Fails:     never
3832  * Returns:   Worm data formatted like:
3833  *
3834  * A19:
3835  * color           black
3836  * size            10
3837  * effective_size  17.83
3838  * origin          A19
3839  * liberties       8
3840  * liberties2      15
3841  * liberties3      10
3842  * liberties4      8
3843  * attack          PASS
3844  * attack_code     0
3845  * lunch           B19
3846  * defend          PASS
3847  * defend_code     0
3848  * cutstone        2
3849  * cutstone2       0
3850  * genus           0
3851  * inessential     0
3852  * B19:
3853  * color           white
3854  * .
3855  * .
3856  * .
3857  * inessential     0
3858  * C19:
3859  * ...
3860  *
3861  * If an intersection is specified, only data for this one will be returned.
3862  */
3863 static int
gtp_worm_data(char * s)3864 gtp_worm_data(char *s)
3865 {
3866   int i = -1;
3867   int j = -1;
3868   int m, n;
3869 
3870   if (sscanf(s, "%*c") >= 0 && !gtp_decode_coord(s, &i, &j))
3871     return gtp_failure("invalid color or coordinate");
3872 
3873   silent_examine_position(EXAMINE_WORMS);
3874 
3875   gtp_start_response(GTP_SUCCESS);
3876 
3877   for (m = 0; m < board_size; m++)
3878     for (n = 0; n < board_size; n++)
3879       if (i == -1 || (m == i && n == j)) {
3880 	struct worm_data *w = &worm[POS(m, n)];
3881 	gtp_print_vertex(m, n);
3882 	gtp_printf(":\n");
3883 	gtp_mprintf("origin               %m\n",  I(w->origin), J(w->origin));
3884 	gtp_mprintf("color                %C\n",  w->color);
3885 	gtp_printf("size                 %d\n",   w->size);
3886 	gtp_printf("effective_size       %.2f\n", w->effective_size);
3887 	gtp_printf("liberties            %d\n",   w->liberties);
3888 	gtp_printf("liberties2           %d\n",   w->liberties2);
3889 	gtp_printf("liberties3           %d\n",   w->liberties3);
3890 	gtp_printf("liberties4           %d\n",   w->liberties4);
3891 	gtp_printf("attack_code          %d\n",   w->attack_codes[0]);
3892 	gtp_mprintf("attack_point         %m\n",
3893 		    I(w->attack_points[0]), J(w->attack_points[0]));
3894 	gtp_printf("defense_code         %d\n",   w->defense_codes[0]);
3895 	gtp_mprintf("defense_point        %m\n",
3896 		    I(w->defense_points[0]), J(w->defense_points[0]));
3897 	gtp_mprintf("lunch                %m\n",
3898 		    I(w->lunch), J(w->lunch));
3899 	gtp_printf("cutstone             %d\n",   w->cutstone);
3900 	gtp_printf("cutstone2            %d\n",   w->cutstone2);
3901 	gtp_printf("genus                %d\n",   w->genus);
3902 	gtp_printf("inessential          %d\n",   w->inessential);
3903 	gtp_printf("invincible           %d\n",   w->invincible);
3904 	gtp_printf("unconditional_status %s\n",
3905 		   status_to_string(w->unconditional_status));
3906       }
3907 
3908   gtp_printf("\n");
3909   return GTP_OK;
3910 }
3911 
3912 /* Function:  List the stones of a worm
3913  * Arguments: the location, "BLACK" or "WHITE"
3914  * Fails:     if called on an empty or off-board location
3915  * Returns:   list of stones
3916  */
3917 static int
gtp_worm_stones(char * s)3918 gtp_worm_stones(char *s)
3919 {
3920   int i = -1;
3921   int j = -1;
3922   int color = EMPTY;
3923   int m, n;
3924   int u, v;
3925   int board_empty = 1;
3926 
3927   if (sscanf(s, "%*c") >= 0) {
3928     if (!gtp_decode_coord(s, &i, &j)
3929 	&& !gtp_decode_color(s, &color))
3930       return gtp_failure("invalid coordinate");
3931   }
3932 
3933   if (BOARD(i, j) == EMPTY)
3934     return gtp_failure("worm_stones called on an empty vertex");
3935 
3936   gtp_start_response(GTP_SUCCESS);
3937 
3938   for (u = 0; u < board_size; u++)
3939     for (v = 0; v < board_size; v++) {
3940       if (BOARD(u, v) == EMPTY
3941 	  || (color != EMPTY && BOARD(u, v) != color))
3942 	continue;
3943       board_empty = 0;
3944       if (find_origin(POS(u, v)) != POS(u, v))
3945 	continue;
3946       if (ON_BOARD2(i, j)
3947 	  && !same_string(POS(u, v), POS(i, j)))
3948 	continue;
3949       for (m = 0; m < board_size; m++)
3950 	for (n = 0; n < board_size; n++)
3951 	  if (BOARD(m, n) != EMPTY
3952 	      && same_string(POS(m, n), POS(u, v)))
3953 	    gtp_mprintf("%m ", m, n);
3954       gtp_printf("\n");
3955     }
3956 
3957   if (board_empty)
3958     gtp_printf("\n"); /* in case no stones have been printed */
3959   gtp_printf("\n");
3960   return GTP_OK;
3961 }
3962 
3963 
3964 
3965 /* Function:  Return the cutstone field in the worm data structure.
3966  * Arguments: non-empty vertex
3967  * Fails:     never
3968  * Returns:   cutstone
3969  */
3970 static int
gtp_worm_cutstone(char * s)3971 gtp_worm_cutstone(char *s)
3972 {
3973 
3974   int i, j;
3975   if (!gtp_decode_coord(s, &i, &j))
3976     return gtp_failure("invalid coordinate");
3977 
3978   if (BOARD(i, j) == EMPTY)
3979     return gtp_failure("vertex must not be empty");
3980 
3981   silent_examine_position(EXAMINE_WORMS);
3982 
3983   return gtp_success(" %d", worm[POS(i, j)].cutstone);
3984 }
3985 
3986 /* Function:  Return the information in the dragon data structure.
3987  * Arguments: optional intersection
3988  * Fails:     never
3989  * Returns:   Dragon data formatted in the corresponding way to gtp_worm_data.
3990  */
3991 static int
gtp_dragon_data(char * s)3992 gtp_dragon_data(char *s)
3993 {
3994   int i = -1;
3995   int j = -1;
3996   int m, n;
3997   int newline_needed = 0;
3998 
3999   if (sscanf(s, "%*c") >= 0 && !gtp_decode_coord(s, &i, &j))
4000     return gtp_failure("invalid coordinate");
4001 
4002   if (stackp > 0)
4003     return gtp_failure("dragon data unavailable when stackp > 0");
4004 
4005   silent_examine_position(FULL_EXAMINE_DRAGONS);
4006 
4007   gtp_start_response(GTP_SUCCESS);
4008 
4009   if (ON_BOARD2(i, j) && BOARD(i, j) == EMPTY)
4010     gtp_mprintf("%m empty\n", i, j);
4011   else {
4012     newline_needed = 1;
4013     for (m = 0; m < board_size; m++)
4014       for (n = 0; n < board_size; n++)
4015 	if ((m == i && n == j)
4016 	    || (i == -1
4017 		&& BOARD(m, n) != EMPTY
4018 		&& dragon[POS(m, n)].origin == POS(m, n))) {
4019 	  gtp_print_vertex(m, n);
4020 	  gtp_printf(":\n");
4021 	  report_dragon(gtp_output_file, POS(m, n));
4022 	  newline_needed = 0;
4023 	}
4024   }
4025   if (newline_needed)
4026     gtp_printf("\n");
4027   gtp_printf("\n");
4028   return GTP_OK;
4029 }
4030 
4031 /* Function:  List the stones of a dragon
4032  * Arguments: the location
4033  * Fails:     if called on an empty or off-board location
4034  * Returns:   list of stones
4035  */
4036 static int
gtp_dragon_stones(char * s)4037 gtp_dragon_stones(char *s)
4038 {
4039   int i = -1;
4040   int j = -1;
4041   int color = EMPTY;
4042   int m, n;
4043   int u, v;
4044 
4045   if (sscanf(s, "%*c") >= 0) {
4046     if (!gtp_decode_coord(s, &i, &j)
4047 	&& !gtp_decode_color(s, &color))
4048     return gtp_failure("invalid coordinate");
4049   }
4050 
4051   if (BOARD(i, j) == EMPTY)
4052     return gtp_failure("dragon_stones called on an empty vertex");
4053 
4054   silent_examine_position(EXAMINE_DRAGONS);
4055 
4056   gtp_start_response(GTP_SUCCESS);
4057 
4058 
4059   for (u = 0; u < board_size; u++)
4060     for (v = 0; v < board_size; v++) {
4061       if (BOARD(u, v) == EMPTY
4062 	  || (color != EMPTY && BOARD(u, v) != color))
4063 	continue;
4064       if (dragon[POS(u, v)].origin != POS(u, v))
4065 	continue;
4066       if (ON_BOARD2(i, j) && dragon[POS(i, j)].origin != POS(u, v))
4067 	continue;
4068       for (m = 0; m < board_size; m++)
4069 	for (n = 0; n < board_size; n++)
4070 	  if (dragon[POS(m, n)].origin == POS(u, v))
4071 	    gtp_mprintf("%m ", m, n);
4072       gtp_printf("\n");
4073     }
4074 
4075   gtp_printf("\n");
4076   return GTP_OK;
4077 }
4078 
4079 /* Function:  Return the information in the eye data structure.
4080  * Arguments: color, vertex
4081  * Fails:     never
4082  * Returns:   eye data fields and values, one pair per row
4083  */
4084 static int
gtp_eye_data(char * s)4085 gtp_eye_data(char *s)
4086 {
4087   int color = EMPTY;
4088   int i = -1;
4089   int j = -1;
4090   struct eye_data *e;
4091 
4092   if (!gtp_decode_move(s, &color, &i, &j))
4093     return gtp_failure("invalid color or coordinate");
4094 
4095   if (stackp > 0)
4096     return gtp_failure("eye data unavailable when stackp > 0");
4097 
4098   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
4099 
4100   gtp_start_response(GTP_SUCCESS);
4101 
4102   if (color == BLACK)
4103     e = &black_eye[POS(i, j)];
4104   else
4105     e = &white_eye[POS(i, j)];
4106 
4107   gtp_mprintf("origin               %m\n", I(e->origin), J(e->origin));
4108   gtp_mprintf("color                %C\n", e->color);
4109   gtp_printf("esize                %d\n", e->esize);
4110   gtp_printf("msize                %d\n", e->msize);
4111   gtp_printf("value                %s\n", eyevalue_to_string(&e->value));
4112   gtp_printf("marginal             %d\n", e->marginal);
4113   gtp_printf("neighbors            %d\n", e->neighbors);
4114   gtp_printf("marginal_neighbors   %d\n", e->marginal_neighbors);
4115 
4116   gtp_printf("\n");
4117   return GTP_OK;
4118 }
4119 
4120 
4121 /* Function:  Return the information in the half eye data structure.
4122  * Arguments: vertex
4123  * Fails:     never
4124  * Returns:   half eye data fields and values, one pair per row
4125  */
4126 static int
gtp_half_eye_data(char * s)4127 gtp_half_eye_data(char *s)
4128 {
4129   int i = -1;
4130   int j = -1;
4131   struct half_eye_data *h;
4132   int k;
4133 
4134   if (!gtp_decode_coord(s, &i, &j))
4135     return gtp_failure("invalid coordinate");
4136 
4137   if (stackp > 0)
4138     return gtp_failure("half eye data unavailable when stackp > 0");
4139 
4140   silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
4141 
4142   gtp_start_response(GTP_SUCCESS);
4143 
4144   h = &half_eye[POS(i, j)];
4145 
4146   gtp_printf("value                %.2f\n", h->value);
4147   if (h->type == HALF_EYE)
4148     gtp_printf("type                 HALF_EYE\n");
4149   else if (h->type == FALSE_EYE)
4150     gtp_printf("type                 FALSE_EYE\n");
4151   else
4152     gtp_printf("type                 %d\n", h->type);
4153   gtp_printf("num_attacks          %d\n", h->num_attacks);
4154   for (k = 0; k < h->num_attacks; k++)
4155     gtp_mprintf("attack_point[%d]      %m\n", k, I(h->attack_point[k]),
4156 		J(h->attack_point[k]));
4157   gtp_printf("num_defenses         %d\n", h->num_defenses);
4158   for (k = 0; k < h->num_defenses; k++)
4159     gtp_mprintf("defense_point[%d]     %m\n", k, I(h->defense_point[k]),
4160 		J(h->defense_point[k]));
4161 
4162   gtp_printf("\n");
4163   return GTP_OK;
4164 }
4165 
4166 
4167 static SGFTree gtp_sgftree;
4168 
4169 /* Function:  Start storing moves executed during reading in an sgf
4170  *            tree in memory.
4171  * Arguments: none
4172  * Fails:     never
4173  * Returns:   nothing
4174  *
4175  * Warning: You had better know what you're doing if you try to use this
4176  *          command.
4177  */
4178 static int
gtp_start_sgftrace(char * s)4179 gtp_start_sgftrace(char *s)
4180 {
4181   UNUSED(s);
4182   sgffile_begindump(&gtp_sgftree);
4183   count_variations = 1;
4184   return gtp_success("");
4185 }
4186 
4187 
4188 /* Function:  Finish storing moves in an sgf tree and write it to file.
4189  * Arguments: filename
4190  * Fails:     never
4191  * Returns:   nothing
4192  *
4193  * Warning: You had better know what you're doing if you try to use this
4194  *          command.
4195  */
4196 static int
gtp_finish_sgftrace(char * s)4197 gtp_finish_sgftrace(char *s)
4198 {
4199   char filename[GTP_BUFSIZE];
4200   int nread;
4201 
4202   nread = sscanf(s, "%s", filename);
4203   if (nread < 1)
4204     return gtp_failure("missing filename");
4205 
4206   sgffile_enddump(filename);
4207   count_variations = 0;
4208   return gtp_success("");
4209 }
4210 
4211 
4212 /* Function:  Dump the current position as a static sgf file to filename,
4213  *            or as output if filename is missing or "-"
4214  * Arguments: optional filename
4215  * Fails:     never
4216  * Returns:   nothing if filename, otherwise the sgf
4217  */
4218 static int
gtp_printsgf(char * s)4219 gtp_printsgf(char *s)
4220 {
4221   char filename[GTP_BUFSIZE];
4222   int nread;
4223   int next;
4224 
4225   if (get_last_player() == EMPTY)
4226     next = BLACK;
4227   else
4228     next = OTHER_COLOR(get_last_player());
4229 
4230   nread = sscanf(s, "%s", filename);
4231 
4232   if (nread < 1)
4233     gg_snprintf(filename, GTP_BUFSIZE, "%s", "-");
4234 
4235   if (strcmp(filename, "-") == 0) {
4236     gtp_start_response(GTP_SUCCESS);
4237     sgffile_printsgf(next, filename);
4238     gtp_printf("\n");
4239     return GTP_OK;
4240   }
4241   else {
4242     sgffile_printsgf(next, filename);
4243     return gtp_success("");
4244   }
4245 }
4246 
4247 
4248 /* Function:  Tune the parameters for the move ordering in the tactical
4249  *            reading.
4250  * Arguments: MOVE_ORDERING_PARAMETERS integers
4251  * Fails:     incorrect arguments
4252  * Returns:   nothing
4253  */
4254 static int
gtp_tune_move_ordering(char * s)4255 gtp_tune_move_ordering(char *s)
4256 {
4257   int params[MOVE_ORDERING_PARAMETERS];
4258   int k;
4259   int p;
4260   int n;
4261 
4262   for (k = 0; k < MOVE_ORDERING_PARAMETERS; k++) {
4263     if (sscanf(s, "%d%n", &p, &n) == 0)
4264       return gtp_failure("incorrect arguments, expected %d integers",
4265 			 MOVE_ORDERING_PARAMETERS);
4266     params[k] = p;
4267     s += n;
4268   }
4269 
4270   tune_move_ordering(params);
4271   return gtp_success("");
4272 }
4273 
4274 /* Function:  Echo the parameter
4275  * Arguments: string
4276  * Fails:     never
4277  * Returns:   nothing
4278  */
4279 static int
gtp_echo(char * s)4280 gtp_echo(char *s)
4281 {
4282   return gtp_success("%s", s);
4283 }
4284 
4285 
4286 /* Function:  Echo the parameter to stdout AND stderr
4287  * Arguments: string
4288  * Fails:     never
4289  * Returns:   nothing
4290  */
4291 static int
gtp_echo_err(char * s)4292 gtp_echo_err(char *s)
4293 {
4294   fprintf(stderr, "%s", s);
4295   fflush(gtp_output_file);
4296   fflush(stderr);
4297   return gtp_success("%s", s);
4298 }
4299 
4300 /* Function:  List all known commands
4301  * Arguments: none
4302  * Fails:     never
4303  * Returns:   list of known commands, one per line
4304  *
4305  * Status:    GTP version 2 standard command.
4306  */
4307 static int
gtp_list_commands(char * s)4308 gtp_list_commands(char *s)
4309 {
4310   int k;
4311   UNUSED(s);
4312 
4313   gtp_start_response(GTP_SUCCESS);
4314 
4315   for (k = 0; commands[k].name != NULL; k++)
4316     gtp_printf("%s\n", commands[k].name);
4317 
4318   gtp_printf("\n");
4319   return GTP_OK;
4320 }
4321 
4322 
4323 /* Function:  Tell whether a command is known.
4324  * Arguments: command name
4325  * Fails:     never
4326  * Returns:   "true" if command exists, "false" if not
4327  *
4328  * Status:    GTP version 2 standard command.
4329  */
4330 static int
gtp_known_command(char * s)4331 gtp_known_command(char *s)
4332 {
4333   int k;
4334   char command[GTP_BUFSIZE];
4335 
4336   if (sscanf(s, "%s", command) == 1) {
4337     for (k = 0; commands[k].name != NULL; k++)
4338       if (strcmp(command, commands[k].name) == 0)
4339 	return gtp_success("true");
4340   }
4341 
4342   return gtp_success("false");
4343 }
4344 
4345 
4346 /* Function:  Turn uncertainty reports from owl_attack
4347  *            and owl_defend on or off.
4348  * Arguments: "on" or "off"
4349  * Fails:     invalid argument
4350  * Returns:   nothing
4351  */
4352 static int
gtp_report_uncertainty(char * s)4353 gtp_report_uncertainty(char *s)
4354 {
4355   if (!strncmp(s, "on", 2)) {
4356     report_uncertainty = 1;
4357     return gtp_success("");
4358   }
4359   if (!strncmp(s, "off", 3)) {
4360     report_uncertainty = 0;
4361     return gtp_success("");
4362   }
4363   return gtp_failure("invalid argument");
4364 }
4365 
4366 
4367 static void
gtp_print_code(int c)4368 gtp_print_code(int c)
4369 {
4370   static int conversion[6] = {
4371     0, /* LOSE */
4372     3, /* KO_B */
4373     5, /* LOSS */
4374     4, /* GAIN */
4375     2, /* KO_A */
4376     1, /* WIN  */
4377   };
4378   gtp_printf("%d", conversion[c]);
4379 }
4380 
4381 static void
gtp_print_vertices2(int n,int * moves)4382 gtp_print_vertices2(int n, int *moves)
4383 {
4384   int movei[MAX_BOARD * MAX_BOARD];
4385   int movej[MAX_BOARD * MAX_BOARD];
4386   int k;
4387 
4388   for (k = 0; k < n; k++) {
4389     movei[k] = I(moves[k]);
4390     movej[k] = J(moves[k]);
4391   }
4392 
4393   gtp_print_vertices(n, movei, movej);
4394 }
4395 
4396 /*************
4397  * transform *
4398  *************/
4399 
4400 static void
rotate_on_input(int ai,int aj,int * bi,int * bj)4401 rotate_on_input(int ai, int aj, int *bi, int *bj)
4402 {
4403   rotate(ai, aj, bi, bj, board_size, gtp_orientation);
4404 }
4405 
4406 static void
rotate_on_output(int ai,int aj,int * bi,int * bj)4407 rotate_on_output(int ai, int aj, int *bi, int *bj)
4408 {
4409   inv_rotate(ai, aj, bi, bj, board_size, gtp_orientation);
4410 }
4411 
4412 
4413 /***************
4414  * random seed *
4415  ***************/
4416 
4417 /* Function:  Get the random seed
4418  * Arguments: none
4419  * Fails:     never
4420  * Returns:   random seed
4421  */
4422 static int
gtp_get_random_seed(char * s)4423 gtp_get_random_seed(char *s)
4424 {
4425   UNUSED(s);
4426   return gtp_success("%d", get_random_seed());
4427 }
4428 
4429 /* Function:  Set the random seed
4430  * Arguments: integer
4431  * Fails:     invalid data
4432  * Returns:   nothing
4433  */
4434 static int
gtp_set_random_seed(char * s)4435 gtp_set_random_seed(char *s)
4436 {
4437   int seed;
4438   if (sscanf(s, "%d", &seed) < 1)
4439     return gtp_failure("invalid seed");
4440 
4441   set_random_seed(seed);
4442   return gtp_success("");
4443 }
4444 
4445 
4446 /* Function:  Advance the random seed by a number of games.
4447  * Arguments: integer
4448  * Fails:     invalid data
4449  * Returns:   New random seed.
4450  */
4451 static int
gtp_advance_random_seed(char * s)4452 gtp_advance_random_seed(char *s)
4453 {
4454   int i;
4455   int games;
4456   if (sscanf(s, "%d", &games) < 1
4457       || games < 0)
4458     return gtp_failure("invalid number of games");
4459 
4460   for (i = 0; i < games; i++)
4461     update_random_seed();
4462 
4463   return gtp_success("%d", get_random_seed());
4464 }
4465 
4466 /***************
4467  * surrounding *
4468  ***************/
4469 
4470 /* Function:  Determine if a dragon is surrounded
4471  * Arguments: vertex (dragon)
4472  * Fails:     invalid vertex, empty vertex
4473  * Returns:   1 if surrounded, 2 if weakly surrounded, 0 if not
4474  */
4475 static int
gtp_is_surrounded(char * s)4476 gtp_is_surrounded(char *s)
4477 {
4478   int i, j;
4479   int n;
4480 
4481   n = gtp_decode_coord(s, &i, &j);
4482   if (n == 0)
4483     return gtp_failure("invalid coordinate");
4484 
4485   if (BOARD(i, j) == EMPTY)
4486     return gtp_failure("dragon vertex must be nonempty");
4487 
4488   silent_examine_position(EXAMINE_DRAGONS);
4489   return gtp_success("%d", DRAGON2(POS(i, j)).surround_status);
4490 }
4491 
4492 /* Function:  Determine if a move surrounds a dragon
4493  * Arguments: vertex (move), vertex (dragon)
4494  * Fails:     invalid vertex, empty (dragon, nonempty (move)
4495  * Returns:   1 if (move) surrounds (dragon)
4496  */
4497 static int
gtp_does_surround(char * s)4498 gtp_does_surround(char *s)
4499 {
4500   int si, sj, di, dj;
4501   int n;
4502 
4503   n = gtp_decode_coord(s, &si, &sj);
4504   if (n == 0)
4505     return gtp_failure("invalid coordinate");
4506 
4507   if (BOARD(si, sj) != EMPTY)
4508     return gtp_failure("move vertex must be empty");
4509 
4510   n = gtp_decode_coord(s + n, &di, &dj);
4511   if (n == 0)
4512     return gtp_failure("invalid coordinate");
4513 
4514   if (BOARD(di, dj) == EMPTY)
4515     return gtp_failure("dragon vertex must be nonempty");
4516 
4517   silent_examine_position(EXAMINE_DRAGONS);
4518   return gtp_success("%d", does_surround(POS(si, sj), POS(di, dj)));
4519 }
4520 
4521 /* Function:  Report the surround map for dragon at a vertex
4522  * Arguments: vertex (dragon), vertex (mapped location)
4523  * Fails:     invalid vertex, empty dragon
4524  * Returns:   value of surround map at (mapped location), or -1 if
4525  *            dragon not surrounded.
4526  */
4527 
4528 static int
gtp_surround_map(char * s)4529 gtp_surround_map(char *s)
4530 {
4531   int di, dj, mi, mj;
4532   int n;
4533 
4534   n = gtp_decode_coord(s, &di, &dj);
4535   if (n == 0)
4536     return gtp_failure("invalid coordinate");
4537 
4538   if (BOARD(di, dj) == EMPTY)
4539     return gtp_failure("dragon vertex must not be empty");
4540 
4541   n = gtp_decode_coord(s + n, &mi, &mj);
4542   if (n == 0)
4543     return gtp_failure("invalid coordinate");
4544 
4545   silent_examine_position(EXAMINE_DRAGONS);
4546   return gtp_success("%d", surround_map(POS(di, dj), POS(mi, mj)));
4547 }
4548 
4549 /***************
4550  * search area *
4551  ***************/
4552 
4553 /* Function:  limit search, and establish a search diamond
4554  * Arguments: pos
4555  * Fails:     invalid value
4556  * Returns:   nothing
4557  */
4558 static int
gtp_set_search_diamond(char * s)4559 gtp_set_search_diamond(char *s)
4560 {
4561   int i, j;
4562 
4563   if (!gtp_decode_coord(s, &i, &j))
4564     return gtp_failure("invalid coordinate");
4565 
4566   set_limit_search(1);
4567   set_search_diamond(POS(i, j));
4568   return gtp_success("");
4569 }
4570 
4571 /* Function:  unmark the entire board for limited search
4572  * Arguments: none
4573  * Fails:     never
4574  * Returns:   nothing
4575  */
4576 static int
gtp_reset_search_mask(char * s)4577 gtp_reset_search_mask(char *s)
4578 {
4579   UNUSED(s);
4580 
4581   reset_search_mask();
4582   return gtp_success("");
4583 }
4584 
4585 /* Function:  sets the global variable limit_search
4586  * Arguments: value
4587  * Fails:     invalid arguments
4588  * Returns:   nothing
4589  */
4590 static int
gtp_limit_search(char * s)4591 gtp_limit_search(char *s)
4592 {
4593   int value;
4594 
4595   if (sscanf(s, "%d", &value) < 1)
4596     return gtp_failure("invalid value for search limit");
4597   set_limit_search(value);
4598   return gtp_success("");
4599 }
4600 
4601 /* Function:  mark a vertex for limited search
4602  * Arguments: position
4603  * Fails:     invalid arguments
4604  * Returns:   nothing
4605  */
4606 static int
gtp_set_search_limit(char * s)4607 gtp_set_search_limit(char *s)
4608 {
4609   int i, j;
4610 
4611   gtp_decode_coord(s, &i, &j);
4612   set_search_mask(POS(i, j), 1);
4613   return gtp_success("");
4614 }
4615 
4616 /* Function:  Draw search area. Writes to stderr.
4617  * Arguments: none
4618  * Fails:     never
4619  * Returns:   nothing
4620  */
4621 static int
gtp_draw_search_area(char * s)4622 gtp_draw_search_area(char *s)
4623 {
4624   UNUSED(s);
4625 
4626   gtp_start_response(GTP_SUCCESS);
4627   gtp_printf("\n");
4628   draw_search_area();
4629   return gtp_finish_response();
4630 }
4631 
4632 
4633 
4634 /*
4635  * Local Variables:
4636  * tab-width: 8
4637  * c-basic-offset: 2
4638  * End:
4639  */
4640