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 <stdlib.h>
28 #include <string.h>
29 
30 #include "liberty.h"
31 #include "patterns.h"
32 
33 static void compute_effective_worm_sizes(void);
34 static void do_compute_effective_worm_sizes(int color,
35 					    int (*cw)[MAX_CLOSE_WORMS],
36 					    int *ncw, int max_distance);
37 static void compute_unconditional_status(void);
38 static void find_worm_attacks_and_defenses(void);
39 static void find_worm_threats(void);
40 static int find_lunch(int str, int *lunch);
41 static void change_tactical_point(int str, int move, int code,
42 				  int points[MAX_TACTICAL_POINTS],
43 				  int codes[MAX_TACTICAL_POINTS]);
44 static void propagate_worm2(int str);
45 static int genus(int str);
46 static void markcomponent(int str, int pos, int mg[BOARDMAX]);
47 static int examine_cavity(int pos, int *edge);
48 static void cavity_recurse(int pos, int mx[BOARDMAX],
49 			   int *border_color, int *edge, int str);
50 static void ping_cave(int str, int *result1,  int *result2,
51 		      int *result3, int *result4);
52 static void ping_recurse(int pos, int *counter,
53 			 int mx[BOARDMAX],
54 			 int mr[BOARDMAX], int color);
55 static int touching(int pos, int color);
56 static void find_attack_patterns(void);
57 static void attack_callback(int anchor, int color,
58 			    struct pattern *pattern, int ll, void *data);
59 static void find_defense_patterns(void);
60 static void defense_callback(int anchor, int color,
61 			     struct pattern *pattern, int ll, void *data);
62 static void build_worms(void);
63 static void report_worm(int pos);
64 
65 /* A worm or string is a maximal connected set of stones of the same color,
66  * black or white.
67  *
68  * Cavities are sets of connected empty vertices.
69  */
70 
71 
72 /* make_worms() finds all worms and assembles some data about them.
73  *
74  * Each worm is marked with an origin.  This is an arbitrarily chosen
75  * element of the worm, in practice the algorithm puts the origin at
76  * the first element when they are given the lexicographical order,
77  * though its location is irrelevant for applications. To see if two
78  * stones lie in the same worm, compare their origins.
79  *
80  * We will use the field dragon[ii].genus to keep track of
81  * black- or white-bordered cavities (essentially eyes) which are found.
82  * so this field must be zero'd now.
83  */
84 
85 void
make_worms(void)86 make_worms(void)
87 {
88   int pos;
89 
90   /* Build the basic worm data:  color, origin, size, liberties. */
91   build_worms();
92 
93   /* No point continuing if the board is completely empty. */
94   if (stones_on_board(BLACK | WHITE) == 0)
95     return;
96 
97   /* Compute effective sizes of all worms. */
98   compute_effective_worm_sizes();
99 
100   /* Look for unconditionally alive and dead worms, and unconditional
101    * territory.
102    */
103   compute_unconditional_status();
104 
105   find_worm_attacks_and_defenses();
106 
107   gg_assert(stackp == 0);
108 
109   /* Count liberties of different orders and initialize cutstone fields. */
110   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
111     if (IS_STONE(board[pos]) && is_worm_origin(pos, pos)) {
112       int lib1, lib2, lib3, lib4;
113 
114       ping_cave(pos, &lib1, &lib2, &lib3, &lib4);
115       ASSERT1(worm[pos].liberties == lib1, pos);
116       worm[pos].liberties2 = lib2;
117       worm[pos].liberties3 = lib3;
118       worm[pos].liberties4 = lib4;
119       worm[pos].cutstone = 0;
120       worm[pos].cutstone2 = 0;
121       propagate_worm(pos);
122     }
123   }
124 
125   gg_assert(stackp == 0);
126 
127   /*
128    * There are two concepts of cutting stones in the worm array.
129    *
130    * worm.cutstone:
131    *
132    *     A CUTTING STONE is one adjacent to two enemy strings,
133    *     which do not have a liberty in common. The most common
134    *     type of cutting string is in this situation.
135    *
136    *     XO
137    *     OX
138    *
139    *     A POTENTIAL CUTTING STONE is adjacent to two enemy
140    *     strings which do share a liberty. For example, X in:
141    *
142    *     XO
143    *     O.
144    *
145    *     For cutting strings we set worm[m][n].cutstone=2. For potential
146    *     cutting strings we set worm[m][n].cutstone=1. For other strings,
147    *     worm[m][n].cutstone=0.
148    *
149    * worm.cutstone2:
150    *
151    *     Cutting points are identified by the patterns in the
152    *     connections database. Proper cuts are handled by the fact
153    *     that attacking and defending moves also count as moves
154    *     cutting or connecting the surrounding dragons.
155    *
156    * The cutstone field will now be set. The cutstone2 field is set
157    * later, during find_cuts(), called from make_dragons().
158    *
159    * We maintain both fields because the historically older cutstone
160    * field is needed to deal with the fact that e.g. in the position
161    *
162    *
163    *    OXX.O
164    *    .OOXO
165    *    OXX.O
166    *
167    * the X stones are amalgamated into one dragon because neither cut
168    * works as long as the two O stones are in atari. Therefore we add
169    * one to the cutstone field for each potential cutting point,
170    * indicating that these O stones are indeed worth rescuing.
171    *
172    * For the time being we use both concepts in parallel. It's
173    * possible we also need the old concept for correct handling of lunches.
174    */
175 
176   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
177     int w1 = NO_MOVE;
178     int w2 = NO_MOVE;
179     int k;
180     int pos2;
181 
182     /* Only work on each worm once. This is easiest done if we only
183      * work with the origin of each worm.
184      */
185     if (!IS_STONE(board[pos]) || !is_worm_origin(pos, pos))
186       continue;
187 
188     /* Try to find two adjacent worms (w1) and (w2)
189      * of opposite colour from (pos).
190      */
191     for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++) {
192       /* Work only with the opposite color from (pos). */
193       if (board[pos2] != OTHER_COLOR(board[pos]))
194 	continue;
195 
196       for (k = 0; k < 4; k++) {
197 	if (!ON_BOARD(pos2 + delta[k])
198 	    || worm[pos2 + delta[k]].origin != pos)
199 	  continue;
200 
201 	ASSERT1(board[pos2 + delta[k]] == board[pos], pos);
202 
203 	/* If we have not already found a worm which meets the criteria,
204 	 * store it into (w1), otherwise store it into (w2).
205 	 */
206 	if (w1 == NO_MOVE)
207 	  w1 = worm[pos2].origin;
208 	else if (!is_same_worm(pos2, w1))
209 	  w2 = worm[pos2].origin;
210       }
211     }
212 
213     /*
214      *  We now verify the definition of cutting stones. We have
215      *  verified that the string at (pos) is adjacent to two enemy
216      *  strings at (w1) and (w2). We need to know if these
217      *  strings share a liberty.
218      */
219 
220     /* Only do this if we really found something. */
221     if (w2 != NO_MOVE) {
222       worm[pos].cutstone = 2;
223       if (count_common_libs(w1, w2) > 0)
224 	worm[pos].cutstone = 1;
225 
226       DEBUG(DEBUG_WORMS, "Worm at %1m has w1 %1m and w2 %1m, cutstone %d\n",
227 	    pos, w1, w2, worm[pos].cutstone);
228     }
229   }
230 
231   gg_assert(stackp == 0);
232 
233   /* Set the genus of all worms. */
234   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
235     if (IS_STONE(board[pos]) && is_worm_origin(pos, pos)) {
236       worm[pos].genus = genus(pos);
237       propagate_worm(pos);
238     }
239   }
240   gg_assert(stackp == 0);
241 
242   /* Now we try to improve the values of worm.attack and worm.defend.
243    * If we find that capturing the string at str also defends the
244    * string at str2, or attacks it, then we add points of attack and
245    * defense. We don't add attacking point for strings that can't be
246    * defended.
247    */
248   {
249     int color;
250     int str;
251     int moves_to_try[BOARDMAX];
252     memset(moves_to_try, 0, sizeof(moves_to_try));
253 
254     /* Find which colors to try at what points. */
255     for (str = BOARDMIN; str < BOARDMAX; str++) {
256       if (IS_STONE(board[str]) && is_worm_origin(str, str)) {
257 	color = board[str];
258 	moves_to_try[worm[str].defense_points[0]] |= color;
259 	moves_to_try[worm[str].attack_points[0]] |= OTHER_COLOR(color);
260       }
261     }
262 
263     /* Loop over the board and over the colors and try the moves found
264      * in the previous loop.
265      */
266     for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
267       if (!ON_BOARD(pos))
268 	continue;
269 
270       for (color = WHITE; color <= BLACK; color++) {
271 	if (!(moves_to_try[pos] & color))
272 	  continue;
273 
274 	/* Try to play color at pos and see what it leads to. */
275 	if (!trymove(pos, color, "make_worms", NO_MOVE))
276 	  continue;
277 
278 	/* We must read to the same depth that was used in the
279 	 * initial determination of worm.attack and worm.defend
280 	 * to avoid horizon effects. Since stackp has been
281 	 * incremented we must also increment depth values.
282 	 */
283 
284 	DEBUG(DEBUG_WORMS, "trying %1m\n", pos);
285 	increase_depth_values();
286 
287 	/* Now we try to find a group which is saved or attacked as well
288 	 * by this move.
289 	 */
290 	for (str = BOARDMIN; str < BOARDMAX; str++) {
291 	  if (!IS_STONE(board[str])
292 	      || !is_worm_origin(str, str))
293 	    continue;
294 
295 	  /* If the worm is of the opposite color to the move,
296 	   * then we try to defend it. If there was a previous
297 	   * attack and defense of it, and there is no defense
298 	   * for the attack now...
299 	   */
300 	  if (worm[str].color == OTHER_COLOR(color)
301 	      && worm[str].attack_codes[0] != 0
302 	      && worm[str].defense_codes[0] != 0) {
303 	    int dcode = find_defense(str, NULL);
304 	    if (dcode < worm[str].defense_codes[0]) {
305 	      int attack_works = 1;
306 
307 	      /* Sometimes find_defense() fails to find a
308 	       * defense which has been found by other means.
309 	       * Try if the old defense move still works.
310 	       *
311 	       * However, we first check if the _attack_ still exists,
312 	       * because we could, for instance, drive the worm into
313 	       * seki with our move.
314 	       */
315 	      if (attack(str, NULL) >= worm[str].attack_codes[0]) {
316 		if (worm[str].defense_codes[0] != 0
317 		    && trymove(worm[str].defense_points[0],
318 			       OTHER_COLOR(color), "make_worms", 0)) {
319 		  int this_dcode = REVERSE_RESULT(attack(str, NULL));
320 		  if (this_dcode > dcode) {
321 		    dcode = this_dcode;
322 		    if (dcode >= worm[str].defense_codes[0])
323 		      attack_works = 0;
324 		  }
325 		  popgo();
326 		}
327 	      }
328 	      else
329 		attack_works = 0;
330 
331 	      /* ...then add an attack point of that worm at pos. */
332 	      if (attack_works) {
333 		DEBUG(DEBUG_WORMS,
334 		      "adding point of attack of %1m at %1m with code %d\n",
335 		      str, pos, REVERSE_RESULT(dcode));
336 		change_attack(str, pos, REVERSE_RESULT(dcode));
337 	      }
338 	    }
339 	  }
340 
341 	  /* If the worm is of the same color as the move we try to
342 	   * attack it. If there previously was an attack on it, but
343 	   * there is none now, then add a defense point of str at
344 	   * pos.
345 	   */
346 	  else if (worm[str].color == color
347 		   && worm[str].attack_codes[0] != 0) {
348 	    int acode = attack(str, NULL);
349 	    if (acode < worm[str].attack_codes[0]) {
350 	      int defense_works = 1;
351 	      /* Sometimes attack() fails to find an
352 	       * attack which has been found by other means.
353 	       * Try if the old attack move still works.
354 	       */
355 	      if (worm[str].attack_codes[0] != 0
356 		  && trymove(worm[str].attack_points[0],
357 			     OTHER_COLOR(color), "make_worms", 0)) {
358 		int this_acode;
359 		if (board[str] == EMPTY)
360 		  this_acode = WIN;
361 		else
362 		  this_acode = REVERSE_RESULT(find_defense(str, NULL));
363 		if (this_acode > acode) {
364 		  acode = this_acode;
365 		  if (acode >= worm[str].attack_codes[0])
366 		    defense_works = 0;
367 		}
368 		popgo();
369 	      }
370 
371 	      /* ...then add an attack point of that worm at pos. */
372 	      if (defense_works) {
373 		DEBUG(DEBUG_WORMS,
374 		      "adding point of defense of %1m at %1m with code %d\n",
375 		      str, pos, REVERSE_RESULT(acode));
376 		change_defense(str, pos, REVERSE_RESULT(acode));
377 	      }
378 	    }
379 	  }
380 	}
381 	decrease_depth_values();
382 	popgo();
383       }
384     }
385   }
386 
387   gg_assert(stackp == 0);
388 
389   /* Sometimes it happens that the tactical reading finds adjacent
390    * strings which both can be attacked but not defended. (The reason
391    * seems to be that the attacker tries harder to attack a string,
392    * than the defender tries to capture it's neighbors.) When this
393    * happens, the eyes code produces overlapping eye spaces and, still
394    * worse, all the nondefendable stones actually get amalgamated with
395    * their allies on the outside.
396    *
397    * To solve this we scan through the strings which can't be defended
398    * and check whether they have a neighbor that can be attacked. In
399    * this case we set the defense point of the former string to the
400    * attacking point of the latter.
401    *
402    * Please notice that find_defense() will still read this out
403    * incorrectly, which may lead to some confusion later.
404    */
405 
406   /* First look for vertical neighbors. */
407   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
408     if (IS_STONE(board[pos])
409 	&& IS_STONE(board[SOUTH(pos)])
410 	&& !is_same_worm(pos, SOUTH(pos))) {
411       if (worm[pos].attack_codes[0] != 0
412 	  && worm[SOUTH(pos)].attack_codes[0] != 0) {
413 	if (worm[pos].defense_codes[0] == 0
414 	    && does_defend(worm[SOUTH(pos)].attack_points[0], pos)) {
415 	  /* FIXME: need to check ko relationship here */
416 	  change_defense(pos, worm[SOUTH(pos)].attack_points[0], WIN);
417 	}
418 	if (worm[SOUTH(pos)].defense_codes[0] == 0
419 	    && does_defend(worm[pos].attack_points[0], SOUTH(pos))) {
420 	  /* FIXME: need to check ko relationship here */
421 	  change_defense(SOUTH(pos), worm[pos].attack_points[0], WIN);
422 	}
423       }
424     }
425   }
426 
427   /* Then look for horizontal neighbors. */
428   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
429     if (IS_STONE(board[pos])
430 	&& IS_STONE(board[EAST(pos)])
431 	&& !is_same_worm(pos, EAST(pos))) {
432       if (worm[pos].attack_codes[0] != 0
433 	  && worm[EAST(pos)].attack_codes[0] != 0) {
434 	if (worm[pos].defense_codes[0] == 0
435 	    && does_defend(worm[EAST(pos)].attack_points[0], pos)) {
436 	  /* FIXME: need to check ko relationship here */
437 	  change_defense(pos, worm[EAST(pos)].attack_points[0], WIN);
438 	}
439 	if (worm[EAST(pos)].defense_codes[0] == 0
440 	    && does_defend(worm[pos].attack_points[0], EAST(pos))) {
441 	  /* FIXME: need to check ko relationship here */
442 	  change_defense(EAST(pos), worm[pos].attack_points[0], WIN);
443 	}
444       }
445     }
446   }
447 
448   gg_assert(stackp == 0);
449 
450   /* Find adjacent worms that can be easily captured, aka lunches. */
451 
452   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
453     int lunch;
454 
455     if (!IS_STONE(board[pos]) || !is_worm_origin(pos, pos))
456       continue;
457 
458     if (find_lunch(pos, &lunch)
459 	&& (worm[lunch].attack_codes[0] == WIN
460 	    || worm[lunch].attack_codes[0] == KO_A)) {
461       DEBUG(DEBUG_WORMS, "lunch found for %1m at %1m\n", pos, lunch);
462       worm[pos].lunch = lunch;
463     }
464     else
465       worm[pos].lunch = NO_MOVE;
466 
467     propagate_worm(pos);
468   }
469 
470   if (!disable_threat_computation)
471     find_worm_threats();
472 
473   /* Identify INESSENTIAL strings.
474    *
475    * These are defined as surrounded strings which have no life
476    * potential unless part of their surrounding chain can be captured.
477    * We give a conservative definition of inessential:
478    *  - the genus must be zero
479    *  - there can no second order liberties
480    *  - there can be no more than two edge liberties
481    *  - if it is removed from the board, the remaining cavity has
482    *    border color the opposite color of the string
483    *  - it contains at most two edge vertices.
484    *
485    * If we get serious about identifying seki, we might want to add:
486    *
487    *  - if it has fewer than 4 liberties it is tactically dead.
488    *
489    * The last condition is helpful in excluding strings which are
490    * alive in seki.
491    *
492    * An inessential string can be thought of as residing inside the
493    * opponent's eye space.
494    */
495 
496   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
497     if (IS_STONE(board[pos])
498 	&& worm[pos].origin == pos
499 	&& worm[pos].genus == 0
500 	&& worm[pos].liberties2 == 0
501 	&& !worm[pos].cutstone
502 	&& worm[pos].lunch == NO_MOVE) {
503       int edge;
504       int border_color = examine_cavity(pos, &edge);
505       if (border_color != GRAY && edge < 3) {
506 	DEBUG(DEBUG_WORMS, "Worm %1m identified as inessential.\n", pos);
507 	worm[pos].inessential = 1;
508 	propagate_worm(pos);
509       }
510     }
511   }
512 }
513 
514 
515 /*
516  * Clear all worms and initialize the basic data fields:
517  *   color, origin, size, liberties
518  * This is a substep of make_worms().
519  */
520 
521 static void
build_worms()522 build_worms()
523 {
524   int pos;
525 
526   /* Set all worm data fields to 0. */
527   memset(worm, 0 , sizeof(worm));
528 
529   /* Initialize the worm data for each worm. */
530   for (pos = BOARDMIN; pos < BOARDMAX; pos++)
531     if (ON_BOARD(pos))
532       worm[pos].origin = NO_MOVE;
533 
534   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
535     if (!ON_BOARD(pos) || worm[pos].origin != NO_MOVE)
536       continue;
537     worm[pos].color = board[pos];
538     worm[pos].origin = pos;
539     worm[pos].inessential = 0;
540     worm[pos].invincible = 0;
541     worm[pos].unconditional_status = UNKNOWN;
542     worm[pos].effective_size = 0.0;
543     if (IS_STONE(board[pos])) {
544       worm[pos].liberties = countlib(pos);
545       worm[pos].size = countstones(pos);
546       propagate_worm(pos);
547     }
548   }
549 }
550 
551 
552 /* Compute effective size of each worm.
553  *
554  * Effective size is the number of stones in a worm plus half the
555  * number of empty intersections that are at least as close to this
556  * worm as to any other worm. This is used to estimate the direct
557  * territorial value of capturing a worm. Intersections that are
558  * shared are counted with equal fractional values for each worm.
559  *
560  * We never count intersections further away than distance 3.
561  *
562  * This function is also used to compute arrays with information about
563  * the distances to worms of both or either color. In the latter case
564  * we count intersections up to a distance of 5.
565  */
566 
567 static void
compute_effective_worm_sizes()568 compute_effective_worm_sizes()
569 {
570   do_compute_effective_worm_sizes(BLACK | WHITE, close_worms,
571 				  number_close_worms, 3);
572   do_compute_effective_worm_sizes(BLACK, close_black_worms,
573 				  number_close_black_worms, 5);
574   do_compute_effective_worm_sizes(WHITE, close_white_worms,
575 				  number_close_white_worms, 5);
576 }
577 
578 static void
do_compute_effective_worm_sizes(int color,int (* cw)[MAX_CLOSE_WORMS],int * ncw,int max_distance)579 do_compute_effective_worm_sizes(int color, int (*cw)[MAX_CLOSE_WORMS],
580 				int *ncw, int max_distance)
581 {
582   int pos;
583 
584   /* Distance to closest worm, -1 means unassigned, 0 that there is
585    * a stone at the location, 1 a liberty of a stone, and so on.
586    */
587   int distance[BOARDMAX];
588   /* Pointer to the origin of the closest worms. A very large number of
589    * worms may potentially be equally close, but no more than
590    * 2*(board_size-1).
591    */
592   static int worms[BOARDMAX][2*(MAX_BOARD-1)];
593   int nworms[BOARDMAX];   /* number of equally close worms */
594   int found_one;
595   int dist; /* current distance */
596   int k, l;
597   int r;
598 
599   /* Initialize arrays. */
600   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
601     if (!ON_BOARD(pos))
602       continue;
603 
604     for (k = 0; k < 2*(board_size-1); k++)
605       worms[pos][k] = NO_MOVE;
606 
607     nworms[pos] = 0;
608 
609     if (board[pos] & color) {
610       distance[pos] = 0;
611       worms[pos][0] = worm[pos].origin;
612       nworms[pos]++;
613     }
614     else
615       distance[pos] = -1;
616   }
617 
618   dist = 0;
619   found_one = 1;
620   while (found_one && dist <= max_distance) {
621     found_one = 0;
622     dist++;
623     for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
624       if (!ON_BOARD(pos) || distance[pos] != -1)
625 	continue; /* already claimed */
626 
627       for (r = 0; r < 4; r++) {
628 	int pos2 = pos + delta[r];
629 
630 	if (ON_BOARD(pos2) && distance[pos2] == dist - 1) {
631 	  found_one = 1;
632 	  distance[pos] = dist;
633 	  for (k = 0; k < nworms[pos2]; k++) {
634 	    int already_counted = 0;
635 	    for (l = 0; l < nworms[pos]; l++)
636 	      if (worms[pos][l] == worms[pos2][k]) {
637 		already_counted = 1;
638 		break;
639 	      }
640 	    if (!already_counted) {
641 	      ASSERT1(nworms[pos] < 2*(board_size-1), pos);
642 	      worms[pos][nworms[pos]] = worms[pos2][k];
643 	      nworms[pos]++;
644 	    }
645 	  }
646 	}
647       }
648     }
649   }
650 
651   /* Compute the effective sizes but only when all worms are considered. */
652   if (color == (BLACK | WHITE)) {
653     /* Distribute (fractional) contributions to the worms. */
654     for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
655       if (!ON_BOARD(pos))
656 	continue;
657 
658       for (k = 0; k < nworms[pos]; k++) {
659 	int w = worms[pos][k];
660 	if (board[pos] == EMPTY)
661 	  worm[w].effective_size += 0.5/nworms[pos];
662 	else
663 	  worm[w].effective_size += 1.0;
664       }
665     }
666 
667     /* Propagate the effective size values all over the worms. */
668     for (pos = BOARDMIN; pos < BOARDMAX; pos++)
669       if (IS_STONE(board[pos]) && is_worm_origin(pos, pos))
670 	propagate_worm(pos);
671   }
672 
673   /* Fill in the appropriate close_*_worms (cw) and
674    * number_close_*_worms (ncw) arrays.
675    */
676   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
677     if (!ON_BOARD(pos))
678       continue;
679 
680     if (nworms[pos] > MAX_CLOSE_WORMS)
681       ncw[pos] = 0;
682     else
683       ncw[pos] = nworms[pos];
684 
685     for (k = 0; k < ncw[pos]; k++)
686       cw[pos][k] = worms[pos][k];
687   }
688 }
689 
690 /* Identify worms which are unconditionally uncapturable in the
691  * strongest sense, i.e. even if the opponent is allowed an arbitrary
692  * number of consecutive moves. Also identify worms which are
693  * similarly unconditionally dead and empty points which are
694  * unconditional territory for either player.
695  */
696 static void
compute_unconditional_status()697 compute_unconditional_status()
698 {
699   int unconditional_territory[BOARDMAX];
700   int pos;
701   int color;
702 
703   for (color = WHITE; color <= BLACK; color++) {
704     unconditional_life(unconditional_territory, color);
705     if (get_level() >= 10)
706       find_unconditionally_meaningless_moves(unconditional_territory, color);
707 
708     for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
709       if (!ON_BOARD(pos) || !unconditional_territory[pos])
710 	continue;
711 
712       if (board[pos] == color) {
713 	worm[pos].unconditional_status = ALIVE;
714 	if (unconditional_territory[pos] == 1)
715 	  worm[pos].invincible = 1;
716       }
717       else if (board[pos] == EMPTY) {
718 	if (color == WHITE)
719 	  worm[pos].unconditional_status = WHITE_TERRITORY;
720 	else
721 	  worm[pos].unconditional_status = BLACK_TERRITORY;
722       }
723       else
724 	worm[pos].unconditional_status = DEAD;
725     }
726   }
727   gg_assert(stackp == 0);
728 }
729 
730 /*
731  * Analyze tactical safety of each worm.
732  */
733 
734 static void
find_worm_attacks_and_defenses()735 find_worm_attacks_and_defenses()
736 {
737   int str;
738   int k;
739   int acode, dcode;
740   int attack_point;
741   int defense_point;
742   static int libs[MAXLIBS];
743   int liberties;
744   int color;
745   int other;
746 
747    /* 1. Start with finding attack points. */
748   for (str = BOARDMIN; str < BOARDMAX; str++) {
749     if (!IS_STONE(board[str]) || !is_worm_origin(str, str))
750       continue;
751 
752     TRACE("considering attack of %1m\n", str);
753     /* Initialize all relevant fields at once. */
754     for (k = 0; k < MAX_TACTICAL_POINTS; k++) {
755       worm[str].attack_codes[k]   = 0;
756       worm[str].attack_points[k]  = 0;
757       worm[str].defense_codes[k]  = 0;
758       worm[str].defense_points[k] = 0;
759     }
760     propagate_worm(str);
761 
762     acode = attack(str, &attack_point);
763     if (acode != 0) {
764       DEBUG(DEBUG_WORMS, "worm at %1m can be attacked at %1m\n",
765 	    str, attack_point);
766       change_attack(str, attack_point, acode);
767     }
768   }
769   gg_assert(stackp == 0);
770 
771   /* 2. Use pattern matching to find a few more attacks. */
772   find_attack_patterns();
773   gg_assert(stackp == 0);
774 
775   /* 3. Now find defense moves. */
776   for (str = BOARDMIN; str < BOARDMAX; str++) {
777     if (!IS_STONE(board[str]) || !is_worm_origin(str, str))
778       continue;
779 
780     if (worm[str].attack_codes[0] != 0) {
781 
782       TRACE("considering defense of %1m\n", str);
783       dcode = find_defense(str, &defense_point);
784       if (dcode != 0) {
785 	TRACE("worm at %1m can be defended at %1m\n", str, defense_point);
786 	if (defense_point != NO_MOVE)
787 	  change_defense(str, defense_point, dcode);
788       }
789       else {
790 	/* If the point of attack is not adjacent to the worm,
791 	 * it is possible that this is an overlooked point of
792 	 * defense, so we try and see if it defends.
793 	 */
794 	attack_point = worm[str].attack_points[0];
795 	if (!liberty_of_string(attack_point, str))
796 	  if (trymove(attack_point, worm[str].color, "make_worms", NO_MOVE)) {
797 	    int acode = attack(str, NULL);
798 	    if (acode != WIN) {
799 	      change_defense(str, attack_point, REVERSE_RESULT(acode));
800 	      TRACE("worm at %1m can be defended at %1m with code %d\n",
801 		    str, attack_point, REVERSE_RESULT(acode));
802 	    }
803 	    popgo();
804 	  }
805       }
806     }
807   }
808   gg_assert(stackp == 0);
809 
810   /* 4. Use pattern matching to find a few more defense moves. */
811   find_defense_patterns();
812   gg_assert(stackp == 0);
813 
814   /*
815    * 5. Find additional attacks and defenses by testing all immediate
816    *    liberties. Further attacks and defenses are found by pattern
817    *    matching and by trying whether each attack or defense point
818    *    attacks or defends other strings.
819    */
820   for (str = BOARDMIN; str < BOARDMAX; str++) {
821     color = board[str];
822     if (!IS_STONE(color) || !is_worm_origin(str, str))
823       continue;
824 
825     other = OTHER_COLOR(color);
826 
827     if (worm[str].attack_codes[0] == 0)
828       continue;
829 
830     /* There is at least one attack on this group. Try the
831      * liberties.
832      */
833     liberties = findlib(str, MAXLIBS, libs);
834 
835     for (k = 0; k < liberties; k++) {
836       int pos = libs[k];
837       if (!attack_move_known(pos, str)) {
838 	/* Try to attack on the liberty. Don't consider
839 	 * send-two-return-one moves.
840 	 */
841 	if (!send_two_return_one(pos, other)
842 	    && trymove(pos, other, "make_worms", str)) {
843 	  if (board[str] == EMPTY || attack(str, NULL)) {
844 	    if (board[str] == EMPTY)
845 	      dcode = 0;
846 	    else
847 	      dcode = find_defense(str, NULL);
848 
849 	    if (dcode != WIN)
850 	      change_attack(str, pos, REVERSE_RESULT(dcode));
851 	  }
852 	  popgo();
853 	}
854       }
855       /* Try to defend at the liberty. */
856       if (!defense_move_known(pos, str)) {
857 	if (worm[str].defense_codes[0] != 0)
858 	  if (trymove(pos, color, "make_worms", NO_MOVE)) {
859 	    acode = attack(str, NULL);
860 	    if (acode != WIN)
861 	      change_defense(str, pos, REVERSE_RESULT(acode));
862 	    popgo();
863 	  }
864       }
865     }
866   }
867   gg_assert(stackp == 0);
868 }
869 
870 
871 /*
872  * Find moves threatening to attack or save all worms.
873  */
874 
875 static void
find_worm_threats()876 find_worm_threats()
877 {
878   int str;
879   static int libs[MAXLIBS];
880   int liberties;
881 
882   int k;
883   int l;
884   int color;
885 
886   for (str = BOARDMIN; str < BOARDMAX; str++) {
887     color = board[str];
888     if (!IS_STONE(color) || !is_worm_origin(str, str))
889       continue;
890 
891     /* 1. Start with finding attack threats. */
892     /* Only try those worms that have no attack. */
893     if (worm[str].attack_codes[0] == 0) {
894       attack_threats(str, MAX_TACTICAL_POINTS,
895 		     worm[str].attack_threat_points,
896 		     worm[str].attack_threat_codes);
897 #if 0
898       /* Threaten to attack by saving weak neighbors. */
899       num_adj = chainlinks(str, adjs);
900       for (k = 0; k < num_adj; k++) {
901 	if (worm[adjs[k]].attack_codes[0] != 0
902 	    && worm[adjs[k]].defense_codes[0] != 0)
903 	  for (r = 0; r < MAX_TACTICAL_POINTS; r++) {
904 	    int bb;
905 
906 	    if (worm[adjs[k]].defense_codes[r] == 0)
907 	      break;
908 	    bb = worm[adjs[k]].defense_points[r];
909 	    if (trymove(bb, other, "threaten attack", str,
910 			EMPTY, NO_MOVE)) {
911 	      int acode;
912 	      if (board[str] == EMPTY)
913 		acode = WIN;
914 	      else
915 		acode = attack(str, NULL);
916 	      if (acode != 0)
917 		change_attack_threat(str, bb, acode);
918 	      popgo();
919 	    }
920 	  }
921       }
922 #endif
923       /* FIXME: Try other moves also (patterns?). */
924     }
925 
926     /* 2. Continue with finding defense threats. */
927     /* Only try those worms that have an attack. */
928     if (worm[str].attack_codes[0] != 0
929 	&& worm[str].defense_codes[0] == 0) {
930 
931       liberties = findlib(str, MAXLIBS, libs);
932 
933       for (k = 0; k < liberties; k++) {
934 	int aa = libs[k];
935 
936 	/* Try to threaten on the liberty. */
937 	if (trymove(aa, color, "threaten defense", NO_MOVE)) {
938 	  if (attack(str, NULL) == WIN) {
939 	    int dcode = find_defense(str, NULL);
940 	    if (dcode != 0)
941 	      change_defense_threat(str, aa, dcode);
942 	  }
943 	  popgo();
944 	}
945 
946 	/* Try to threaten on second order liberties. */
947 	for (l = 0; l < 4; l++) {
948 	  int bb = libs[k] + delta[l];
949 
950 	  if (!ON_BOARD(bb)
951 	      || IS_STONE(board[bb])
952 	      || liberty_of_string(bb, str))
953 	    continue;
954 
955 	  if (trymove(bb, color, "threaten defense", str)) {
956 	    if (attack(str, NULL) == WIN) {
957 	      int dcode = find_defense(str, NULL);
958 	      if (dcode != 0)
959 		change_defense_threat(str, bb, dcode);
960 	    }
961 	    popgo();
962 	  }
963 	}
964       }
965 
966       /* It might be interesting to look for defense threats by
967        * attacking weak neighbors, similar to threatening attack by
968        * defending a weak neighbor. However, in this case it seems
969        * probable that if there is such an attack, it's a real
970        * defense, not only a threat.
971        */
972 
973       /* FIXME: Try other moves also (patterns?). */
974     }
975   }
976 }
977 
978 
979 /* find_lunch(str, &worm) looks for a worm adjoining the
980  * string at (str) which can be easily captured. Whether or not it can
981  * be defended doesn't matter.
982  *
983  * Returns the location of the string in (*lunch).
984  */
985 
986 static int
find_lunch(int str,int * lunch)987 find_lunch(int str, int *lunch)
988 {
989   int pos;
990   int k;
991 
992   ASSERT1(IS_STONE(board[str]), str);
993   ASSERT1(stackp == 0, str);
994 
995   *lunch = NO_MOVE;
996   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
997     if (board[pos] != OTHER_COLOR(board[str]))
998       continue;
999     for (k = 0; k < 8; k++) {
1000       int apos = pos + delta[k];
1001       if (ON_BOARD(apos) && is_same_worm(apos, str)) {
1002 	if (worm[pos].attack_codes[0] != 0 && !is_ko_point(pos)) {
1003 	  /*
1004 	   * If several adjacent lunches are found, we pick the
1005 	   * juiciest. First maximize cutstone, then minimize liberties.
1006 	   * We can only do this if the worm data is available,
1007 	   * i.e. if stackp==0.
1008 	   */
1009 	  if (*lunch == NO_MOVE
1010 	      || worm[pos].cutstone > worm[*lunch].cutstone
1011 	      || (worm[pos].cutstone == worm[*lunch].cutstone
1012 		  && worm[pos].liberties < worm[*lunch].liberties)) {
1013 	    *lunch = worm[pos].origin;
1014 	  }
1015 	}
1016 	break;
1017       }
1018     }
1019   }
1020 
1021   if (*lunch != NO_MOVE)
1022     return 1;
1023 
1024   return 0;
1025 }
1026 
1027 
1028 /*
1029  * Test whether two worms are the same. Used by autohelpers.
1030  * Before this function can be called, build_worms must have been run.
1031  */
1032 
1033 int
is_same_worm(int w1,int w2)1034 is_same_worm(int w1, int w2)
1035 {
1036   return worm[w1].origin == worm[w2].origin;
1037 }
1038 
1039 
1040 /*
1041  * Test whether the origin of the worm at (w) is (pos).
1042  */
1043 
1044 int
is_worm_origin(int w,int pos)1045 is_worm_origin(int w, int pos)
1046 {
1047   return worm[w].origin == pos;
1048 }
1049 
1050 
1051 /*
1052  * change_defense(str, move, dcode) is used to add and remove defense
1053  * points. It can also be used to change the defense code. The meaning
1054  * of the call is that the string (str) can be defended by (move) with
1055  * defense code (dcode). If (dcode) is zero, the move is removed from
1056  * the list of defense moves if it was previously listed.
1057  */
1058 
1059 void
change_defense(int str,int move,int dcode)1060 change_defense(int str, int move, int dcode)
1061 {
1062   str = worm[str].origin;
1063   change_tactical_point(str, move, dcode,
1064 			worm[str].defense_points, worm[str].defense_codes);
1065 }
1066 
1067 
1068 /*
1069  * change_attack(str, move, acode) is used to add and remove attack
1070  * points. It can also be used to change the attack code. The meaning
1071  * of the call is that the string (str) can be attacked by (move) with
1072  * attack code (acode). If (acode) is zero, the move is removed from
1073  * the list of attack moves if it was previously listed.
1074  */
1075 
1076 void
change_attack(int str,int move,int acode)1077 change_attack(int str, int move, int acode)
1078 {
1079   str = worm[str].origin;
1080   DEBUG(DEBUG_WORMS, "change_attack: %1m %1m %d\n", str, move, acode);
1081   change_tactical_point(str, move, acode,
1082 			worm[str].attack_points, worm[str].attack_codes);
1083 }
1084 
1085 
1086 /*
1087  * change_defense_threat(str, move, dcode) is used to add and remove
1088  * defense threat points. It can also be used to change the defense
1089  * threat code. The meaning of the call is that the string (str) can
1090  * threaten to be defended by (move) with defense threat code (dcode).
1091  * If (dcode) is zero, the move is removed from the list of defense
1092  * threat moves if it was previously listed.
1093  */
1094 
1095 void
change_defense_threat(int str,int move,int dcode)1096 change_defense_threat(int str, int move, int dcode)
1097 {
1098   str = worm[str].origin;
1099   change_tactical_point(str, move, dcode,
1100 			worm[str].defense_threat_points,
1101 			worm[str].defense_threat_codes);
1102 }
1103 
1104 
1105 /*
1106  * change_attack_threat(str, move, acode) is used to add and remove
1107  * attack threat points. It can also be used to change the attack
1108  * threat code. The meaning of the call is that the string (str) can
1109  * threaten to be attacked by (move) with attack threat code (acode).
1110  * If (acode) is zero, the move is removed from the list of attack
1111  * threat moves if it was previously listed.
1112  */
1113 
1114 void
change_attack_threat(int str,int move,int acode)1115 change_attack_threat(int str, int move, int acode)
1116 {
1117   str = worm[str].origin;
1118   change_tactical_point(str, move, acode,
1119 			worm[str].attack_threat_points,
1120 			worm[str].attack_threat_codes);
1121 }
1122 
1123 
1124 /* Check whether (move) is listed as an attack point for (str) and
1125  * return the attack code. If (move) is not listed, return 0.
1126  */
1127 int
attack_move_known(int move,int str)1128 attack_move_known(int move, int str)
1129 {
1130   return movelist_move_known(move, MAX_TACTICAL_POINTS,
1131 			     worm[str].attack_points,
1132 			     worm[str].attack_codes);
1133 }
1134 
1135 /* Check whether (move) is listed as a defense point for (str) and
1136  * return the defense code. If (move) is not listed, return 0.
1137  */
1138 int
defense_move_known(int move,int str)1139 defense_move_known(int move, int str)
1140 {
1141   return movelist_move_known(move, MAX_TACTICAL_POINTS,
1142 			     worm[str].defense_points,
1143 			     worm[str].defense_codes);
1144 }
1145 
1146 /* Check whether (move) is listed as an attack threat point for (str)
1147  * and return the attack threat code. If (move) is not listed, return
1148  * 0.
1149  */
1150 int
attack_threat_move_known(int move,int str)1151 attack_threat_move_known(int move, int str)
1152 {
1153   return movelist_move_known(move, MAX_TACTICAL_POINTS,
1154 			     worm[str].attack_threat_points,
1155 			     worm[str].attack_threat_codes);
1156 }
1157 
1158 /* Check whether (move) is listed as a defense threat point for (str)
1159  * and return the defense threat code. If (move) is not listed, return
1160  * 0.
1161  */
1162 int
defense_threat_move_known(int move,int str)1163 defense_threat_move_known(int move, int str)
1164 {
1165   return movelist_move_known(move, MAX_TACTICAL_POINTS,
1166 			     worm[str].defense_threat_points,
1167 			     worm[str].defense_threat_codes);
1168 }
1169 
1170 
1171 /*
1172  * This function does the real work for change_attack(),
1173  * change_defense(), change_attack_threat(), and
1174  * change_defense_threat().
1175  */
1176 
1177 static void
change_tactical_point(int str,int move,int code,int points[MAX_TACTICAL_POINTS],int codes[MAX_TACTICAL_POINTS])1178 change_tactical_point(int str, int move, int code,
1179 		      int points[MAX_TACTICAL_POINTS],
1180 		      int codes[MAX_TACTICAL_POINTS])
1181 {
1182   ASSERT_ON_BOARD1(str);
1183   ASSERT1(str == worm[str].origin, str);
1184 
1185   movelist_change_point(move, code, MAX_TACTICAL_POINTS, points, codes);
1186   propagate_worm2(str);
1187 }
1188 
1189 
1190 /*
1191  * propagate_worm() takes the worm data at one stone and copies it to
1192  * the remaining members of the worm.
1193  *
1194  * Even though we don't need to copy all the fields, it's probably
1195  * better to do a structure copy which should compile to a block copy.
1196  */
1197 
1198 void
propagate_worm(int pos)1199 propagate_worm(int pos)
1200 {
1201   int k;
1202   int num_stones;
1203   int stones[MAX_BOARD * MAX_BOARD];
1204   gg_assert(stackp == 0);
1205   ASSERT1(IS_STONE(board[pos]), pos);
1206 
1207   num_stones = findstones(pos, MAX_BOARD * MAX_BOARD, stones);
1208   for (k = 0; k < num_stones; k++)
1209     if (stones[k] != pos)
1210       worm[stones[k]] = worm[pos];
1211 }
1212 
1213 
1214 /*
1215  * propagate_worm2() is a relative to propagate_worm() which can be
1216  * used when stackp>0 but not for the initial construction of the
1217  * worms.
1218  */
1219 
1220 static void
propagate_worm2(int str)1221 propagate_worm2(int str)
1222 {
1223   int pos;
1224   ASSERT_ON_BOARD1(str);
1225   ASSERT1(IS_STONE(worm[str].color), str);
1226 
1227   for (pos = BOARDMIN; pos < BOARDMAX; pos++)
1228     if (board[pos] == board[str] && is_same_worm(pos, str)
1229 	&& pos != str)
1230       worm[pos] = worm[str];
1231 }
1232 
1233 
1234 /* Report all known attack, defense, attack threat, and defense threat
1235  * moves. But limit this to the moves which can be made by (color).
1236  */
1237 void
worm_reasons(int color)1238 worm_reasons(int color)
1239 {
1240   int pos;
1241   int k;
1242 
1243   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
1244     if (!ON_BOARD(pos) || board[pos] == EMPTY)
1245       continue;
1246 
1247     if (!is_worm_origin(pos, pos))
1248       continue;
1249 
1250     if (board[pos] == OTHER_COLOR(color)) {
1251       for (k = 0; k < MAX_TACTICAL_POINTS; k++) {
1252 	if (worm[pos].attack_codes[k] != 0)
1253 	  add_attack_move(worm[pos].attack_points[k], pos,
1254 			  worm[pos].attack_codes[k]);
1255 	if (worm[pos].attack_threat_codes[k] != 0)
1256 	  add_attack_threat_move(worm[pos].attack_threat_points[k], pos,
1257 				 worm[pos].attack_threat_codes[k]);
1258       }
1259     }
1260 
1261     if (board[pos] == color) {
1262       for (k = 0; k < MAX_TACTICAL_POINTS; k++) {
1263 	if (worm[pos].defense_codes[k] != 0)
1264 	  add_defense_move(worm[pos].defense_points[k], pos,
1265 			   worm[pos].defense_codes[k]);
1266 
1267 	if (worm[pos].defense_threat_codes[k] != 0)
1268 	  add_defense_threat_move(worm[pos].defense_threat_points[k], pos,
1269 				  worm[pos].defense_threat_codes[k]);
1270       }
1271     }
1272   }
1273 }
1274 
1275 
1276 /* ping_cave(str, *lib1, ...) is applied when (str) points to a string.
1277  * It computes the vector (*lib1, *lib2, *lib3, *lib4),
1278  * where *lib1 is the number of liberties of the string,
1279  * *lib2 is the number of second order liberties (empty vertices
1280  * at distance two) and so forth.
1281  *
1282  * The definition of liberties of order >1 is adapted to the problem
1283  * of detecting the shape of the surrounding cavity. In particular
1284  * we want to be able to see if a group is loosely surrounded.
1285  *
1286  * A liberty of order n is an empty space which may be connected
1287  * to the string by placing n stones of the same color on the board,
1288  * but no fewer. The path of connection may pass through an intervening group
1289  * of the same color. The stones placed at distance >1 may not touch a
1290  * group of the opposite color. At the edge, also diagonal neighbors
1291  * count as touching. The path may also not pass through a liberty at distance
1292  * 1 if that liberty is flanked by two stones of the opposing color. This
1293  * reflects the fact that the O stone is blocked from expansion to the
1294  * left by the two X stones in the following situation:
1295  *
1296  *          X.
1297  *          .O
1298  *          X.
1299  *
1300  * On the edge, one stone is sufficient to block expansion:
1301  *
1302  *          X.
1303  *          .O
1304  *          --
1305  */
1306 
1307 static void
ping_cave(int str,int * lib1,int * lib2,int * lib3,int * lib4)1308 ping_cave(int str, int *lib1, int *lib2, int *lib3, int *lib4)
1309 {
1310   int pos;
1311   int k;
1312   int libs[MAXLIBS];
1313   int mrc[BOARDMAX];
1314   int mse[BOARDMAX];
1315   int color = board[str];
1316   int other = OTHER_COLOR(color);
1317 
1318   memset(mse, 0, sizeof(mse));
1319 
1320   /* Find and mark the first order liberties. */
1321   *lib1 = findlib(str, MAXLIBS, libs);
1322   for (k = 0; k < *lib1; k++)
1323     mse[libs[k]] = 1;
1324 
1325   /* Reset mse at liberties which are flanked by two stones of the
1326    * opposite color, or one stone and the edge.
1327    */
1328 
1329   for (pos = BOARDMIN; pos < BOARDMAX; pos++)
1330     if (ON_BOARD(pos)
1331 	&& mse[pos]
1332 	&& (((      !ON_BOARD(SOUTH(pos)) || board[SOUTH(pos)] == other)
1333 	     && (   !ON_BOARD(NORTH(pos)) || board[NORTH(pos)] == other))
1334 	    || ((   !ON_BOARD(WEST(pos))  || board[WEST(pos)]  == other)
1335 		&& (!ON_BOARD(EAST(pos))  || board[EAST(pos)]  == other))))
1336       mse[pos] = 0;
1337 
1338   *lib2 = 0;
1339   memset(mrc, 0, sizeof(mrc));
1340   ping_recurse(str, lib2, mse, mrc, color);
1341 
1342   *lib3 = 0;
1343   memset(mrc, 0, sizeof(mrc));
1344   ping_recurse(str, lib3, mse, mrc, color);
1345 
1346   *lib4 = 0;
1347   memset(mrc, 0, sizeof(mrc));
1348   ping_recurse(str, lib4, mse, mrc, color);
1349 }
1350 
1351 
1352 /* recursive function called by ping_cave */
1353 
1354 static void
ping_recurse(int pos,int * counter,int mx[BOARDMAX],int mr[BOARDMAX],int color)1355 ping_recurse(int pos, int *counter,
1356 	     int mx[BOARDMAX], int mr[BOARDMAX],
1357 	     int color)
1358 {
1359   int k;
1360   mr[pos] = 1;
1361 
1362   for (k = 0; k < 4; k++) {
1363     int apos = pos + delta[k];
1364     if (board[apos] == EMPTY
1365 	&& mx[apos] == 0
1366 	&& mr[apos] == 0
1367 	&& !touching(apos, OTHER_COLOR(color))) {
1368       (*counter)++;
1369       mr[apos] = 1;
1370       mx[apos] = 1;
1371     }
1372   }
1373 
1374   if (!is_ko_point(pos)) {
1375     for (k = 0; k < 4; k++) {
1376       int apos = pos + delta[k];
1377       if (ON_BOARD(apos)
1378 	  && mr[apos] == 0
1379 	  && (mx[apos] == 1
1380 	      || board[apos] == color))
1381 	ping_recurse(apos, counter, mx, mr, color);
1382     }
1383   }
1384 }
1385 
1386 
1387 /* touching(pos, color) returns true if the vertex at (pos) is
1388  * touching any stone of (color).
1389  */
1390 
1391 static int
touching(int pos,int color)1392 touching(int pos, int color)
1393 {
1394   return (board[SOUTH(pos)] == color
1395 	  || board[WEST(pos)] == color
1396 	  || board[NORTH(pos)] == color
1397 	  || board[EAST(pos)] == color);
1398 }
1399 
1400 
1401 /* The GENUS of a string is the number of connected components of
1402  * its complement, minus one. It is an approximation to the number of
1403  * eyes of the string.
1404  */
1405 
1406 static int
genus(int str)1407 genus(int str)
1408 {
1409   int pos;
1410   int mg[BOARDMAX];
1411   int gen = -1;
1412 
1413   memset(mg, 0, sizeof(mg));
1414   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
1415     if (ON_BOARD(pos)
1416 	&& !mg[pos]
1417 	&& (board[pos] == EMPTY || !is_same_worm(pos, str))) {
1418       markcomponent(str, pos, mg);
1419       gen++;
1420     }
1421   }
1422 
1423   return gen;
1424 }
1425 
1426 
1427 /* This recursive function marks the component at (pos) of
1428  * the complement of the string with origin (str)
1429  */
1430 
1431 static void
markcomponent(int str,int pos,int mg[BOARDMAX])1432 markcomponent(int str, int pos, int mg[BOARDMAX])
1433 {
1434   int k;
1435   mg[pos] = 1;
1436   for (k = 0; k < 4; k++) {
1437     int apos = pos + delta[k];
1438     if (ON_BOARD(apos)
1439 	&& mg[apos] == 0
1440 	&& (board[apos] == EMPTY || !is_same_worm(apos, str)))
1441       markcomponent(str, apos, mg);
1442   }
1443 }
1444 
1445 
1446 /* examine_cavity(pos, *edge), if (pos) is EMPTY, examines the
1447  * cavity at (m, n) and returns its bordercolor,
1448  * which can be BLACK, WHITE or GRAY. The edge parameter is set to the
1449  * number of edge vertices in the cavity.
1450  *
1451  * If (pos) is nonempty, it returns the same result, imagining
1452  * that the string at (pos) is removed. The edge parameter is
1453  * set to the number of vertices where the cavity meets the
1454  * edge in a point outside the removed string.
1455  */
1456 
1457 static int
examine_cavity(int pos,int * edge)1458 examine_cavity(int pos, int *edge)
1459 {
1460   int border_color = EMPTY;
1461   int ml[BOARDMAX];
1462   int origin = NO_MOVE;
1463 
1464   ASSERT_ON_BOARD1(pos);
1465   gg_assert(edge != NULL);
1466 
1467   memset(ml, 0, sizeof(ml));
1468 
1469   *edge = 0;
1470 
1471   if (IS_STONE(board[pos]))
1472     origin = find_origin(pos);
1473 
1474   cavity_recurse(pos, ml, &border_color, edge, origin);
1475 
1476   if (border_color != EMPTY)
1477     return border_color;
1478 
1479   /* We should have returned now, unless the board is completely empty.
1480    * Verify that this is the case and then return GRAY.
1481    *
1482    * Notice that the board appears completely empty if there's only a
1483    * single string and pos points to it.
1484    */
1485   gg_assert(border_color == EMPTY
1486 	    && ((pos == NO_MOVE
1487 		 && stones_on_board(BLACK | WHITE) == 0)
1488 		|| (pos != NO_MOVE
1489 		    && stones_on_board(BLACK | WHITE) == countstones(pos))));
1490 
1491   return GRAY;
1492 }
1493 
1494 
1495 /* helper function for examine_cavity.
1496  * border_color contains information so far : transitions allowed are
1497  *   EMPTY       -> BLACK/WHITE
1498  *   BLACK/WHITE -> BLACK | WHITE
1499  *
1500  * mx[pos] is 1 if (pos) has already been visited.
1501  *
1502  * if (str) points to the origin of a string, it will be ignored.
1503  *
1504  * On (fully-unwound) exit
1505  *   *border_color should be BLACK, WHITE or BLACK | WHITE
1506  *   *edge is the count of edge pieces
1507  *
1508  * *border_color should be EMPTY if and only if the board
1509  * is completely empty or only contains the ignored string.
1510  */
1511 
1512 static void
cavity_recurse(int pos,int mx[BOARDMAX],int * border_color,int * edge,int str)1513 cavity_recurse(int pos, int mx[BOARDMAX],
1514 	       int *border_color, int *edge, int str)
1515 {
1516   int k;
1517   ASSERT1(mx[pos] == 0, pos);
1518 
1519   mx[pos] = 1;
1520 
1521   if (is_edge_vertex(pos) && board[pos] == EMPTY)
1522     (*edge)++;
1523 
1524   /* Loop over the four neighbors. */
1525   for (k = 0; k < 4; k++) {
1526     int apos = pos + delta[k];
1527     if (ON_BOARD(apos) && !mx[apos]) {
1528       int neighbor_empty = 0;
1529 
1530       if (board[apos] == EMPTY)
1531 	neighbor_empty = 1;
1532       else {
1533 	/* Count the neighbor as empty if it is part of the (ai, aj) string. */
1534 	if (str == find_origin(apos))
1535 	  neighbor_empty = 1;
1536 	else
1537 	  neighbor_empty = 0;
1538       }
1539 
1540       if (!neighbor_empty)
1541 	*border_color |= board[apos];
1542       else
1543 	cavity_recurse(apos, mx, border_color, edge, str);
1544     }
1545   }
1546 }
1547 
1548 
1549 /* Find attacking moves by pattern matching, for both colors. */
1550 static void
find_attack_patterns(void)1551 find_attack_patterns(void)
1552 {
1553   matchpat(attack_callback, ANCHOR_OTHER, &attpat_db, NULL, NULL);
1554 }
1555 
1556 /* Try to attack every X string in the pattern, whether there is an attack
1557  * before or not. Only exclude already known attacking moves.
1558  */
1559 static void
attack_callback(int anchor,int color,struct pattern * pattern,int ll,void * data)1560 attack_callback(int anchor, int color, struct pattern *pattern, int ll,
1561 		void *data)
1562 {
1563   int move;
1564   int k;
1565   UNUSED(data);
1566 
1567   move = AFFINE_TRANSFORM(pattern->move_offset, ll, anchor);
1568 
1569   /* If the pattern has a constraint, call the autohelper to see
1570    * if the pattern must be rejected.
1571    */
1572   if (pattern->autohelper_flag & HAVE_CONSTRAINT) {
1573     if (!pattern->autohelper(ll, move, color, 0))
1574       return;
1575   }
1576 
1577   /* If the pattern has a helper, call it to see if the pattern must
1578    * be rejected.
1579    */
1580   if (pattern->helper) {
1581     if (!pattern->helper(pattern, ll, move, color)) {
1582       DEBUG(DEBUG_WORMS,
1583 	    "Attack pattern %s+%d rejected by helper at %1m\n",
1584 	    pattern->name, ll, move);
1585       return;
1586     }
1587   }
1588 
1589   /* Loop through pattern elements in search of X strings to attack. */
1590   for (k = 0; k < pattern->patlen; ++k) { /* match each point */
1591     if (pattern->patn[k].att == ATT_X) {
1592       /* transform pattern real coordinate */
1593       int pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor);
1594 
1595       int str = worm[pos].origin;
1596 
1597       /* A string with 5 liberties or more is considered tactically alive. */
1598       if (countlib(str) > 4)
1599 	continue;
1600 
1601       if (attack_move_known(move, str))
1602 	continue;
1603 
1604       /* No defenses are known at this time, so defend_code is always 0. */
1605 #if 0
1606       /* If the string can be attacked but not defended, ignore it. */
1607       if (worm[str].attack_codes[0] == WIN && worm[str].defense_codes[0] == 0)
1608 	continue;
1609 #endif
1610 
1611       /* FIXME: Don't attack the same string more than once.
1612        * Play (move) and see if there is a defense.
1613        */
1614       if (trymove(move, color, "attack_callback", str)) {
1615 	int dcode;
1616 	if (!board[str])
1617 	  dcode = 0;
1618 	else if (!attack(str, NULL))
1619 	  dcode = WIN;
1620 	else
1621 	  dcode = find_defense(str, NULL);
1622 
1623 	popgo();
1624 
1625 	/* Do not pick up suboptimal attacks at this time. Since we
1626          * don't know whether the string can be defended it's quite
1627          * possible that it only has a ko defense and then we would
1628          * risk to find an irrelevant move to attack with ko.
1629 	 */
1630 	if (dcode != WIN && REVERSE_RESULT(dcode) >= worm[str].attack_codes[0]) {
1631 	  change_attack(str, move, REVERSE_RESULT(dcode));
1632 	  DEBUG(DEBUG_WORMS,
1633 		"Attack pattern %s+%d found attack on %1m at %1m with code %d\n",
1634 		pattern->name, ll, str, move, REVERSE_RESULT(dcode));
1635 	}
1636       }
1637     }
1638   }
1639 }
1640 
1641 static void
find_defense_patterns(void)1642 find_defense_patterns(void)
1643 {
1644   matchpat(defense_callback, ANCHOR_COLOR, &defpat_db, NULL, NULL);
1645 }
1646 
1647 static void
defense_callback(int anchor,int color,struct pattern * pattern,int ll,void * data)1648 defense_callback(int anchor, int color, struct pattern *pattern, int ll,
1649 		 void *data)
1650 {
1651   int move;
1652   int k;
1653   UNUSED(data);
1654 
1655   move = AFFINE_TRANSFORM(pattern->move_offset, ll, anchor);
1656 
1657   /* If the pattern has a constraint, call the autohelper to see
1658    * if the pattern must be rejected.
1659    */
1660   if (pattern->autohelper_flag & HAVE_CONSTRAINT) {
1661     if (!pattern->autohelper(ll, move, color, 0))
1662       return;
1663   }
1664 
1665   /* If the pattern has a helper, call it to see if the pattern must
1666    * be rejected.
1667    */
1668   if (pattern->helper) {
1669     if (!pattern->helper(pattern, ll, move, color)) {
1670       DEBUG(DEBUG_WORMS,
1671 	    "Defense pattern %s+%d rejected by helper at %1m\n",
1672 	    pattern->name, ll, move);
1673       return;
1674     }
1675   }
1676 
1677   /* Loop through pattern elements in search for O strings to defend. */
1678   for (k = 0; k < pattern->patlen; ++k) { /* match each point */
1679     if (pattern->patn[k].att == ATT_O) {
1680       /* transform pattern real coordinate */
1681       int pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor);
1682       int str = worm[pos].origin;
1683 
1684       if (worm[str].attack_codes[0] == 0
1685 	  || defense_move_known(move, str))
1686 	continue;
1687 
1688       /* FIXME: Don't try to defend the same string more than once.
1689        * FIXME: For all attacks on this string, we should test whether
1690        *        the proposed move happens to refute the attack.
1691        * Play (move) and see if there is an attack.
1692        */
1693       if (trymove(move, color, "defense_callback", str)) {
1694 	int acode = attack(str, NULL);
1695 
1696 	popgo();
1697 
1698 	if (acode < worm[str].attack_codes[0]) {
1699 	  change_defense(str, move, REVERSE_RESULT(acode));
1700 	  DEBUG(DEBUG_WORMS,
1701 		"Defense pattern %s+%d found defense of %1m at %1m with code %d\n",
1702 		pattern->name, ll, str, move, REVERSE_RESULT(acode));
1703 	}
1704       }
1705     }
1706   }
1707 }
1708 
1709 
1710 void
get_lively_stones(int color,signed char safe_stones[BOARDMAX])1711 get_lively_stones(int color, signed char safe_stones[BOARDMAX])
1712 {
1713   int pos;
1714   memset(safe_stones, 0, BOARDMAX * sizeof(*safe_stones));
1715   for (pos = BOARDMIN; pos < BOARDMAX; pos++)
1716     if (IS_STONE(board[pos]) && find_origin(pos) == pos) {
1717       if ((stackp == 0 && worm[pos].attack_codes[0] == 0) || !attack(pos, NULL)
1718 	  || (board[pos] == color
1719 	      && ((stackp == 0 && worm[pos].defense_codes[0] != 0)
1720 		  || find_defense(pos, NULL))))
1721 	mark_string(pos, safe_stones, 1);
1722     }
1723 }
1724 
1725 
1726 void
compute_worm_influence()1727 compute_worm_influence()
1728 {
1729   signed char safe_stones[BOARDMAX];
1730 
1731   get_lively_stones(BLACK, safe_stones);
1732   compute_influence(BLACK, safe_stones, NULL, &initial_black_influence,
1733       		    NO_MOVE, "initial black influence");
1734   get_lively_stones(WHITE, safe_stones);
1735   compute_influence(WHITE, safe_stones, NULL, &initial_white_influence,
1736       		    NO_MOVE, "initial white influence");
1737 }
1738 
1739 /* ================================================================ */
1740 /*                      Debugger functions                          */
1741 /* ================================================================ */
1742 
1743 /* For use in gdb, print details of the worm at (m, n).
1744  * Add this to your .gdbinit file:
1745  *
1746  * define worm
1747  * set ascii_report_worm("$arg0")
1748  * end
1749  *
1750  * Now 'worm S8' will report the details of the S8 worm.
1751  *
1752  */
1753 
1754 void
ascii_report_worm(char * string)1755 ascii_report_worm(char *string)
1756 {
1757   int pos = string_to_location(board_size, string);
1758   report_worm(pos);
1759 }
1760 
1761 
1762 static void
report_worm(int pos)1763 report_worm(int pos)
1764 {
1765   int i;
1766 
1767   if (board[pos] == EMPTY) {
1768     gprintf("There is no worm at %1m\n", pos);
1769     return;
1770   }
1771 
1772   gprintf("*** worm at %1m:\n", pos);
1773   gprintf("color: %s; origin: %1m; size: %d; effective size: %f\n",
1774 	  (worm[pos].color == WHITE) ? "White" : "Black",
1775 	  worm[pos].origin, worm[pos].size, worm[pos].effective_size);
1776 
1777   gprintf("liberties: %d order 2 liberties:%d order 3:%d order 4:%d\n",
1778 	  worm[pos].liberties,
1779 	  worm[pos].liberties2,
1780 	  worm[pos].liberties3,
1781 	  worm[pos].liberties4);
1782 
1783   /* List all attack points. */
1784   if (worm[pos].attack_points[0] == NO_MOVE)
1785     gprintf("no attack point, ");
1786   else {
1787     gprintf("attack point(s):");
1788     i = 0;
1789     while (worm[pos].attack_points[i] != NO_MOVE) {
1790       if (i > 0)
1791 	gprintf(",");
1792       gprintf(" %1m: %s", worm[pos].attack_points[i],
1793 	      result_to_string(worm[pos].attack_codes[i]));
1794       i++;
1795     }
1796     gprintf("\n;");
1797   }
1798 
1799   /* List all defense points. */
1800   if (worm[pos].defense_points[0] == NO_MOVE)
1801     gprintf("no defense point, ");
1802   else {
1803     gprintf("defense point(s):");
1804     i = 0;
1805     while (worm[pos].defense_points[i] != NO_MOVE) {
1806       if (i > 0)
1807 	gprintf(",");
1808       gprintf(" %1m: %s", worm[pos].defense_points[i],
1809 	      result_to_string(worm[pos].defense_codes[i]));
1810       i++;
1811     }
1812     gprintf("\n;");
1813   }
1814 
1815   /* List all attack threat points. */
1816   if (worm[pos].attack_threat_points[0] == NO_MOVE)
1817     gprintf("no attack threat point, ");
1818   else {
1819     gprintf("attack threat point(s):");
1820     i = 0;
1821     while (worm[pos].attack_threat_points[i] != NO_MOVE) {
1822       if (i > 0)
1823 	gprintf(",");
1824       gprintf(" %1m: %s", worm[pos].attack_threat_points[i],
1825 	      result_to_string(worm[pos].attack_threat_codes[i]));
1826       i++;
1827     }
1828     gprintf("\n;");
1829   }
1830 
1831   /* List all defense threat points. */
1832   if (worm[pos].defense_threat_points[0] == NO_MOVE)
1833     gprintf("no defense threat point, ");
1834   else {
1835     gprintf("defense threat point(s):");
1836     i = 0;
1837     while (worm[pos].defense_threat_points[i] != NO_MOVE) {
1838       if (i > 0)
1839 	gprintf(",");
1840       gprintf(" %1m: %s", worm[pos].defense_threat_points[i],
1841 	      result_to_string(worm[pos].defense_threat_codes[i]));
1842       i++;
1843     }
1844     gprintf("\n;");
1845   }
1846 
1847   /* Report lunch if any. */
1848   if (worm[pos].lunch != NO_MOVE)
1849     gprintf("lunch at %1m\n", worm[pos].lunch);
1850 
1851   gprintf("cutstone: %d, cutstone2: %d\n",
1852 	  worm[pos].cutstone, worm[pos].cutstone2);
1853 
1854   gprintf("genus: %d, ", worm[pos].genus);
1855 
1856   if (worm[pos].inessential)
1857     gprintf("inessential: YES, ");
1858   else
1859     gprintf("inessential: NO, ");
1860 
1861   if (worm[pos].invincible)
1862     gprintf("invincible: YES, \n");
1863   else
1864     gprintf("invincible: NO, \n");
1865 
1866   gprintf("unconditional status %s\n",
1867 	  status_to_string(worm[pos].unconditional_status));
1868 }
1869 
1870 
1871 /*
1872  * Local Variables:
1873  * tab-width: 8
1874  * c-basic-offset: 2
1875  * End:
1876  */
1877