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 <string.h>
28 #include <stdlib.h>
29
30 #include "liberty.h"
31
32 /* Unconditionally meaningless moves. */
33 int meaningless_black_moves[BOARDMAX];
34 int meaningless_white_moves[BOARDMAX];
35
36 /* Capture as many strings of the given color as we can. Played stones
37 * are left on the board and the number of played stones is returned.
38 * Strings marked in the exceptions array are excluded from capturing
39 * attempts. If all non-excepted strings are successfully captured,
40 * *none_invincible is set to one. Set none_invincible to NULL if you
41 * don't need that information.
42 */
43 static int
capture_non_invincible_strings(int color,int exceptions[BOARDMAX],int * none_invincible)44 capture_non_invincible_strings(int color, int exceptions[BOARDMAX],
45 int *none_invincible)
46 {
47 int other = OTHER_COLOR(color);
48 int something_captured = 1; /* To get into the first turn of the loop. */
49 int string_found = 0;
50 int moves_played = 0;
51 int save_moves;
52 int libs[MAXLIBS];
53 int liberties;
54 int pos;
55 int k;
56
57 while (something_captured) {
58 /* Nothing captured so far in this turn of the loop. */
59 something_captured = 0;
60
61 /* Is there something left to try to capture? */
62 string_found = 0;
63
64 /* Visit all friendly strings on the board. */
65 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
66 if (board[pos] != color || find_origin(pos) != pos)
67 continue;
68
69 if (exceptions && exceptions[pos])
70 continue;
71
72 string_found = 1;
73
74 /* Try to capture the string at pos. */
75 liberties = findlib(pos, MAXLIBS, libs);
76 save_moves = moves_played;
77 for (k = 0; k < liberties; k++) {
78 if (trymove(libs[k], other, "unconditional_life", pos))
79 moves_played++;
80 }
81
82 /* Successful if already captured or a single liberty remains.
83 * Otherwise we must rewind and take back the last batch of moves.
84 */
85 if (board[pos] == EMPTY)
86 something_captured = 1;
87 else if (findlib(pos, 2, libs) == 1) {
88 /* Need to use tryko as a defense against the extreme case
89 * when the only opponent liberty that is not suicide is an
90 * illegal ko capture, like in this 5x5 position:
91 * +-----+
92 * |.XO.O|
93 * |XXOO.|
94 * |X.XOO|
95 * |XXOO.|
96 * |.XO.O|
97 * +-----+
98 */
99 int success = tryko(libs[0], other, "unconditional_life");
100 gg_assert(success);
101 moves_played++;
102 something_captured = 1;
103 }
104 else
105 while (moves_played > save_moves) {
106 popgo();
107 moves_played--;
108 }
109 }
110 }
111
112 if (none_invincible)
113 *none_invincible = !string_found;
114
115 return moves_played;
116 }
117
118 /* Find those worms of the given color that can never be captured,
119 * even if the opponent is allowed an arbitrary number of consecutive
120 * moves. The coordinates of the origins of these worms are written to
121 * the worm arrays and the number of non-capturable worms is
122 * returned.
123 *
124 * The algorithm is to cycle through the worms until none remains or
125 * no more can be captured. A worm is removed when it is found to be
126 * capturable, by letting the opponent try to play on all its
127 * liberties. If the attack fails, the moves are undone. When no more
128 * worm can be removed in this way, the remaining ones are
129 * unconditionally alive.
130 *
131 * After this, unconditionally dead opponent worms and unconditional
132 * territory are identified. This is almost, but only almost,
133 * straightforward. We first present a simple but only almost correct
134 * solution, then show how to patch up its deficiencies.
135 *
136 * - - - - - - -
137 *
138 * Algorithm 1, simple but slightly incorrect.
139 *
140 * To find unconditionally dead opponent worms and unconditional
141 * territory, we continue from the position obtained at the end of the
142 * previous operation (only unconditionally alive strings remain for
143 * color) with the following steps:
144 *
145 * 1. Play opponent stones on all liberties of the unconditionally
146 * alive strings except where illegal. (That the move order may
147 * determine exactly which liberties can be played legally is not
148 * important. Just pick an arbitrary order).
149 * 2. Recursively extend opponent strings in atari, except where this
150 * would be suicide.
151 * 3. Play an opponent stone anywhere it can get two empty
152 * neighbors. (I.e. split big eyes into small ones).
153 * 4. Play an opponent stone anywhere it can get one empty
154 * neighbor. (I.e. reduce two space eyes to one space eyes.)
155 *
156 * Remaining opponent strings in atari and remaining liberties of the
157 * unconditionally alive strings constitute the unconditional
158 * territory.
159 *
160 * Opponent strings from the initial position placed on
161 * unconditional territory are unconditionally dead.
162 *
163 * - - - - - - -
164 *
165 * The deficiency with this algorithm is that a certain class of sekis
166 * are considered as dead, e.g. this position:
167 *
168 * .OOOOO.
169 * OOXXXOO
170 * OXX.XXO
171 * OX.O.XO
172 * OX.O.XO
173 * OXX.XXO
174 * OOXXXOO
175 * .OOOOO.
176 *
177 * The problem is that while removing the two O stones, X is reduced
178 * to a single small eye. Still O cannot capture these stones under
179 * alternating play since the eyespace is too big.
180 *
181 * Before discussing this seki further we make a preliminary
182 * modification of the algorithm.
183 *
184 * - - - - - - -
185 *
186 * Algorithm 2. More complex but still slightly incorrect algorithm:
187 *
188 * 1. Run algorithm 1.
189 * 2. Return to the original position.
190 * 3. Capture all capturable O strings which according to algorithm 1
191 * do not belong to unconditional territory.
192 * 4. Play opponent stones on all liberties of the unconditionally
193 * alive strings except where illegal. (That the move order may
194 * determine exactly which liberties can be played legally is not
195 * important. Just pick an arbitrary order).
196 * 5. Recursively extend opponent strings in atari, except where this
197 * would be suicide.
198 * 6. Capture all remaining capturable O strings.
199 * 7. Repeat 4 and 5 once.
200 * 8. Play an opponent stone anywhere it can get two empty
201 * neighbors. (I.e. split big eyes into small ones).
202 * 9. Play an opponent stone anywhere it can get one empty
203 * neighbor. (I.e. reduce two space eyes to one space eyes.)
204 *
205 * Remaining opponent strings in atari and remaining liberties of the
206 * unconditionally alive strings constitute the unconditional
207 * territory.
208 *
209 * Opponent strings from the initial position placed on
210 * unconditional territory are unconditionally dead.
211 *
212 * - - - - - - -
213 *
214 * We can observe that, after step 5, an X group with at least two
215 * distinct eyespaces would not risk being reduced to a single small
216 * eye. Similarly an X group with a capturable O string of size at
217 * least three would allow the formation of two distinct small eyes
218 * after being captured. Thus it is easy to see that the only X groups
219 * which would live in seki but could not be transformed into
220 * unconditionally alive groups would have a single eyespace with a
221 * capturable O string of size at most 2. Furthermore the eyespace
222 * would not be possible to subdivide. Then if the capturable string
223 * would be of size 1 it would in all cases form a nakade and we would
224 * not have a seki. The plausible seki positions would all be
225 * reducable to the following eyeshape:
226 *
227 * .OOOOO.
228 * OOXXXO.
229 * OXX.XOO
230 * OX.OXXO
231 * OXXO.XO
232 * OOX.XXO
233 * .OXXXOO
234 * .OOOOO.
235 *
236 * The remaining question is what effects cutting points in the X
237 * group would have. For example these X groups are dead:
238 *
239 * .OOOOO. .OOOOO. .OOOOO. .OOOOO. ..OOOO. ..OOOO.
240 * .OXXXO. .OXXXO. .OXXXO. .OXXXO. OOOXXO. OOOXXO.
241 * OOX.XO. OOX.XOO OOX.XOO OOX.XOO OXX.XO. OXX.XOO
242 * OX.OXOO OX.OXXO OX.OXXO OX.OXXO OX.OXOO OX.OXXO
243 * OXXO.XO OXXO.XO OXXO.XO OXXO.XO OXXO.XO OXXO.XO
244 * OOX.XXO OOX.XOO OOX.XXO OOX.XXO OOX.XXO OOX.XXO
245 * .OXXXOO .OXXXO. .OXXOOO .OOXXOO .OXXXOO .OXXOOO
246 * .OOOOO. .OOOOO. .OOOO.. ..OOOO. .OOOOO. .OOOO..
247 *
248 * while these are alive in seki
249 *
250 * ..OOOO. .OOOO.. .OOOO.. ..OOOO. ..OOOO.
251 * OOOXXO. .OXXOO. OOXXOO. .OOXXO. OOOXXO.
252 * OXX.XOO OOX.XOO OXX.XOO OOX.XOO OXX.XOO
253 * OX.OXXO OX.OXXO OX.OXXO OX.OXXO OX.OXXO
254 * OXXO.XO OXXO.XO OOXO.XO OXXO.XO OOXO.XO
255 * OOX.XXO OOX.XXO .OX.XXO OOX.XXO .OX.XXO
256 * .OXXXOO .OXXXOO .OXXOOO .OXXXOO .OXXXOO
257 * .OOOOO. .OOOOO. .OOOO.. ..OOOO. .OOOOO.
258 *
259 * The critical distinction between the dead ones and the seki ones is
260 * that the stones marked a and b below,
261 *
262 * .OOOOO.
263 * OOXXXO.
264 * OXX.XOO
265 * OX.ObXO
266 * OXaO.XO
267 * OOX.XXO
268 * .OXXXOO
269 * .OOOOO.
270 *
271 * belong to different strings for the dead groups and to the same
272 * string for the seki groups.
273 *
274 * The trick to avoid misclassifying areas where the opponent can form
275 * a seki group but not an invincible group as unconditional territory
276 * is thus to detect the formation above and add a third stone to the
277 * O group before the capturing in step 6 above.
278 *
279 * This leads to the final algorithm.
280 *
281 * - - - - - - -
282 *
283 * Algorithm 3. Final and correct algorithm:
284 *
285 * 1. Run algorithm 1.
286 * 2. Return to the original position.
287 * 3. Capture all capturable O strings which according to algorithm 1
288 * do not belong to unconditional territory.
289 * 4. Play opponent stones on all liberties of the unconditionally
290 * alive strings except where illegal. (That the move order may
291 * determine exactly which liberties can be played legally is not
292 * important. Just pick an arbitrary order).
293 * 5. Recursively extend opponent strings in atari, except where this
294 * would be suicide.
295 * 6. Identify eyespaces of the kind described above and extend any
296 * matching two-stone string with a third stone.
297 * 7. Capture all remaining capturable O strings.
298 * 8. Repeat 4 and 5 once.
299 * 9. Play an opponent stone anywhere it can get two empty
300 * neighbors. (I.e. split big eyes into small ones).
301 * 10. Play an opponent stone anywhere it can get one empty
302 * neighbor. (I.e. reduce two space eyes to one space eyes.)
303 *
304 * Remaining opponent strings in atari and remaining liberties of the
305 * unconditionally alive strings constitute the unconditional
306 * territory.
307 *
308 * Opponent strings from the initial position placed on
309 * unconditional territory are unconditionally dead.
310 *
311 * - - - - - - -
312 *
313 * On return, unconditional_territory[][] is 1 where color has
314 * unconditionally alive stones, 2 where it has unconditional
315 * territory, and 0 otherwise.
316 */
317
318 void
unconditional_life(int unconditional_territory[BOARDMAX],int color)319 unconditional_life(int unconditional_territory[BOARDMAX], int color)
320 {
321 int found_one;
322 int other = OTHER_COLOR(color);
323 int libs[MAXLIBS];
324 int liberties;
325 int pos;
326 int k, r;
327 int moves_played;
328 int potential_sekis[BOARDMAX];
329 int none_invincible;
330
331 /* Initialize unconditional_territory array. */
332 memset(unconditional_territory, 0,
333 sizeof(unconditional_territory[0]) * BOARDMAX);
334
335 /* Find isolated two-stone strings which might be involved in the
336 * kind of seki described in the comments.
337 */
338 memset(potential_sekis, 0, sizeof(potential_sekis));
339 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
340 int isolated = 1;
341 int stones[2];
342 int pos2;
343
344 if (board[pos] != color
345 || find_origin(pos) != pos
346 || countstones(pos) != 2)
347 continue;
348
349 findstones(pos, 2, stones);
350 for (k = 0; k < 2 && isolated; k++) {
351 for (r = 0; r < 8 && isolated; r++) {
352 pos2 = stones[k] + delta[r];
353 if (!ON_BOARD(pos2)
354 || (board[pos2] == color
355 && !same_string(pos, pos2)))
356 isolated = 0;
357 }
358 }
359
360 if (isolated) {
361 potential_sekis[stones[0]] = 1;
362 potential_sekis[stones[1]] = 1;
363 }
364 }
365
366 moves_played = capture_non_invincible_strings(color, potential_sekis,
367 &none_invincible);
368
369 /* If there are no invincible strings, nothing can be unconditionally
370 * settled.
371 */
372 if (none_invincible) {
373 /* Take back all moves. */
374 while (moves_played > 0) {
375 popgo();
376 moves_played--;
377 }
378 return;
379 }
380
381 /* The strings still remaining except those marked in
382 * potential_sekis[] are uncapturable. Now see which opponent
383 * strings can survive.
384 *
385 * 1. Play opponent stones on all liberties of the unconditionally
386 * alive strings except where illegal.
387 */
388 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
389 if (board[pos] != color || potential_sekis[pos] || find_origin(pos) != pos)
390 continue;
391
392 /* Play as many liberties as we can. */
393 liberties = findlib(pos, MAXLIBS, libs);
394 for (k = 0; k < liberties; k++) {
395 if (trymove(libs[k], other, "unconditional_life", pos))
396 moves_played++;
397 }
398 }
399
400 /* 2. Recursively extend opponent strings in atari, except where this
401 * would be suicide.
402 */
403 found_one = 1;
404 while (found_one) {
405 /* Nothing found so far in this turn of the loop. */
406 found_one = 0;
407
408 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
409 if (board[pos] != other || countlib(pos) > 1)
410 continue;
411
412 /* Try to extend the string at (m, n). */
413 findlib(pos, 1, libs);
414 if (trymove(libs[0], other, "unconditional_life", pos)) {
415 moves_played++;
416 found_one = 1;
417 }
418 }
419 }
420
421 /* Now see whether there are any significant sekis on the board. */
422 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
423 if (!potential_sekis[pos]
424 || board[pos] == EMPTY
425 || find_origin(pos) != pos)
426 continue;
427 for (r = 0; r < 4; r++) {
428 int up = delta[r];
429 int right = delta[(r + 1) % 4];
430 int locally_played_moves = 0;
431 if (board[pos + up] != color
432 || board[pos + up + up] != EMPTY
433 || board[pos - up] != EMPTY)
434 continue;
435 for (k = 0; k < 2; k++) {
436 if (k == 1)
437 right = -right;
438 if (board[pos + right] != EMPTY || board[pos + up - right] != EMPTY)
439 continue;
440 if (board[pos - right] == EMPTY
441 && trymove(pos - right, other, "unconditional_life", pos))
442 locally_played_moves++;
443 if (board[pos + up + right] == EMPTY
444 && trymove(pos + up + right, other, "unconditional_life", pos))
445 locally_played_moves++;
446 if (board[pos - right] == other && board[pos + up + right] == other
447 && same_string(pos - right, pos + up + right)) {
448 /* This is a critical seki. Extend the string with one stone
449 * in an arbitrary direction to break the seki.
450 */
451 while (locally_played_moves > 0) {
452 popgo();
453 locally_played_moves--;
454 }
455 trymove(pos - up, color, "unconditional_life", pos);
456 moves_played++;
457 break;
458 }
459 else {
460 while (locally_played_moves > 0) {
461 popgo();
462 locally_played_moves--;
463 }
464 }
465 }
466 if (countstones(pos) > 2)
467 break;
468 }
469 }
470
471 /* Capture the strings involved in potential sekis. */
472 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
473 if (!potential_sekis[pos] || board[pos] == EMPTY)
474 continue;
475 /* Play as many liberties as we can. */
476 liberties = findlib(pos, MAXLIBS, libs);
477 for (k = 0; k < liberties; k++) {
478 if (trymove(libs[k], other, "unconditional_life", pos))
479 moves_played++;
480 }
481 }
482
483
484 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
485 int apos;
486 int bpos;
487 int aopen, bopen;
488 int alib, blib;
489 if (board[pos] != other || countlib(pos) != 2)
490 continue;
491 findlib(pos, 2, libs);
492 apos = libs[0];
493 bpos = libs[1];
494 if (abs(I(apos) - I(bpos)) + abs(J(apos) - J(bpos)) != 1)
495 continue;
496
497 /* Only two liberties and these are adjacent. Play one. We want
498 * to maximize the number of open liberties. In this particular
499 * situation we can count this with approxlib for the opposite
500 * color. If the number of open liberties is the same, we
501 * maximize the total number of obtained liberties.
502 * Two relevant positions:
503 *
504 * |XXX.
505 * |OOXX |XXXXXXX
506 * |O.OX |OOXOOOX
507 * |..OX |..OO.OX
508 * +---- +-------
509 */
510 aopen = approxlib(apos, color, 4, NULL);
511 bopen = approxlib(bpos, color, 4, NULL);
512 alib = approxlib(apos, other, 4, NULL);
513 blib = approxlib(bpos, other, 4, NULL);
514
515 if (aopen > bopen || (aopen == bopen && alib >= blib)) {
516 trymove(apos, other, "unconditional_life", pos);
517 moves_played++;
518 }
519 else {
520 trymove(bpos, other, "unconditional_life", pos);
521 moves_played++;
522 }
523 }
524
525 /* Identify unconditionally alive stones and unconditional territory. */
526 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
527 if (board[pos] == color && !potential_sekis[pos]) {
528 unconditional_territory[pos] = 1;
529 if (find_origin(pos) == pos) {
530 liberties = findlib(pos, MAXLIBS, libs);
531 for (k = 0; k < liberties; k++)
532 unconditional_territory[libs[k]] = 2;
533 }
534 }
535 else if (board[pos] == other && countlib(pos) == 1) {
536 unconditional_territory[pos] = 2;
537 findlib(pos, 1, libs);
538 unconditional_territory[libs[0]] = 2;
539 }
540 }
541
542 /* Take back all moves. */
543 while (moves_played > 0) {
544 popgo();
545 moves_played--;
546 }
547 }
548
549
550 /* By unconditional status analysis we can statically find some moves
551 * which there is never any need to play. Those belong to three
552 * different categories:
553 *
554 * 1. A move on a vertex which is already unconditional territory for
555 * either color.
556 * 2. A move which after having been made ends up as unconditional
557 * territory for the opponent.
558 * 3. If a move at vertex A makes vertex B become unconditional
559 * territory, there is no need to consider a move at B, since A has
560 * all the positive effects that B would have.
561 *
562 * Moves in categories 1 and 2 are never any better than passing and
563 * often worse (with territory scoring always worse). Moves in
564 * category three can be either better or worse than passing, but it's
565 * always true that a move at A is at least as good as a move at B.
566 * Occasionally they are identically good (A makes B unconditional
567 * territory and B makes A unconditional territory) but there is never
568 * any need to analyze both.
569 *
570 * In meaningless_black_moves[] and meaningless_white_moves[] a value
571 * of -1 means it is not meaningless, 0 (NO_MOVE) means it belongs to
572 * category 1 or 2, and a value greater than zero points to the
573 * preferred move in category 3.
574 *
575 * The parameter unconditional_territory should contain the result of
576 * calling unconditional_life() in the original position. Meaningless
577 * moves are computed for the given color.
578 */
579 void
find_unconditionally_meaningless_moves(int unconditional_territory[BOARDMAX],int color)580 find_unconditionally_meaningless_moves(int unconditional_territory[BOARDMAX],
581 int color)
582 {
583 int *meaningless_moves;
584 int other = OTHER_COLOR(color);
585 int friendly_unconditional[BOARDMAX];
586 int opponent_unconditional[BOARDMAX];
587 int pos;
588 int pos2;
589
590 gg_assert(color == BLACK || color == WHITE);
591
592 if (color == BLACK)
593 meaningless_moves = meaningless_black_moves;
594 else
595 meaningless_moves = meaningless_white_moves;
596
597 /* Initialize meaningless_moves and detect moves of category 1, but
598 * only for own unconditional territory.
599 *
600 * FIXME: We would save some time by detecting all category 1 moves
601 * here but then we would need to have the initial unconditional
602 * territory for the opponent as well. This can of course be done,
603 * the question is how we get it in the nicest way.
604 */
605 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
606 if (board[pos] == EMPTY) {
607 if (unconditional_territory[pos])
608 meaningless_moves[pos] = NO_MOVE;
609 else
610 meaningless_moves[pos] = -1;
611 }
612
613 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
614 if (board[pos] != EMPTY || meaningless_moves[pos] != -1)
615 continue;
616
617 if (!tryko(pos, color, "find_unconditionally_meaningless_moves"))
618 continue;
619
620 unconditional_life(opponent_unconditional, other);
621 if (opponent_unconditional[pos]) {
622 /* Move of category 1 or 2. */
623 meaningless_moves[pos] = NO_MOVE;
624 }
625 else {
626 unconditional_life(friendly_unconditional, color);
627 if (friendly_unconditional[pos])
628 for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++)
629 if (board[pos2] == EMPTY
630 && meaningless_moves[pos2] == -1
631 && friendly_unconditional[pos2]) {
632 /* Move of category 3. */
633 meaningless_moves[pos2] = pos;
634 }
635 }
636
637 popgo();
638 }
639
640 /* Meaningless moves of category 3 may have been found in multiple
641 * steps. Normalize to the final replacement move.
642 */
643 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
644 if (board[pos] == EMPTY && meaningless_moves[pos] > 0)
645 while (meaningless_moves[meaningless_moves[pos]] > 0)
646 meaningless_moves[pos] = meaningless_moves[meaningless_moves[pos]];
647 }
648
649 /* Returns 1 if the move at pos by color is meaningless and 0
650 * otherwise. When it is meaningless, *replacement_move will contain a
651 * replacing move, which is NO_MOVE if passing is guaranteed to be no
652 * worse than making the move.
653 */
654 int
unconditionally_meaningless_move(int pos,int color,int * replacement_move)655 unconditionally_meaningless_move(int pos, int color, int *replacement_move)
656 {
657 if (color == WHITE && meaningless_white_moves[pos] != -1) {
658 *replacement_move = meaningless_white_moves[pos];
659 return 1;
660 }
661 if (color == BLACK && meaningless_black_moves[pos] != -1) {
662 *replacement_move = meaningless_black_moves[pos];
663 return 1;
664 }
665
666 return 0;
667 }
668
669 void
clear_unconditionally_meaningless_moves()670 clear_unconditionally_meaningless_moves()
671 {
672 int pos;
673
674 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
675 if (ON_BOARD(pos)) {
676 meaningless_black_moves[pos] = -1;
677 meaningless_white_moves[pos] = -1;
678 }
679 }
680
681 /* Pick up antisuji and replacement move reasons found by analysis
682 * of unconditional status.
683 */
684 void
unconditional_move_reasons(int color)685 unconditional_move_reasons(int color)
686 {
687 int replacement_move;
688 int pos;
689
690 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
691 if (board[pos] == EMPTY
692 && unconditionally_meaningless_move(pos, color, &replacement_move)) {
693 if (replacement_move == NO_MOVE) {
694 TRACE("%1m unconditional antisuji.\n", pos);
695 add_antisuji_move(pos);
696 }
697 else {
698 TRACE("%1m unconditionally replaced to %1m.\n", pos, replacement_move);
699 add_replacement_move(pos, replacement_move, color);
700 }
701 }
702 }
703
704 /*
705 * Local Variables:
706 * tab-width: 8
707 * c-basic-offset: 2
708 * End:
709 */
710