Updated README: Equal sign not required with `--mode` flag.
[sgk-go] / engine / board.c
CommitLineData
7eeb782e
AT
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
25/* The functions in this file implements a go board with incremental
26 * update of strings and liberties.
27 *
28 * See the Texinfo documentation (Utility Functions: Incremental Board)
29 * for an introduction.
30 */
31
32#include "board.h"
33#include "hash.h"
34#include "sgftree.h"
35#include "gg_utils.h"
36
37#include <stdio.h>
38#include <string.h>
39#include <stdlib.h>
40#include <stdarg.h>
41
42
43/* This can be used for internal checks w/in board.c that should
44 * typically not be necessary (for speed).
45 */
46#if 1
47#define PARANOID1(x, pos) ASSERT1(x, pos)
48#else
49#define PARANOID1(x, pos)
50#endif
51
52
53/* ================================================================ */
54/* data structures */
55/* ================================================================ */
56
57
58/* Incremental string data. */
59struct string_data {
60 int color; /* Color of string, BLACK or WHITE */
61 int size; /* Number of stones in string. */
62 int origin; /* Coordinates of "origin", i.e. */
63 /* "upper left" stone. */
64 int liberties; /* Number of liberties. */
65 int neighbors; /* Number of neighbor strings */
66 int mark; /* General purpose mark. */
67};
68
69struct string_liberties_data {
70 int list[MAX_LIBERTIES]; /* Coordinates of liberties. */
71};
72
73struct string_neighbors_data {
74 int list[MAXCHAIN]; /* List of neighbor string numbers. */
75};
76
77/* we keep the address and the old value */
78struct change_stack_entry {
79 int *address;
80 int value;
81};
82
83/* we keep the address and the old value */
84struct vertex_stack_entry {
85 Intersection *address;
86 int value;
87};
88
89
90/* Experimental results show that the average number of change stack
91 * entries per move usually is in the 20-30 range and very seldom
92 * exceeds 40. But since we have no way to recover from running out of
93 * stack space, we allocate with a substantial safety margin.
94 */
95#define STACK_SIZE 80 * MAXSTACK
96
97
98#define CLEAR_STACKS() do { \
99 change_stack_pointer = change_stack; \
100 vertex_stack_pointer = vertex_stack; \
101 VALGRIND_MAKE_WRITABLE(change_stack, sizeof(change_stack)); \
102 VALGRIND_MAKE_WRITABLE(vertex_stack, sizeof(vertex_stack)); \
103} while (0)
104
105/* Begin a record : address == NULL */
106#define BEGIN_CHANGE_RECORD()\
107((change_stack_pointer++)->address = NULL,\
108 (vertex_stack_pointer++)->address = NULL)
109
110/* Save a value : store the address and the value in the stack */
111#define PUSH_VALUE(v)\
112(change_stack_pointer->address = &(v),\
113 (change_stack_pointer++)->value = (v))
114
115/* Save a board value : store the address and the value in the stack */
116#define PUSH_VERTEX(v)\
117(vertex_stack_pointer->address = &(v),\
118 (vertex_stack_pointer++)->value = (v))
119
120#define POP_MOVE()\
121 while ((--change_stack_pointer)->address)\
122 *(change_stack_pointer->address) =\
123 change_stack_pointer->value
124
125
126#define POP_VERTICES()\
127 while ((--vertex_stack_pointer)->address)\
128 *(vertex_stack_pointer->address) =\
129 vertex_stack_pointer->value
130
131
132/* ================================================================ */
133/* static data structures */
134/* ================================================================ */
135
136
137/* Main array of string information. */
138static struct string_data string[MAX_STRINGS];
139static struct string_liberties_data string_libs[MAX_STRINGS];
140static struct string_neighbors_data string_neighbors[MAX_STRINGS];
141
142/* Stacks and stack pointers. */
143static struct change_stack_entry change_stack[STACK_SIZE];
144static struct change_stack_entry *change_stack_pointer;
145
146static struct vertex_stack_entry vertex_stack[STACK_SIZE];
147static struct vertex_stack_entry *vertex_stack_pointer;
148
149
150/* Index into list of strings. The index is only valid if there is a
151 * stone at the vertex.
152 */
153static int string_number[BOARDMAX];
154
155
156/* The stones in a string are linked together in a cyclic list.
157 * These are the coordinates to the next stone in the string.
158 */
159static int next_stone[BOARDMAX];
160
161
162/* ---------------------------------------------------------------- */
163
164
165/* Macros to traverse the stones of a string.
166 *
167 * Usage:
168 * int s, pos;
169 * s = find_the_string()
170 * pos = FIRST_STONE(s);
171 * do {
172 * use_stone(pos);
173 * pos = NEXT_STONE(pos);
174 * } while (!BACK_TO_FIRST_STONE(s, pos));
175 */
176#define FIRST_STONE(s) \
177 (string[s].origin)
178
179#define NEXT_STONE(pos) \
180 (next_stone[pos])
181
182#define BACK_TO_FIRST_STONE(s, pos) \
183 ((pos) == string[s].origin)
184
185
186/* Assorted useful macros.
187 *
188 * Some of them could have been functions but are implemented as
189 * macros for speed.
190 */
191
192#define LIBERTY(pos) \
193 (board[pos] == EMPTY)
194
195#define UNMARKED_LIBERTY(pos) \
196 (board[pos] == EMPTY && ml[pos] != liberty_mark)
197
198#define MARK_LIBERTY(pos) \
199 ml[pos] = liberty_mark
200
201#define UNMARKED_STRING(pos) \
202 (string[string_number[pos]].mark != string_mark)
203
204/* Note that these two macros are not complementary. Both return
205 * false if board[pos] != color.
206 */
207#define UNMARKED_COLOR_STRING(pos, color)\
208 (board[pos] == color\
209 && string[string_number[pos]].mark != string_mark)
210
211#define MARKED_COLOR_STRING(pos, color)\
212 (board[pos] == color\
213 && string[string_number[pos]].mark == string_mark)
214
215#define MARK_STRING(pos) string[string_number[pos]].mark = string_mark
216
217#define STRING_AT_VERTEX(pos, s, color)\
218 ((board[pos] == color) && string_number[pos] == (s))
219
220#define NEIGHBOR_OF_STRING(pos, s, color)\
221 (STRING_AT_VERTEX(SOUTH(pos), s, color)\
222 || STRING_AT_VERTEX(WEST(pos), s, color)\
223 || STRING_AT_VERTEX(NORTH(pos), s, color)\
224 || STRING_AT_VERTEX(EAST(pos), s, color))
225
226/* These four macros have rather confusing names. It should be read as:
227 * "(pos) is a neighbor of string (s) of (color) in any direction except
228 * the specified one".
229 */
230#define NON_SOUTH_NEIGHBOR_OF_STRING(pos, s, color)\
231 (STRING_AT_VERTEX(SOUTH(pos), s, color)\
232 || STRING_AT_VERTEX(WEST(pos), s, color)\
233 || STRING_AT_VERTEX(EAST(pos), s, color))
234
235#define NON_WEST_NEIGHBOR_OF_STRING(pos, s, color)\
236 (STRING_AT_VERTEX(WEST(pos), s, color)\
237 || STRING_AT_VERTEX(NORTH(pos), s, color)\
238 || STRING_AT_VERTEX(SOUTH(pos), s, color))
239
240#define NON_NORTH_NEIGHBOR_OF_STRING(pos, s, color)\
241 (STRING_AT_VERTEX(NORTH(pos), s, color)\
242 || STRING_AT_VERTEX(EAST(pos), s, color)\
243 || STRING_AT_VERTEX(WEST(pos), s, color))
244
245#define NON_EAST_NEIGHBOR_OF_STRING(pos, s, color)\
246 (STRING_AT_VERTEX(EAST(pos), s, color)\
247 || STRING_AT_VERTEX(SOUTH(pos), s, color)\
248 || STRING_AT_VERTEX(NORTH(pos), s, color))
249
250#define LIBERTIES(pos)\
251 string[string_number[pos]].liberties
252
253#define COUNTSTONES(pos) \
254 string[string_number[pos]].size
255
256#define ADD_LIBERTY(s, pos)\
257 do {\
258 if (string[s].liberties < MAX_LIBERTIES)\
259 string_libs[s].list[string[s].liberties] = pos;\
260 string[s].liberties++;\
261 } while (0)
262
263#define ADD_AND_MARK_LIBERTY(s, pos)\
264 do {\
265 if (string[s].liberties < MAX_LIBERTIES)\
266 string_libs[s].list[string[s].liberties] = pos;\
267 string[s].liberties++;\
268 ml[pos] = liberty_mark;\
269 } while (0)
270
271#define ADD_NEIGHBOR(s, pos)\
272 string_neighbors[s].list[string[s].neighbors++] = string_number[pos]
273
274#define DO_ADD_STONE(pos, color)\
275 do {\
276 PUSH_VERTEX(board[pos]);\
277 board[pos] = color;\
278 hashdata_invert_stone(&board_hash, pos, color);\
279 } while (0)
280
281#define DO_REMOVE_STONE(pos)\
282 do {\
283 PUSH_VERTEX(board[pos]);\
284 hashdata_invert_stone(&board_hash, pos, board[pos]);\
285 board[pos] = EMPTY;\
286 } while (0)
287
288
289/* ---------------------------------------------------------------- */
290
291
292
293/* Number of the next free string. */
294static int next_string;
295
296
297/* For marking purposes. */
298static int ml[BOARDMAX];
299static int liberty_mark;
300static int string_mark;
301
302
303/* Forward declarations. */
304static void really_do_trymove(int pos, int color);
305static int do_trymove(int pos, int color, int ignore_ko);
306static void undo_trymove(void);
307
308static int do_approxlib(int pos, int color, int maxlib, int *libs);
309static int slow_approxlib(int pos, int color, int maxlib, int *libs);
310static int do_accuratelib(int pos, int color, int maxlib, int *libs);
311
312static int is_superko_violation(int pos, int color, enum ko_rules type);
313
314static void new_position(void);
315static int propagate_string(int stone, int str);
316static void find_liberties_and_neighbors(int s);
317static int do_remove_string(int s);
318static void do_commit_suicide(int pos, int color);
319static void do_play_move(int pos, int color);
320
321static int komaster, kom_pos;
322
323
324/* Statistics. */
325static int trymove_counter = 0;
326
327/* Coordinates for the eight directions, ordered
328 * south, west, north, east, southwest, northwest, northeast, southeast.
329 */
330int deltai[8] = { 1, 0, -1, 0, 1, -1, -1, 1};
331int deltaj[8] = { 0, -1, 0, 1, -1, -1, 1, 1};
332int delta[8] = { NS, -1, -NS, 1, NS-1, -NS-1, -NS+1, NS+1};
333
334
335/* ================================================================ */
336/* Board initialization */
337/* ================================================================ */
338
339/*
340 * Save board state.
341 */
342
343void
344store_board(struct board_state *state)
345{
346 int k;
347
348 gg_assert(stackp == 0);
349
350 state->board_size = board_size;
351
352 memcpy(state->board, board, sizeof(board));
353 memcpy(state->initial_board, initial_board, sizeof(initial_board));
354
355 state->board_ko_pos = board_ko_pos;
356 state->white_captured = white_captured;
357 state->black_captured = black_captured;
358
359 state->initial_board_ko_pos = initial_board_ko_pos;
360 state->initial_white_captured = initial_white_captured;
361 state->initial_black_captured = initial_black_captured;
362
363 state->move_history_pointer = move_history_pointer;
364 for (k = 0; k < move_history_pointer; k++) {
365 state->move_history_color[k] = move_history_color[k];
366 state->move_history_pos[k] = move_history_pos[k];
367 state->move_history_hash[k] = move_history_hash[k];
368 }
369
370 state->komi = komi;
371 state->handicap = handicap;
372 state->move_number = movenum;
373}
374
375
376/*
377 * Restore a saved board state.
378 */
379
380void
381restore_board(struct board_state *state)
382{
383 int k;
384
385 gg_assert(stackp == 0);
386
387 board_size = state->board_size;
388
389 memcpy(board, state->board, sizeof(board));
390 memcpy(initial_board, state->initial_board, sizeof(initial_board));
391
392 board_ko_pos = state->board_ko_pos;
393 white_captured = state->white_captured;
394 black_captured = state->black_captured;
395
396 initial_board_ko_pos = state->initial_board_ko_pos;
397 initial_white_captured = state->initial_white_captured;
398 initial_black_captured = state->initial_black_captured;
399
400 move_history_pointer = state->move_history_pointer;
401 for (k = 0; k < move_history_pointer; k++) {
402 move_history_color[k] = state->move_history_color[k];
403 move_history_pos[k] = state->move_history_pos[k];
404 move_history_hash[k] = state->move_history_hash[k];
405 }
406
407 komi = state->komi;
408 handicap = state->handicap;
409 movenum = state->move_number;
410
411 hashdata_recalc(&board_hash, board, board_ko_pos);
412 new_position();
413}
414
415
416/*
417 * Clear the internal board.
418 */
419
420void
421clear_board(void)
422{
423 int k;
424
425 gg_assert(board_size > 0 && board_size <= MAX_BOARD);
426
427 memset(board, EMPTY, sizeof(board));
428 memset(initial_board, EMPTY, sizeof(initial_board));
429 for (k = 0; k < BOARDSIZE; k++) {
430 if (!ON_BOARD2(I(k), J(k))) {
431 board[k] = GRAY;
432 initial_board[k] = GRAY;
433 }
434 }
435
436 board_ko_pos = NO_MOVE;
437 white_captured = 0;
438 black_captured = 0;
439
440 komaster = EMPTY;
441 kom_pos = NO_MOVE;
442
443 initial_board_ko_pos = NO_MOVE;
444 initial_white_captured = 0;
445 initial_black_captured = 0;
446
447 move_history_pointer = 0;
448 movenum = 0;
449
450 handicap = 0;
451
452 hashdata_recalc(&board_hash, board, board_ko_pos);
453 new_position();
454}
455
456/* Test the integrity of the gray border. */
457int
458test_gray_border(void)
459{
460 int k;
461
462 gg_assert(board_size > 0 && board_size <= MAX_BOARD);
463
464 for (k = 0; k < BOARDSIZE; k++)
465 if (!ON_BOARD2(I(k), J(k)))
466 if (board[k] != GRAY)
467 return k;
468
469 return -1;
470}
471
472
473/* ================================================================ */
474/* Temporary moves */
475/* ================================================================ */
476
477
478/* Stack of trial moves to get to current
479 * position and which color made them. Perhaps
480 * this should be one array of a structure
481 */
482static int stack[MAXSTACK];
483static int move_color[MAXSTACK];
484
485static Hash_data board_hash_stack[MAXSTACK];
486
487/*
488 * trymove pushes the position onto the stack, and makes a move
489 * at pos of color. Returns one if the move is legal. The
490 * stack pointer is only incremented if the move is legal.
491 *
492 * The way to use this is:
493 *
494 * if (trymove(...)) {
495 * ...
496 * popgo();
497 * }
498 *
499 * The message can be written as a comment to an sgf file using
500 * sgfdump(). str can be NO_MOVE if it is not needed but otherwise
501 * the location of str is included in the comment.
502 */
503
504int
505trymove(int pos, int color, const char *message, int str)
506{
507 UNUSED(str);
508 /* Do the real work elsewhere. */
509 if (!do_trymove(pos, color, 0))
510 return 0;
511
512 /* Store the move in an sgf tree if one is available. */
513 if (sgf_dumptree) {
514 char buf[100];
515
516 if (message == NULL)
517 message = "UNKNOWN";
518
519 if (pos == NO_MOVE) {
520 if (komaster != EMPTY)
521 gg_snprintf(buf, 100, "%s (variation %d, hash %s, komaster %s:%s)",
522 message, count_variations, hashdata_to_string(&board_hash),
523 color_to_string(komaster), location_to_string(kom_pos));
524 else
525 gg_snprintf(buf, 100, "%s (variation %d, hash %s)", message,
526 count_variations, hashdata_to_string(&board_hash));
527 }
528 else {
529 if (komaster != EMPTY)
530 gg_snprintf(buf, 100,
531 "%s at %s (variation %d, hash %s, komaster %s:%s)",
532 message, location_to_string(pos), count_variations,
533 hashdata_to_string(&board_hash),
534 color_to_string(komaster),
535 location_to_string(kom_pos));
536 else
537 gg_snprintf(buf, 100, "%s at %s (variation %d, hash %s)",
538 message, location_to_string(pos), count_variations,
539 hashdata_to_string(&board_hash));
540 }
541 sgftreeAddPlayLast(sgf_dumptree, color, I(pos), J(pos));
542 sgftreeAddComment(sgf_dumptree, buf);
543 }
544
545 if (count_variations)
546 count_variations++;
547 stats.nodes++;
548
549 return 1;
550}
551
552
553/*
554 * tryko pushes the position onto the stack, and makes a move
555 * at (pos) of (color). The move is allowed even if it is an
556 * illegal ko capture. It is to be imagined that (color) has
557 * made an intervening ko threat which was answered and now
558 * the continuation is to be explored.
559 *
560 * Return 1 if the move is legal with the above caveat. Returns
561 * zero if it is not legal because of suicide.
562 */
563
564int
565tryko(int pos, int color, const char *message)
566{
567 /* Do the real work elsewhere. */
568 if (!do_trymove(pos, color, 1))
569 return 0;
570
571 if (sgf_dumptree) {
572 char buf[100];
573 if (message == NULL)
574 message = "UNKNOWN";
575 if (komaster != EMPTY)
576 gg_snprintf(buf, 100, "tryko: %s (variation %d, %s, komaster %s:%s)",
577 message, count_variations, hashdata_to_string(&board_hash),
578 color_to_string(komaster), location_to_string(kom_pos));
579 else
580 gg_snprintf(buf, 100, "tryko: %s (variation %d, %s)", message,
581 count_variations, hashdata_to_string(&board_hash));
582
583 /* Add two pass moves to the SGF output to simulate the ko threat
584 * and the answer.
585 *
586 * The reason we add these is that certain SGF viewers, including
587 * Cgoban 1, won't properly display variations with illegal ko
588 * captures. SGF FF[4] compliant browsers should have no problem
589 * with this, though.
590 */
591 sgftreeAddPlayLast(sgf_dumptree, color, -1, -1);
592 sgftreeAddComment(sgf_dumptree, "tenuki (ko threat)");
593 sgftreeAddPlayLast(sgf_dumptree, OTHER_COLOR(color), -1, -1);
594 sgftreeAddComment(sgf_dumptree, "tenuki (answers ko threat)");
595
596 sgftreeAddPlayLast(sgf_dumptree, color, I(pos), J(pos));
597 sgftreeAddComment(sgf_dumptree, buf);
598 }
599
600 if (count_variations)
601 count_variations++;
602 stats.nodes++;
603
604 return 1;
605}
606
607/* Really, really make a temporary move. It is assumed that all
608 * necessary checks have already been made and likewise that various
609 * administrative bookkeeping outside of the actual board logic has
610 * either been done or is not needed.
611 */
612static void
613really_do_trymove(int pos, int color)
614{
615 BEGIN_CHANGE_RECORD();
616 PUSH_VALUE(board_ko_pos);
617
618 /*
619 * FIXME: Do we really have to store board_hash in a stack?
620 *
621 * Answer: No, we don't. But for every stone that we add
622 * or remove, we must call hashdata_invert_stone(). This is
623 * not difficult per se, but the whole board.c
624 * will have to be checked, and there is lots of room
625 * for mistakes.
626 *
627 * At the same time, profiling shows that storing the
628 * hashdata in a stack doesn't take a lot of time, so
629 * this is not an urgent FIXME.
630 */
631 memcpy(&board_hash_stack[stackp], &board_hash, sizeof(board_hash));
632
633 if (board_ko_pos != NO_MOVE)
634 hashdata_invert_ko(&board_hash, board_ko_pos);
635
636 board_ko_pos = NO_MOVE;
637
638 stackp++;
639
640 if (pos != PASS_MOVE) {
641 PUSH_VALUE(black_captured);
642 PUSH_VALUE(white_captured);
643 do_play_move(pos, color);
644 }
645}
646
647/*
648 * Do the main work of trymove() and tryko(), i.e. the common parts.
649 * The ignore_ko flag tells whether an illegal ko capture may be done.
650 * Return 1 if the move was valid, otherwise 0.
651 */
652
653static int
654do_trymove(int pos, int color, int ignore_ko)
655{
656 /* 1. The color must be BLACK or WHITE. */
657 gg_assert(color == BLACK || color == WHITE);
658
659 if (pos != PASS_MOVE) {
660 /* 2. Unless pass, the move must be inside the board. */
661 ASSERT_ON_BOARD1(pos);
662
663 /* Update the reading tree shadow. */
664 shadow[pos] = 1;
665
666 /* 3. The location must be empty. */
667 if (board[pos] != EMPTY)
668 return 0;
669
670 /* 4. The location must not be the ko point, unless ignore_ko == 1. */
671 if (!ignore_ko && pos == board_ko_pos) {
672 if (board[WEST(pos)] == OTHER_COLOR(color)
673 || board[EAST(pos)] == OTHER_COLOR(color)) {
674 return 0;
675 }
676 }
677
678 /* 5. Test for suicide. */
679 if (is_suicide(pos, color))
680 return 0;
681 }
682
683 /* Check for stack overflow. */
684 if (stackp >= MAXSTACK-2) {
685 fprintf(stderr,
686 "gnugo: Truncating search. This is beyond my reading ability!\n");
687 /* FIXME: Perhaps it's best to just assert here and be done with it? */
688 if (0) {
689 ASSERT1(0 && "trymove stack overflow", pos);
690 }
691#if 0
692 if (verbose > 0) {
693 showboard(0);
694 dump_stack();
695 }
696#endif
697 fflush(stderr);
698 return 0;
699 }
700
701
702 /* Only count trymove when we do create a new position. */
703 trymove_counter++;
704
705 /* So far, so good. Now push the move on the move stack. These are
706 * needed for dump_stack().
707 */
708 stack[stackp] = pos;
709 move_color[stackp] = color;
710
711 really_do_trymove(pos, color);
712
713 return 1;
714}
715
716
717/*
718 * popgo pops the position from the stack.
719 */
720
721void
722popgo()
723{
724 undo_trymove();
725
726 if (sgf_dumptree) {
727 char buf[100];
728 int is_tryko = 0;
729 char *sgf_comment;
730
731 /* FIXME: Change the sgfGet*Property() interface so that either
732 * "C" instead of "C " works or the SGFXX symbols are used.
733 */
734 if (sgfGetCharProperty(sgf_dumptree->lastnode, "C ", &sgf_comment)
735 && strncmp(sgf_comment, "tryko:", 6) == 0)
736 is_tryko = 1;
737
738 gg_snprintf(buf, 100, "(next variation: %d)", count_variations);
739 sgftreeAddComment(sgf_dumptree, buf);
740 sgf_dumptree->lastnode = sgf_dumptree->lastnode->parent;
741
742 /* After tryko() we need to undo two pass nodes too. */
743 if (is_tryko)
744 sgf_dumptree->lastnode = sgf_dumptree->lastnode->parent->parent;
745 }
746}
747
748
749/* Restore board state to the position before the last move. This is
750 * accomplished by popping everything that was stored on the stacks
751 * since the last BEGIN_CHANGE_RECORD(). Also stackp is decreased and
752 * board hash is restored from stack.
753 *
754 * This undoes the effects of do_trymove() or really_do_trymove() and
755 * is appropriate to call instead of popgo() if you have not passed
756 * through trymove() or tryko().
757 */
758
759static void
760undo_trymove()
761{
762 gg_assert(change_stack_pointer - change_stack <= STACK_SIZE);
763
764 if (0) {
765 gprintf("Change stack size = %d\n", change_stack_pointer - change_stack);
766 gprintf("Vertex stack size = %d\n", vertex_stack_pointer - vertex_stack);
767 }
768
769 POP_MOVE();
770 POP_VERTICES();
771
772 stackp--;
773 memcpy(&board_hash, &(board_hash_stack[stackp]), sizeof(board_hash));
774}
775
776
777
778/*
779 * dump_stack() for use under gdb prints the move stack.
780 */
781
782void
783dump_stack(void)
784{
785 do_dump_stack();
786
787#if !TRACE_READ_RESULTS
788 if (count_variations)
789 gprintf("%o (variation %d)", count_variations-1);
790#else
791 gprintf("%o (%s)", hashdata_to_string(&board_hash));
792#endif
793
794 gprintf("%o\n");
795 fflush(stderr);
796}
797
798/* Bare bones of dump_stack(). */
799void
800do_dump_stack(void)
801{
802 int n;
803
804 for (n = 0; n < stackp; n++)
805 gprintf("%o%s:%1m ", move_color[n] == BLACK ? "B" : "W", stack[n]);
806}
807
808/* ================================================================ */
809/* Permanent moves */
810/* ================================================================ */
811
812
813static void
814reset_move_history(void)
815{
816 memcpy(initial_board, board, sizeof(board));
817 initial_board_ko_pos = board_ko_pos;
818 initial_white_captured = white_captured;
819 initial_black_captured = black_captured;
820 move_history_pointer = 0;
821}
822
823/* Place a stone on the board and update the board_hash. This operation
824 * destroys all move history.
825 */
826
827void
828add_stone(int pos, int color)
829{
830 ASSERT1(stackp == 0, pos);
831 ASSERT_ON_BOARD1(pos);
832 ASSERT1(board[pos] == EMPTY, pos);
833
834 board[pos] = color;
835 hashdata_invert_stone(&board_hash, pos, color);
836 reset_move_history();
837 new_position();
838}
839
840
841/* Remove a stone from the board and update the board_hash. This
842 * operation destroys the move history.
843 */
844
845void
846remove_stone(int pos)
847{
848 ASSERT1(stackp == 0, pos);
849 ASSERT_ON_BOARD1(pos);
850 ASSERT1(IS_STONE(board[pos]), pos);
851
852 hashdata_invert_stone(&board_hash, pos, board[pos]);
853 board[pos] = EMPTY;
854 reset_move_history();
855 new_position();
856}
857
858
859/* Play a move. Basically the same as play_move() below, but doesn't store
860 * the move in history list.
861 *
862 * Set `update_internals' to zero if you want to play several moves in a
863 * row to avoid overhead caused by new_position(). Don't forget to call
864 * it yourself after all the moves have been played.
865 */
866static void
867play_move_no_history(int pos, int color, int update_internals)
868{
869#if CHECK_HASHING
870 Hash_data oldkey;
871
872 /* Check the hash table to see if it corresponds to the cumulative one. */
873 hashdata_recalc(&oldkey, board, board_ko_pos);
874 gg_assert(hashdata_is_equal(oldkey, board_hash));
875#endif
876
877 if (board_ko_pos != NO_MOVE)
878 hashdata_invert_ko(&board_hash, board_ko_pos);
879 board_ko_pos = NO_MOVE;
880
881 /* If the move is a pass, we can skip some steps. */
882 if (pos != PASS_MOVE) {
883 ASSERT_ON_BOARD1(pos);
884 ASSERT1(board[pos] == EMPTY, pos);
885
886 /* Do play the move. */
887 if (!is_suicide(pos, color))
888 do_play_move(pos, color);
889 else
890 do_commit_suicide(pos, color);
891
892#if CHECK_HASHING
893 /* Check the hash table to see if it equals the previous one. */
894 hashdata_recalc(&oldkey, board, board_ko_pos);
895 gg_assert(hashdata_is_equal(oldkey, board_hash));
896#endif
897 }
898
899 if (update_internals || next_string == MAX_STRINGS)
900 new_position();
901 else
902 CLEAR_STACKS();
903}
904
905/* Load the initial position and replay the first n moves. */
906static void
907replay_move_history(int n)
908{
909 int k;
910
911 memcpy(board, initial_board, sizeof(board));
912 board_ko_pos = initial_board_ko_pos;
913 white_captured = initial_white_captured;
914 black_captured = initial_black_captured;
915 new_position();
916
917 for (k = 0; k < n; k++)
918 play_move_no_history(move_history_pos[k], move_history_color[k], 0);
919
920 new_position();
921}
922
923/* Play a move. If you want to test for legality you should first call
924 * is_legal(). This function strictly follows the algorithm:
925 * 1. Place a stone of given color on the board.
926 * 2. If there are any adjacent opponent strings without liberties,
927 * remove them and increase the prisoner count.
928 * 3. If the newly placed stone is part of a string without liberties,
929 * remove it and increase the prisoner count.
930 *
931 * In spite of the name "permanent move", this move can (usually) be
932 * unplayed by undo_move(), but it is significantly more costly than
933 * unplaying a temporary move. There are limitations on the available
934 * move history, so under certain circumstances the move may not be
935 * possible to unplay at a later time.
936 */
937void
938play_move(int pos, int color)
939{
940 ASSERT1(stackp == 0, pos);
941 ASSERT1(color == WHITE || color == BLACK, pos);
942 ASSERT1(pos == PASS_MOVE || ON_BOARD1(pos), pos);
943 ASSERT1(pos == PASS_MOVE || board[pos] == EMPTY, pos);
944 ASSERT1(komaster == EMPTY && kom_pos == NO_MOVE, pos);
945
946 if (move_history_pointer >= MAX_MOVE_HISTORY) {
947 /* The move history is full. We resolve this by collapsing the
948 * first about 10% of the moves into the initial position.
949 */
950 int number_collapsed_moves = 1 + MAX_MOVE_HISTORY / 10;
951 int k;
952 Intersection saved_board[BOARDSIZE];
953 int saved_board_ko_pos = board_ko_pos;
954 int saved_white_captured = white_captured;
955 int saved_black_captured = black_captured;
956 memcpy(saved_board, board, sizeof(board));
957
958 replay_move_history(number_collapsed_moves);
959
960 memcpy(initial_board, board, sizeof(board));
961 initial_board_ko_pos = board_ko_pos;
962 initial_white_captured = white_captured;
963 initial_black_captured = black_captured;
964
965 for (k = number_collapsed_moves; k < move_history_pointer; k++) {
966 move_history_color[k - number_collapsed_moves] = move_history_color[k];
967 move_history_pos[k - number_collapsed_moves] = move_history_pos[k];
968 move_history_hash[k - number_collapsed_moves] = move_history_hash[k];
969 }
970 move_history_pointer -= number_collapsed_moves;
971
972 memcpy(board, saved_board, sizeof(board));
973 board_ko_pos = saved_board_ko_pos;
974 white_captured = saved_white_captured;
975 black_captured = saved_black_captured;
976 new_position();
977 }
978
979 move_history_color[move_history_pointer] = color;
980 move_history_pos[move_history_pointer] = pos;
981 move_history_hash[move_history_pointer] = board_hash;
982 if (board_ko_pos != NO_MOVE)
983 hashdata_invert_ko(&move_history_hash[move_history_pointer], board_ko_pos);
984 move_history_pointer++;
985
986 play_move_no_history(pos, color, 1);
987
988 movenum++;
989}
990
991
992/* Undo n permanent moves. Returns 1 if successful and 0 if it fails.
993 * If n moves cannot be undone, no move is undone.
994 */
995int
996undo_move(int n)
997{
998 gg_assert(stackp == 0);
999
1000 /* Fail if and only if the move history is too short. */
1001 if (move_history_pointer < n)
1002 return 0;
1003
1004 replay_move_history(move_history_pointer - n);
1005 move_history_pointer -= n;
1006 movenum -= n;
1007
1008 return 1;
1009}
1010
1011
1012/* Return the last move done by the opponent to color. Both if no move
1013 * was found or if the last move was a pass, PASS_MOVE is returned.
1014 */
1015int
1016get_last_opponent_move(int color)
1017{
1018 int k;
1019
1020 for (k = move_history_pointer - 1; k >= 0; k--)
1021 if (move_history_color[k] == OTHER_COLOR(color))
1022 return move_history_pos[k];
1023
1024 return PASS_MOVE;
1025}
1026
1027/* Return the last move done by anyone. Both if no move was found or
1028 * if the last move was a pass, PASS_MOVE is returned.
1029 */
1030int
1031get_last_move()
1032{
1033 if (move_history_pointer == 0)
1034 return PASS_MOVE;
1035
1036 return move_history_pos[move_history_pointer - 1];
1037}
1038
1039/* Return the color of the player doing the last move. If no move was
1040 * found, EMPTY is returned.
1041 */
1042int
1043get_last_player()
1044{
1045 if (move_history_pointer == 0)
1046 return EMPTY;
1047
1048 return move_history_color[move_history_pointer - 1];
1049}
1050
1051
1052/* ================================================================ */
1053/* Utility functions */
1054/* ================================================================ */
1055
1056
1057/*
1058 * Test if the move is a pass or not. Return 1 if it is.
1059 */
1060
1061int
1062is_pass(int pos)
1063{
1064 return pos == 0;
1065}
1066
1067
1068/*
1069 * is_legal(pos, color) determines whether the move (color) at pos is
1070 * legal. This is for internal use in the engine and always assumes
1071 * that suicide is allowed and only simple ko restrictions, no
1072 * superko, regardless of the rules actually used in the game.
1073 *
1074 * Use is_allowed_move() if you want to take alternative suicide and
1075 * ko rules into account.
1076 */
1077
1078int
1079is_legal(int pos, int color)
1080{
1081 /* 0. A pass move is always legal. */
1082 if (pos == PASS_MOVE)
1083 return 1;
1084
1085 /* 1. The move must be inside the board. */
1086 ASSERT_ON_BOARD1(pos);
1087
1088 /* 2. The location must be empty. */
1089 if (board[pos] != EMPTY)
1090 return 0;
1091
1092 /* 3. The location must not be the ko point. */
1093 if (pos == board_ko_pos) {
1094 /* The ko position is guaranteed to have all neighbors of the
1095 * same color, or off board. If that color is the same as the
1096 * move the ko is being filled, which is always allowed. This
1097 * could be tested with has_neighbor() but here a faster test
1098 * suffices.
1099 */
1100 if (board[WEST(pos)] == OTHER_COLOR(color)
1101 || board[EAST(pos)] == OTHER_COLOR(color)) {
1102 return 0;
1103 }
1104 }
1105
1106 /* Check for stack overflow. */
1107 if (stackp >= MAXSTACK-2) {
1108 fprintf(stderr,
1109 "gnugo: Truncating search. This is beyond my reading ability!\n");
1110 /* FIXME: Perhaps it's best to just assert here and be done with it? */
1111 if (0) {
1112 ASSERT1(0 && "is_legal stack overflow", pos);
1113 }
1114 return 0;
1115 }
1116
1117 /* Check for suicide. */
1118 if (is_suicide(pos, color))
1119 return 0;
1120
1121 return 1;
1122}
1123
1124
1125/*
1126 * is_suicide(pos, color) determines whether the move (color) at
1127 * (pos) would be a suicide.
1128 *
1129 * This is the case if
1130 * 1. There is no neighboring empty intersection.
1131 * 2. There is no neighboring opponent string with exactly one liberty.
1132 * 3. There is no neighboring friendly string with more than one liberty.
1133 */
1134int
1135is_suicide(int pos, int color)
1136{
1137 ASSERT_ON_BOARD1(pos);
1138 ASSERT1(board[pos] == EMPTY, pos);
1139
1140 /* Check for suicide. */
1141 if (LIBERTY(SOUTH(pos))
1142 || (ON_BOARD(SOUTH(pos))
1143 && ((board[SOUTH(pos)] == color) ^ (LIBERTIES(SOUTH(pos)) == 1))))
1144 return 0;
1145
1146 if (LIBERTY(WEST(pos))
1147 || (ON_BOARD(WEST(pos))
1148 && ((board[WEST(pos)] == color) ^ (LIBERTIES(WEST(pos)) == 1))))
1149 return 0;
1150
1151 if (LIBERTY(NORTH(pos))
1152 || (ON_BOARD(NORTH(pos))
1153 && ((board[NORTH(pos)] == color) ^ (LIBERTIES(NORTH(pos)) == 1))))
1154 return 0;
1155
1156 if (LIBERTY(EAST(pos))
1157 || (ON_BOARD(EAST(pos))
1158 && ((board[EAST(pos)] == color) ^ (LIBERTIES(EAST(pos)) == 1))))
1159 return 0;
1160
1161 return 1;
1162}
1163
1164
1165/*
1166 * is_illegal_ko_capture(pos, color) determines whether the move
1167 * (color) at (pos) would be an illegal ko capture.
1168 */
1169int
1170is_illegal_ko_capture(int pos, int color)
1171{
1172 ASSERT_ON_BOARD1(pos);
1173 ASSERT1(board[pos] == EMPTY, pos);
1174
1175 return (pos == board_ko_pos
1176 && ((board[WEST(pos)] == OTHER_COLOR(color))
1177 || (board[EAST(pos)] == OTHER_COLOR(color))));
1178}
1179
1180/*
1181 * is_allowed_move(int pos, int color) determines whether a move is
1182 * legal with respect to the suicide and ko rules in play.
1183 *
1184 * This function is only valid when stackp == 0 since there is no
1185 * tracking of superko for trymoves.
1186 */
1187int
1188is_allowed_move(int pos, int color)
1189{
1190 gg_assert(stackp == 0);
1191
1192 /* 1. A pass move is always legal, no matter what. */
1193 if (pos == PASS_MOVE)
1194 return 1;
1195
1196 /* 2. The move must be inside the board. */
1197 ASSERT_ON_BOARD1(pos);
1198
1199 /* 3. The location must be empty. */
1200 if (board[pos] != EMPTY)
1201 return 0;
1202
1203 /* 4. Simple ko repetition is only allowed if no ko rule is in use.
1204 * For superko rules this check is redundant.
1205 *
1206 * The ko position is guaranteed to have all neighbors of the
1207 * same color, or off board. If that color is the same as the
1208 * move the ko is being filled, which is always allowed. This
1209 * could be tested with has_neighbor() but here a faster test
1210 * suffices.
1211 */
1212 if (ko_rule != NONE
1213 && pos == board_ko_pos
1214 && (board[WEST(pos)] == OTHER_COLOR(color)
1215 || board[EAST(pos)] == OTHER_COLOR(color)))
1216 return 0;
1217
1218 /* 5. Check for suicide. Suicide rule options:
1219 * FORBIDDEN - No suicides allowed.
1220 * ALLOWED - Suicide of more than one stone allowed.
1221 * ALL_ALLOWED - All suicides allowed.
1222 */
1223 if (is_suicide(pos, color))
1224 if (suicide_rule == FORBIDDEN
1225 || (suicide_rule == ALLOWED
1226 && !has_neighbor(pos, color)))
1227 return 0;
1228
1229 /* 6. Check for whole board repetitions. The superko options are
1230 * SIMPLE, NONE - No superko restrictions.
1231 * PSK - Repetition of a previous position forbidden.
1232 * SSK - Repetition of a previous position with the same
1233 * player to move forbidden.
1234 */
1235 if (is_superko_violation(pos, color, ko_rule))
1236 return 0;
1237
1238 return 1;
1239}
1240
1241/* Necessary work to set the new komaster state. */
1242static void
1243set_new_komaster(int new_komaster)
1244{
1245 PUSH_VALUE(komaster);
1246 hashdata_invert_komaster(&board_hash, komaster);
1247 komaster = new_komaster;
1248 hashdata_invert_komaster(&board_hash, komaster);
1249}
1250
1251/* Necessary work to set the new komaster position. */
1252static void
1253set_new_kom_pos(int new_kom_pos)
1254{
1255 PUSH_VALUE(kom_pos);
1256 hashdata_invert_kom_pos(&board_hash, kom_pos);
1257 kom_pos = new_kom_pos;
1258 hashdata_invert_kom_pos(&board_hash, kom_pos);
1259}
1260
1261/* Variation of trymove()/tryko() where ko captures (both conditional
1262 * and unconditional) must follow a komaster scheme.
1263 *
1264 * Historical note: Up to GNU Go 3.4 five different komaster schemes
1265 * were implemented and could easily be switched between. In GNU Go
1266 * 3.5.1 four of them were removed to simplify the code and because it
1267 * no longer seemed interesting to be able to switch. The remaining
1268 * komaster scheme was previously known as komaster scheme 5 (or V).
1269 *
1270 * FIXME: This function could be optimized by integrating the
1271 * trymove()/tryko() code.
1272 */
1273
1274/* V. Complex scheme, O to move.
1275 *
1276 * 1. Komaster is EMPTY.
1277 * 1a) Unconditional ko capture is allowed.
1278 * Komaster remains EMPTY if previous move was not a ko capture.
1279 * Komaster is set to WEAK_KO if previous move was a ko capture
1280 * and kom_pos is set to the old value of board_ko_pos.
1281 * 1b) Conditional ko capture is allowed. Komaster is set to O and
1282 * kom_pos to the location of the ko, where a stone was
1283 * just removed.
1284 *
1285 * 2. Komaster is O:
1286 * 2a) Only nested ko captures are allowed. Kom_pos is moved to the
1287 * new removed stone.
1288 * 2b) If komaster fills the ko at kom_pos then komaster reverts to
1289 * EMPTY.
1290 *
1291 * 3. Komaster is X:
1292 * Play at kom_pos is not allowed. Any other ko capture
1293 * is allowed. If O takes another ko, komaster becomes GRAY_X.
1294 *
1295 * 4. Komaster is GRAY_O or GRAY_X:
1296 * Ko captures are not allowed. If the ko at kom_pos is
1297 * filled then the komaster reverts to EMPTY.
1298 *
1299 * 5. Komaster is WEAK_KO:
1300 * 5a) After a non-ko move komaster reverts to EMPTY.
1301 * 5b) Unconditional ko capture is only allowed if it is nested ko capture.
1302 * Komaster is changed to WEAK_X and kom_pos to the old value of
1303 * board_ko_pos.
1304 * 5c) Conditional ko capture is allowed according to the rules of 1b.
1305 */
1306int
1307komaster_trymove(int pos, int color, const char *message, int str,
1308 int *is_conditional_ko, int consider_conditional_ko)
1309{
1310 int other = OTHER_COLOR(color);
1311 int ko_move;
1312 int kpos;
1313 int previous_board_ko_pos = board_ko_pos;
1314
1315 *is_conditional_ko = 0;
1316 ko_move = is_ko(pos, color, &kpos);
1317
1318 if (ko_move) {
1319 /* If opponent is komaster we may not capture his ko. */
1320 if (komaster == other && pos == kom_pos)
1321 return 0;
1322
1323 /* If komaster is gray we may not capture ko at all. */
1324 if (komaster == GRAY_WHITE || komaster == GRAY_BLACK)
1325 return 0;
1326
1327 /* If we are komaster, we may only do nested captures. */
1328 if (komaster == color && !DIAGONAL_NEIGHBORS(kpos, kom_pos))
1329 return 0;
1330
1331 /* If komaster is WEAK_KO, we may only do nested ko capture or
1332 * conditional ko capture.
1333 */
1334 if (komaster == WEAK_KO) {
1335 if (pos != board_ko_pos && !DIAGONAL_NEIGHBORS(kpos, kom_pos))
1336 return 0;
1337 }
1338 }
1339
1340 if (!trymove(pos, color, message, str)) {
1341 if (!consider_conditional_ko)
1342 return 0;
1343
1344 if (!tryko(pos, color, message))
1345 return 0; /* Suicide. */
1346
1347 *is_conditional_ko = 1;
1348
1349 /* Conditional ko capture, set komaster parameters. */
1350 if (komaster == EMPTY || komaster == WEAK_KO) {
1351 set_new_komaster(color);
1352 set_new_kom_pos(kpos);
1353 return 1;
1354 }
1355 }
1356
1357 if (!ko_move) {
1358 /* If we are komaster, check whether the ko was resolved by the
1359 * current move. If that is the case, revert komaster to EMPTY.
1360 *
1361 * The ko has been resolved in favor of the komaster if it has
1362 * been filled, or if it is no longer a ko and an opponent move
1363 * there is suicide.
1364 */
1365 if (((komaster == color
1366 || (komaster == GRAY_WHITE && color == WHITE)
1367 || (komaster == GRAY_BLACK && color == BLACK))
1368 && (IS_STONE(board[kom_pos])
1369 || (!is_ko(kom_pos, other, NULL)
1370 && is_suicide(kom_pos, other))))) {
1371 set_new_komaster(EMPTY);
1372 set_new_kom_pos(NO_MOVE);
1373 }
1374
1375 if (komaster == WEAK_KO) {
1376 set_new_komaster(EMPTY);
1377 set_new_kom_pos(NO_MOVE);
1378 }
1379
1380 return 1;
1381 }
1382
1383 if (komaster == other) {
1384 if (color == WHITE)
1385 set_new_komaster(GRAY_BLACK);
1386 else
1387 set_new_komaster(GRAY_WHITE);
1388 }
1389 else if (komaster == color) {
1390 /* This is where we update kom_pos after a nested capture. */
1391 set_new_kom_pos(kpos);
1392 }
1393 else {
1394 /* We can reach here when komaster is EMPTY or WEAK_KO. If previous
1395 * move was also a ko capture, we now set komaster to WEAK_KO.
1396 */
1397 if (previous_board_ko_pos != NO_MOVE) {
1398 set_new_komaster(WEAK_KO);
1399 set_new_kom_pos(previous_board_ko_pos);
1400 }
1401 }
1402
1403 return 1;
1404}
1405
1406int
1407get_komaster()
1408{
1409 return komaster;
1410}
1411
1412int
1413get_kom_pos()
1414{
1415 return kom_pos;
1416}
1417
1418
1419/* Determine whether vertex is on the edge. */
1420int
1421is_edge_vertex(int pos)
1422{
1423 ASSERT_ON_BOARD1(pos);
1424 if (!ON_BOARD(SW(pos))
1425 || !ON_BOARD(NE(pos)))
1426 return 1;
1427
1428 return 0;
1429}
1430
1431/* Distance to the edge. */
1432int
1433edge_distance(int pos)
1434{
1435 int i = I(pos);
1436 int j = J(pos);
1437 ASSERT_ON_BOARD1(pos);
1438 return gg_min(gg_min(i, board_size-1 - i), gg_min(j, board_size-1 - j));
1439}
1440
1441
1442/* Determine whether vertex is a corner. */
1443int
1444is_corner_vertex(int pos)
1445{
1446 ASSERT_ON_BOARD1(pos);
1447 if ((!ON_BOARD(WEST(pos)) || !ON_BOARD(EAST(pos)))
1448 && (!ON_BOARD(SOUTH(pos)) || !ON_BOARD(NORTH(pos))))
1449 return 1;
1450
1451 return 0;
1452}
1453
1454
1455/* Reorientation of point pos. This function could have been
1456 * implemented using the rotate() function in utils/gg_utils.c but we
1457 * don't want to make libboard dependent on utils.
1458 */
1459int
1460rotate1(int pos, int rot)
1461{
1462 int bs = board_size - 1;
1463 int i = I(pos);
1464 int j = J(pos);
1465 gg_assert(rot >= 0 && rot < 8);
1466
1467 if (pos == PASS_MOVE)
1468 return PASS_MOVE;
1469
1470 if (rot == 0)
1471 return pos; /* identity map */
1472 if (rot == 1)
1473 return POS(bs - j, i); /* rotation over 90 degrees */
1474 if (rot == 2)
1475 return POS(bs - i, bs - j); /* rotation over 180 degrees */
1476 if (rot == 3)
1477 return POS(j, bs - i); /* rotation over 270 degrees */
1478 if (rot == 4)
1479 return POS(j, i); /* flip along diagonal */
1480 if (rot == 5)
1481 return POS(bs - i, j); /* flip */
1482 if (rot == 6)
1483 return POS(bs - j, bs - i); /* flip along diagonal */
1484 if (rot == 7)
1485 return POS(i, bs - j); /* flip */
1486
1487 return PASS_MOVE; /* unreachable */
1488}
1489
1490
1491/* Returns true if the empty vertex respectively the string at pos1 is
1492 * adjacent to the empty vertex respectively the string at pos2.
1493 */
1494int
1495are_neighbors(int pos1, int pos2)
1496{
1497 if (board[pos1] == EMPTY) {
1498 if (board[pos2] == EMPTY)
1499 return (gg_abs(pos1 - pos2) == NS || gg_abs(pos1 - pos2) == WE);
1500 else
1501 return neighbor_of_string(pos1, pos2);
1502 }
1503 else {
1504 if (board[pos2] == EMPTY)
1505 return neighbor_of_string(pos2, pos1);
1506 else
1507 return adjacent_strings(pos1, pos2);
1508 }
1509}
1510
1511
1512/* Count the number of liberties of the string at pos. pos must not be
1513 * empty.
1514 */
1515int
1516countlib(int str)
1517{
1518 ASSERT1(IS_STONE(board[str]), str);
1519
1520 /* We already know the number of liberties. Just look it up. */
1521 return string[string_number[str]].liberties;
1522}
1523
1524
1525/* Find the liberties of the string at str. str must not be
1526 * empty. The locations of up to maxlib liberties are written into
1527 * libs[]. The full number of liberties is returned.
1528 *
1529 * If you want the locations of all liberties, whatever their number,
1530 * you should pass MAXLIBS as the value for maxlib and allocate space
1531 * for libs[] accordingly.
1532 */
1533
1534int
1535findlib(int str, int maxlib, int *libs)
1536{
1537 int k;
1538 int liberties;
1539 int s;
1540
1541 ASSERT1(IS_STONE(board[str]), str);
1542 ASSERT1(libs != NULL, str);
1543
1544 /* We already have the list of liberties and only need to copy it to
1545 * libs[].
1546 *
1547 * However, if the string has more than MAX_LIBERTIES liberties the
1548 * list is truncated and if maxlib is also larger than MAX_LIBERTIES
1549 * we have to traverse the stones in the string in order to find
1550 * where the liberties are.
1551 */
1552 s = string_number[str];
1553 liberties = string[s].liberties;
1554
1555 if (liberties <= MAX_LIBERTIES || maxlib <= MAX_LIBERTIES) {
1556 /* The easy case, it suffices to copy liberty locations from the
1557 * incrementally updated list.
1558 */
1559 for (k = 0; k < maxlib && k < liberties; k++)
1560 libs[k] = string_libs[s].list[k];
1561 }
1562 else {
1563 /* The harder case, where we have to traverse the stones in the
1564 * string. We don't have to check explicitly if we are back to
1565 * the start of the chain since we will run out of liberties
1566 * before that happens.
1567 */
1568 int pos;
1569 liberty_mark++;
1570 for (k = 0, pos = FIRST_STONE(s);
1571 k < maxlib && k < liberties;
1572 pos = NEXT_STONE(pos)) {
1573 if (UNMARKED_LIBERTY(SOUTH(pos))) {
1574 libs[k++] = SOUTH(pos);
1575 MARK_LIBERTY(SOUTH(pos));
1576 if (k >= maxlib)
1577 break;
1578 }
1579
1580 if (UNMARKED_LIBERTY(WEST(pos))) {
1581 libs[k++] = WEST(pos);
1582 MARK_LIBERTY(WEST(pos));
1583 if (k >= maxlib)
1584 break;
1585 }
1586
1587 if (UNMARKED_LIBERTY(NORTH(pos))) {
1588 libs[k++] = NORTH(pos);
1589 MARK_LIBERTY(NORTH(pos));
1590 if (k >= maxlib)
1591 break;
1592 }
1593
1594 if (UNMARKED_LIBERTY(EAST(pos))) {
1595 libs[k++] = EAST(pos);
1596 MARK_LIBERTY(EAST(pos));
1597 if (k >= maxlib)
1598 break;
1599 }
1600 }
1601 }
1602
1603 return liberties;
1604}
1605
1606/* Count the liberties a stone of the given color would get if played
1607 * at (pos). The location (pos) must be empty.
1608 *
1609 * The intent of this function is to be as fast as possible, not
1610 * necessarily complete. But if it returns a positive value (meaning
1611 * it has succeeded), the value is guaranteed to be correct.
1612 *
1613 * Captures are ignored based on the ignore_capture flag. The function
1614 * fails if there are more than two neighbor strings of the same
1615 * color. In this case, the return value is -1. Captures are handled
1616 * in a very limited way, so if ignore_capture is 0, and a capture is
1617 * required, it will often return -1.
1618 *
1619 * Note well, that it relies on incremental data.
1620 */
1621
1622int
1623fastlib(int pos, int color, int ignore_captures)
1624{
1625 int ally1 = -1;
1626 int ally2 = -1;
1627 int fast_liberties = 0;
1628
1629 ASSERT1(board[pos] == EMPTY, pos);
1630 ASSERT1(IS_STONE(color), pos);
1631
1632 /* Find neighboring strings of the same color. If there are more than two of
1633 * them, we give up (it's too difficult to count their common liberties).
1634 */
1635 if (board[SOUTH(pos)] == color) {
1636 ally1 = string_number[SOUTH(pos)];
1637
1638 if (board[WEST(pos)] == color
1639 && string_number[WEST(pos)] != ally1) {
1640 ally2 = string_number[WEST(pos)];
1641
1642 if (board[NORTH(pos)] == color
1643 && string_number[NORTH(pos)] != ally1
1644 && string_number[NORTH(pos)] != ally2)
1645 return -1;
1646 }
1647 else if (board[NORTH(pos)] == color
1648 && string_number[NORTH(pos)] != ally1)
1649 ally2 = string_number[NORTH(pos)];
1650
1651 if (board[EAST(pos)] == color
1652 && string_number[EAST(pos)] != ally1) {
1653 if (ally2 < 0)
1654 ally2 = string_number[EAST(pos)];
1655 else if (string_number[EAST(pos)] != ally2)
1656 return -1;
1657 }
1658 }
1659 else if (board[WEST(pos)] == color) {
1660 ally1 = string_number[WEST(pos)];
1661
1662 if (board[NORTH(pos)] == color
1663 && string_number[NORTH(pos)] != ally1) {
1664 ally2 = string_number[NORTH(pos)];
1665
1666 if (board[EAST(pos)] == color
1667 && string_number[EAST(pos)] != ally1
1668 && string_number[EAST(pos)] != ally2)
1669 return -1;
1670 }
1671 else if (board[EAST(pos)] == color
1672 && string_number[EAST(pos)] != ally1)
1673 ally2 = string_number[EAST(pos)];
1674 }
1675 else if (board[NORTH(pos)] == color) {
1676 ally1 = string_number[NORTH(pos)];
1677
1678 if (board[EAST(pos)] == color
1679 && string_number[EAST(pos)] != ally1)
1680 ally2 = string_number[EAST(pos)];
1681 }
1682 else if (board[EAST(pos)] == color)
1683 ally1 = string_number[EAST(pos)];
1684
1685 /* If we are to ignore captures, the things are very easy. */
1686 if (ignore_captures) {
1687 if (ally1 < 0) { /* No allies */
1688 if (LIBERTY(SOUTH(pos)))
1689 fast_liberties++;
1690 if (LIBERTY(WEST(pos)))
1691 fast_liberties++;
1692 if (LIBERTY(NORTH(pos)))
1693 fast_liberties++;
1694 if (LIBERTY(EAST(pos)))
1695 fast_liberties++;
1696 }
1697 else if (ally2 < 0) { /* One ally */
1698 if (LIBERTY(SOUTH(pos))
1699 && !NON_SOUTH_NEIGHBOR_OF_STRING(SOUTH(pos), ally1, color))
1700 fast_liberties++;
1701 if (LIBERTY(WEST(pos))
1702 && !NON_WEST_NEIGHBOR_OF_STRING(WEST(pos), ally1, color))
1703 fast_liberties++;
1704 if (LIBERTY(NORTH(pos))
1705 && !NON_NORTH_NEIGHBOR_OF_STRING(NORTH(pos), ally1, color))
1706 fast_liberties++;
1707 if (LIBERTY(EAST(pos))
1708 && !NON_EAST_NEIGHBOR_OF_STRING(EAST(pos), ally1, color))
1709 fast_liberties++;
1710
1711 fast_liberties += string[ally1].liberties - 1;
1712 }
1713 else { /* Two allies */
1714 if (LIBERTY(SOUTH(pos))
1715 && !NON_SOUTH_NEIGHBOR_OF_STRING(SOUTH(pos), ally1, color)
1716 && !NON_SOUTH_NEIGHBOR_OF_STRING(SOUTH(pos), ally2, color))
1717 fast_liberties++;
1718 if (LIBERTY(WEST(pos))
1719 && !NON_WEST_NEIGHBOR_OF_STRING(WEST(pos), ally1, color)
1720 && !NON_WEST_NEIGHBOR_OF_STRING(WEST(pos), ally2, color))
1721 fast_liberties++;
1722 if (LIBERTY(NORTH(pos))
1723 && !NON_NORTH_NEIGHBOR_OF_STRING(NORTH(pos), ally1, color)
1724 && !NON_NORTH_NEIGHBOR_OF_STRING(NORTH(pos), ally2, color))
1725 fast_liberties++;
1726 if (LIBERTY(EAST(pos))
1727 && !NON_EAST_NEIGHBOR_OF_STRING(EAST(pos), ally1, color)
1728 && !NON_EAST_NEIGHBOR_OF_STRING(EAST(pos), ally2, color))
1729 fast_liberties++;
1730
1731 fast_liberties += string[ally1].liberties + string[ally2].liberties
1732 - count_common_libs(string[ally1].origin, string[ally2].origin) - 1;
1733 }
1734 }
1735 /* We are to take captures into account. This case is much more rare, so
1736 * it is not optimized much.
1737 */
1738 else {
1739 int k;
1740
1741 for (k = 0; k < 4; k++) {
1742 int neighbor = pos + delta[k];
1743
1744 if (LIBERTY(neighbor)
1745 && (ally1 < 0 || !NEIGHBOR_OF_STRING(neighbor, ally1, color))
1746 && (ally2 < 0 || !NEIGHBOR_OF_STRING(neighbor, ally2, color)))
1747 fast_liberties++;
1748 else if (board[neighbor] == OTHER_COLOR(color) /* A capture */
1749 && LIBERTIES(neighbor) == 1) {
1750 int neighbor_size = COUNTSTONES(neighbor);
1751
1752 if (neighbor_size == 1 || (neighbor_size == 2 && ally1 < 0))
1753 fast_liberties++;
1754 else
1755 return -1;
1756 }
1757 }
1758
1759 if (ally1 >= 0) {
1760 fast_liberties += string[ally1].liberties - 1;
1761 if (ally2 >= 0)
1762 fast_liberties += string[ally2].liberties
1763 - count_common_libs(string[ally1].origin, string[ally2].origin);
1764 }
1765 }
1766
1767 return fast_liberties;
1768}
1769
1770
1771/* Effectively true unless we store full position in hash. */
1772#define USE_BOARD_CACHES (NUM_HASHVALUES <= 4)
1773
1774struct board_cache_entry {
1775 int threshold;
1776 int liberties;
1777 Hash_data position_hash;
1778};
1779
1780
1781/* approxlib() cache. */
1782static struct board_cache_entry approxlib_cache[BOARDMAX][2];
1783
1784
1785/* Clears approxlib() cache. This function should be called only once
1786 * during engine initialization. Sets thresholds to zero.
1787 */
1788void
1789clear_approxlib_cache(void)
1790{
1791 int pos;
1792
1793 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
1794 approxlib_cache[pos][0].threshold = 0;
1795 approxlib_cache[pos][1].threshold = 0;
1796 }
1797}
1798
1799
1800/* Find the liberties a stone of the given color would get if played
1801 * at (pos), ignoring possible captures of opponent stones. (pos)
1802 * must be empty. If libs != NULL, the locations of up to maxlib
1803 * liberties are written into libs[]. The counting of liberties may
1804 * or may not be halted when maxlib is reached. The number of liberties
1805 * found is returned.
1806 *
1807 * If you want the number or the locations of all liberties, however
1808 * many they are, you should pass MAXLIBS as the value for maxlib and
1809 * allocate space for libs[] accordingly.
1810 */
1811int
1812approxlib(int pos, int color, int maxlib, int *libs)
1813{
1814 int liberties;
1815
1816#ifdef USE_BOARD_CACHES
1817
1818 struct board_cache_entry *entry = &approxlib_cache[pos][color - 1];
1819
1820 ASSERT1(board[pos] == EMPTY, pos);
1821 ASSERT1(IS_STONE(color), pos);
1822
1823 if (!libs) {
1824 /* First see if this result is cached. */
1825 if (hashdata_is_equal(board_hash, entry->position_hash)
1826 && maxlib <= entry->threshold) {
1827 return entry->liberties;
1828 }
1829
1830 liberties = fastlib(pos, color, 1);
1831 if (liberties >= 0) {
1832 /* Since fastlib() always returns precise result and doesn't take
1833 * `maxlib' into account, we set threshold to MAXLIBS so that this
1834 * result is used regardless of any `maxlib' passed.
1835 */
1836 entry->threshold = MAXLIBS;
1837 entry->liberties = liberties;
1838 entry->position_hash = board_hash;
1839
1840 return liberties;
1841 }
1842 }
1843
1844 /* We initialize the cache entry threshold to `maxlib'. If do_approxlib()
1845 * or slow_approxlib() finds all the liberties (that is, they don't use
1846 * `maxlib' value for an early return), they will set threshold to
1847 * MAXLIBS themselves.
1848 */
1849 entry->threshold = maxlib;
1850
1851 if (maxlib <= MAX_LIBERTIES)
1852 liberties = do_approxlib(pos, color, maxlib, libs);
1853 else
1854 liberties = slow_approxlib(pos, color, maxlib, libs);
1855
1856 entry->liberties = liberties;
1857 entry->position_hash = board_hash;
1858
1859#else /* not USE_BOARD_CACHES */
1860
1861 ASSERT1(board[pos] == EMPTY, pos);
1862 ASSERT1(IS_STONE(color), pos);
1863
1864 if (!libs) {
1865 liberties = fastlib(pos, color, 1);
1866 if (liberties >= 0)
1867 return liberties;
1868 }
1869
1870 if (maxlib <= MAX_LIBERTIES)
1871 liberties = do_approxlib(pos, color, maxlib, libs);
1872 else
1873 liberties = slow_approxlib(pos, color, maxlib, libs);
1874
1875#endif /* not USE_BOARD_CACHES */
1876
1877 return liberties;
1878}
1879
1880
1881/* Does the real work of approxlib(). */
1882static int
1883do_approxlib(int pos, int color, int maxlib, int *libs)
1884{
1885 int k;
1886 int liberties = 0;
1887
1888 /* Look for empty neighbors and the liberties of the adjacent
1889 * strings of the given color. The algorithm below won't work
1890 * correctly if any of the adjacent strings have more than
1891 * MAX_LIBERTIES liberties AND maxlib is larger than MAX_LIBERTIES.
1892 * therefore approxlib() calls more robust slow_approxlib() if
1893 * this might be the case.
1894 */
1895
1896 /* Start by marking pos itself so it isn't counted among its own
1897 * liberties.
1898 */
1899 liberty_mark++;
1900 MARK_LIBERTY(pos);
1901
1902 if (UNMARKED_LIBERTY(SOUTH(pos))) {
1903 if (libs != NULL)
1904 libs[liberties] = SOUTH(pos);
1905 liberties++;
1906 /* Stop counting if we reach maxlib. */
1907 if (liberties >= maxlib)
1908 return liberties;
1909 MARK_LIBERTY(SOUTH(pos));
1910 }
1911 else if (board[SOUTH(pos)] == color) {
1912 int s = string_number[SOUTH(pos)];
1913 for (k = 0; k < string[s].liberties; k++) {
1914 int lib = string_libs[s].list[k];
1915 if (UNMARKED_LIBERTY(lib)) {
1916 if (libs != NULL)
1917 libs[liberties] = lib;
1918 liberties++;
1919 if (liberties >= maxlib)
1920 return liberties;
1921 MARK_LIBERTY(lib);
1922 }
1923 }
1924 }
1925
1926 if (UNMARKED_LIBERTY(WEST(pos))) {
1927 if (libs != NULL)
1928 libs[liberties] = WEST(pos);
1929 liberties++;
1930 /* Stop counting if we reach maxlib. */
1931 if (liberties >= maxlib)
1932 return liberties;
1933 MARK_LIBERTY(WEST(pos));
1934 }
1935 else if (board[WEST(pos)] == color) {
1936 int s = string_number[WEST(pos)];
1937 for (k = 0; k < string[s].liberties; k++) {
1938 int lib = string_libs[s].list[k];
1939 if (UNMARKED_LIBERTY(lib)) {
1940 if (libs != NULL)
1941 libs[liberties] = lib;
1942 liberties++;
1943 if (liberties >= maxlib)
1944 return liberties;
1945 MARK_LIBERTY(lib);
1946 }
1947 }
1948 }
1949
1950 if (UNMARKED_LIBERTY(NORTH(pos))) {
1951 if (libs != NULL)
1952 libs[liberties] = NORTH(pos);
1953 liberties++;
1954 /* Stop counting if we reach maxlib. */
1955 if (liberties >= maxlib)
1956 return liberties;
1957 MARK_LIBERTY(NORTH(pos));
1958 }
1959 else if (board[NORTH(pos)] == color) {
1960 int s = string_number[NORTH(pos)];
1961 for (k = 0; k < string[s].liberties; k++) {
1962 int lib = string_libs[s].list[k];
1963 if (UNMARKED_LIBERTY(lib)) {
1964 if (libs != NULL)
1965 libs[liberties] = lib;
1966 liberties++;
1967 if (liberties >= maxlib)
1968 return liberties;
1969 MARK_LIBERTY(lib);
1970 }
1971 }
1972 }
1973
1974 if (UNMARKED_LIBERTY(EAST(pos))) {
1975 if (libs != NULL)
1976 libs[liberties] = EAST(pos);
1977 liberties++;
1978 /* Unneeded since we're about to leave. */
1979#if 0
1980 if (liberties >= maxlib)
1981 return liberties;
1982 MARK_LIBERTY(EAST(pos));
1983#endif
1984 }
1985 else if (board[EAST(pos)] == color) {
1986 int s = string_number[EAST(pos)];
1987 for (k = 0; k < string[s].liberties; k++) {
1988 int lib = string_libs[s].list[k];
1989 if (UNMARKED_LIBERTY(lib)) {
1990 if (libs != NULL)
1991 libs[liberties] = lib;
1992 liberties++;
1993 if (liberties >= maxlib)
1994 return liberties;
1995 MARK_LIBERTY(lib);
1996 }
1997 }
1998 }
1999
2000#if USE_BOARD_CACHES
2001 /* If we reach here, then we have counted _all_ the liberties, so
2002 * we set threshold to MAXLIBS (the result is the same regardless
2003 * of `maxlib' value).
2004 */
2005 if (!libs)
2006 approxlib_cache[pos][color - 1].threshold = MAXLIBS;
2007#endif
2008 return liberties;
2009}
2010
2011
2012/* Find the liberties a move of the given color at pos would have,
2013 * excluding possible captures, by traversing all adjacent friendly
2014 * strings. This is a fallback used by approxlib() when a faster
2015 * algorithm can't be used.
2016 */
2017static int
2018slow_approxlib(int pos, int color, int maxlib, int *libs)
2019{
2020 int k;
2021 int liberties = 0;
2022
2023 liberty_mark++;
2024 MARK_LIBERTY(pos);
2025 string_mark++;
2026 for (k = 0; k < 4; k++) {
2027 int d = delta[k];
2028 if (UNMARKED_LIBERTY(pos + d)) {
2029 if (libs)
2030 libs[liberties] = pos + d;
2031 liberties++;
2032 if (liberties == maxlib)
2033 return liberties;
2034 MARK_LIBERTY(pos + d);
2035 }
2036 else if (board[pos + d] == color
2037 && UNMARKED_STRING(pos + d)) {
2038 int s = string_number[pos + d];
2039 int pos2;
2040 pos2 = FIRST_STONE(s);
2041 do {
2042 int l;
2043 for (l = 0; l < 4; l++) {
2044 int d2 = delta[l];
2045 if (UNMARKED_LIBERTY(pos2 + d2)) {
2046 if (libs)
2047 libs[liberties] = pos2 + d2;
2048 liberties++;
2049 if (liberties == maxlib)
2050 return liberties;
2051 MARK_LIBERTY(pos2 + d2);
2052 }
2053 }
2054
2055 pos2 = NEXT_STONE(pos2);
2056 } while (!BACK_TO_FIRST_STONE(s, pos2));
2057 MARK_STRING(pos + d);
2058 }
2059 }
2060
2061#if USE_BOARD_CACHES
2062 /* If we reach here, then we have counted _all_ the liberties, so
2063 * we set threshold to MAXLIBS (the result is the same regardless
2064 * of `maxlib' value).
2065 */
2066 if (!libs)
2067 approxlib_cache[pos][color - 1].threshold = MAXLIBS;
2068#endif
2069 return liberties;
2070}
2071
2072
2073/* accuratelib() cache. */
2074static struct board_cache_entry accuratelib_cache[BOARDMAX][2];
2075
2076
2077/* Clears accuratelib() cache. This function should be called only once
2078 * during engine initialization. Sets thresholds to zero.
2079 */
2080void
2081clear_accuratelib_cache(void)
2082{
2083 int pos;
2084
2085 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
2086 accuratelib_cache[pos][0].threshold = 0;
2087 accuratelib_cache[pos][1].threshold = 0;
2088 }
2089}
2090
2091
2092/* Find the liberties a stone of the given color would get if played
2093 * at (pos). This function takes into consideration all captures. Its
2094 * return value is exact in that sense it counts all the liberties,
2095 * unless (maxlib) allows it to stop earlier. (pos) must be empty. If
2096 * libs != NULL, the locations of up to maxlib liberties are written
2097 * into libs[]. The counting of liberties may or may not be halted
2098 * when maxlib is reached. The number of found liberties is returned.
2099 *
2100 * This function guarantees that liberties which are not results of
2101 * captures come first in libs[] array. To find whether all the
2102 * liberties starting from a given one are results of captures, one
2103 * may use if (board[libs[k]] != EMPTY) construction.
2104 *
2105 * If you want the number or the locations of all liberties, however
2106 * many they are, you should pass MAXLIBS as the value for maxlib and
2107 * allocate space for libs[] accordingly.
2108 */
2109int
2110accuratelib(int pos, int color, int maxlib, int *libs)
2111{
2112 int liberties;
2113
2114#ifdef USE_BOARD_CACHES
2115
2116 struct board_cache_entry *entry = &accuratelib_cache[pos][color - 1];
2117
2118 ASSERT1(board[pos] == EMPTY, pos);
2119 ASSERT1(IS_STONE(color), pos);
2120
2121 if (!libs) {
2122 /* First see if this result is cached. */
2123 if (hashdata_is_equal(board_hash, entry->position_hash)
2124 && maxlib <= entry->threshold) {
2125 return entry->liberties;
2126 }
2127
2128 liberties = fastlib(pos, color, 0);
2129 if (liberties >= 0) {
2130 /* Since fastlib() always returns precise result and doesn't take
2131 * `maxlib' into account, we set threshold to MAXLIBS so that this
2132 * result is used regardless of any `maxlib' passed.
2133 */
2134 entry->threshold = MAXLIBS;
2135 entry->liberties = liberties;
2136 entry->position_hash = board_hash;
2137
2138 return liberties;
2139 }
2140 }
2141
2142 liberties = do_accuratelib(pos, color, maxlib, libs);
2143
2144 /* If accuratelib() found less than `maxlib' liberties, then its
2145 * result is certainly independent of `maxlib' and we set threshold
2146 * to MAXLIBS.
2147 */
2148 entry->threshold = liberties < maxlib ? MAXLIBS : maxlib;
2149 entry->liberties = liberties;
2150 entry->position_hash = board_hash;
2151
2152#else /* not USE_BOARD_CACHES */
2153
2154 ASSERT1(board[pos] == EMPTY, pos);
2155 ASSERT1(IS_STONE(color), pos);
2156
2157 if (!libs) {
2158 liberties = fastlib(pos, color, 0);
2159 if (liberties >= 0)
2160 return liberties;
2161 }
2162
2163 liberties = do_accuratelib(pos, color, maxlib, libs);
2164
2165#endif /* not USE_BOARD_CACHES */
2166
2167 return liberties;
2168}
2169
2170
2171/* Does the real work of accuratelib(). */
2172static int
2173do_accuratelib(int pos, int color, int maxlib, int *libs)
2174{
2175 int k, l;
2176 int liberties = 0;
2177 int lib;
2178 int captured[4];
2179 int captures = 0;
2180
2181 string_mark++;
2182 liberty_mark++;
2183 MARK_LIBERTY(pos);
2184
2185 for (k = 0; k < 4; k++) {
2186 int pos2 = pos + delta[k];
2187 if (UNMARKED_LIBERTY(pos2)) {
2188 /* A trivial liberty */
2189 if (libs)
2190 libs[liberties] = pos2;
2191 liberties++;
2192 if (liberties >= maxlib)
2193 return liberties;
2194
2195 MARK_LIBERTY(pos2);
2196 }
2197 else if (UNMARKED_COLOR_STRING(pos2, color)) {
2198 /* An own neighbor string */
2199 struct string_data *s = &string[string_number[pos2]];
2200 struct string_liberties_data *sl = &string_libs[string_number[pos2]];
2201
2202 if (s->liberties <= MAX_LIBERTIES || maxlib <= MAX_LIBERTIES - 1) {
2203 /* The easy case - we already have all (necessary) liberties of
2204 * the string listed
2205 */
2206 for (l = 0; l < s->liberties; l++) {
2207 lib = sl->list[l];
2208 if (UNMARKED_LIBERTY(lib)) {
2209 if (libs)
2210 libs[liberties] = lib;
2211 liberties++;
2212 if (liberties >= maxlib)
2213 return liberties;
2214
2215 MARK_LIBERTY(lib);
2216 }
2217 }
2218 }
2219 else {
2220 /* The harder case - we need to find all the liberties of the
2221 * string by traversing its stones. We stop as soon as we have
2222 * traversed all the stones or have reached maxlib. Unfortunately,
2223 * we cannot use the trick from findlib() since some of the
2224 * liberties may already have been marked.
2225 */
2226 int stone = pos2;
2227 do {
2228 if (UNMARKED_LIBERTY(SOUTH(stone))) {
2229 if (libs)
2230 libs[liberties] = SOUTH(stone);
2231 liberties++;
2232 if (liberties >= maxlib)
2233 return liberties;
2234
2235 MARK_LIBERTY(SOUTH(stone));
2236 }
2237
2238 if (UNMARKED_LIBERTY(WEST(stone))) {
2239 if (libs)
2240 libs[liberties] = WEST(stone);
2241 liberties++;
2242 if (liberties >= maxlib)
2243 return liberties;
2244
2245 MARK_LIBERTY(WEST(stone));
2246 }
2247
2248 if (UNMARKED_LIBERTY(NORTH(stone))) {
2249 if (libs)
2250 libs[liberties] = NORTH(stone);
2251 liberties++;
2252 if (liberties >= maxlib)
2253 return liberties;
2254
2255 MARK_LIBERTY(NORTH(stone));
2256 }
2257
2258 if (UNMARKED_LIBERTY(EAST(stone))) {
2259 if (libs)
2260 libs[liberties] = EAST(stone);
2261 liberties++;
2262 if (liberties >= maxlib)
2263 return liberties;
2264
2265 MARK_LIBERTY(EAST(stone));
2266 }
2267
2268 stone = NEXT_STONE(stone);
2269 } while (stone != pos2);
2270 }
2271
2272 MARK_STRING(pos2);
2273 }
2274 else if (board[pos2] == OTHER_COLOR(color)
2275 && string[string_number[pos2]].liberties == 1) {
2276 /* A capture. */
2277 captured[captures++] = pos2;
2278 }
2279 }
2280
2281 /* Now we look at all the captures found in the previous step */
2282 for (k = 0; k < captures; k++) {
2283 lib = captured[k];
2284
2285 /* Add the stone adjacent to (pos) to the list of liberties if
2286 * it is not also adjacent to an own marked string (otherwise,
2287 * it will be added later).
2288 */
2289 if (!MARKED_COLOR_STRING(SOUTH(lib), color)
2290 && !MARKED_COLOR_STRING(WEST(lib), color)
2291 && !MARKED_COLOR_STRING(NORTH(lib), color)
2292 && !MARKED_COLOR_STRING(EAST(lib), color)) {
2293 if (libs)
2294 libs[liberties] = lib;
2295 liberties++;
2296 if (liberties >= maxlib)
2297 return liberties;
2298 }
2299
2300 /* Check if we already know of this capture. */
2301 for (l = 0; l < k; l++)
2302 if (string_number[captured[l]] == string_number[lib])
2303 break;
2304
2305 if (l == k) {
2306 /* Traverse all the stones of the capture and add to the list
2307 * of liberties those, which are adjacent to at least one own
2308 * marked string.
2309 */
2310 do {
2311 if (MARKED_COLOR_STRING(SOUTH(lib), color)
2312 || MARKED_COLOR_STRING(WEST(lib), color)
2313 || MARKED_COLOR_STRING(NORTH(lib), color)
2314 || MARKED_COLOR_STRING(EAST(lib), color)) {
2315 if (libs)
2316 libs[liberties] = lib;
2317 liberties++;
2318 if (liberties >= maxlib)
2319 return liberties;
2320 }
2321
2322 lib = NEXT_STONE(lib);
2323 } while (lib != captured[k]);
2324 }
2325 }
2326
2327 return liberties;
2328}
2329
2330
2331/* Find the number of common liberties of the two strings at str1 and str2.
2332 */
2333
2334int
2335count_common_libs(int str1, int str2)
2336{
2337 int all_libs1[MAXLIBS], *libs1;
2338 int liberties1, liberties2;
2339 int commonlibs = 0;
2340 int k, n, tmp;
2341
2342 ASSERT_ON_BOARD1(str1);
2343 ASSERT_ON_BOARD1(str2);
2344 ASSERT1(IS_STONE(board[str1]), str1);
2345 ASSERT1(IS_STONE(board[str2]), str2);
2346
2347 n = string_number[str1];
2348 liberties1 = string[n].liberties;
2349
2350 if (liberties1 > string[string_number[str2]].liberties) {
2351 n = string_number[str2];
2352 liberties1 = string[n].liberties;
2353 tmp = str1;
2354 str1 = str2;
2355 str2 = tmp;
2356 }
2357
2358 if (liberties1 <= MAX_LIBERTIES) {
2359 /* Speed optimization: don't copy liberties with findlib */
2360 libs1 = string_libs[n].list;
2361 n = string_number[str2];
2362 liberties2 = string[n].liberties;
2363
2364 if (liberties2 <= MAX_LIBERTIES) {
2365 /* Speed optimization: NEIGHBOR_OF_STRING is quite expensive */
2366 liberty_mark++;
2367
2368 for (k = 0; k < liberties1; k++)
2369 MARK_LIBERTY(libs1[k]);
2370
2371 libs1 = string_libs[n].list;
2372 for (k = 0; k < liberties2; k++)
2373 if (!UNMARKED_LIBERTY(libs1[k]))
2374 commonlibs++;
2375
2376 return commonlibs;
2377 }
2378 }
2379 else {
2380 findlib(str1, MAXLIBS, all_libs1);
2381 libs1 = all_libs1;
2382 }
2383
2384 for (k = 0; k < liberties1; k++)
2385 if (NEIGHBOR_OF_STRING(libs1[k], string_number[str2], board[str2]))
2386 commonlibs++;
2387
2388 return commonlibs;
2389}
2390
2391
2392/* Find the common liberties of the two strings at str1 and str2. The
2393 * locations of up to maxlib common liberties are written into libs[].
2394 * The full number of common liberties is returned.
2395 *
2396 * If you want the locations of all common liberties, whatever their
2397 * number, you should pass MAXLIBS as the value for maxlib and
2398 * allocate space for libs[] accordingly.
2399 */
2400
2401int
2402find_common_libs(int str1, int str2, int maxlib, int *libs)
2403{
2404 int all_libs1[MAXLIBS], *libs1;
2405 int liberties1, liberties2;
2406 int commonlibs = 0;
2407 int k, n, tmp;
2408
2409 ASSERT_ON_BOARD1(str1);
2410 ASSERT_ON_BOARD1(str2);
2411 ASSERT1(IS_STONE(board[str1]), str1);
2412 ASSERT1(IS_STONE(board[str2]), str2);
2413 ASSERT1(libs != NULL, str1);
2414
2415 n = string_number[str1];
2416 liberties1 = string[n].liberties;
2417
2418 if (liberties1 > string[string_number[str2]].liberties) {
2419 n = string_number[str2];
2420 liberties1 = string[n].liberties;
2421 tmp = str1;
2422 str1 = str2;
2423 str2 = tmp;
2424 }
2425
2426 if (liberties1 <= MAX_LIBERTIES) {
2427 /* Speed optimization: don't copy liberties with findlib */
2428 libs1 = string_libs[n].list;
2429 n = string_number[str2];
2430 liberties2 = string[n].liberties;
2431
2432 if (liberties2 <= MAX_LIBERTIES) {
2433 /* Speed optimization: NEIGHBOR_OF_STRING is quite expensive */
2434 liberty_mark++;
2435
2436 for (k = 0; k < liberties1; k++)
2437 MARK_LIBERTY(libs1[k]);
2438
2439 libs1 = string_libs[n].list;
2440 for (k = 0; k < liberties2; k++)
2441 if (!UNMARKED_LIBERTY(libs1[k])) {
2442 if (commonlibs < maxlib)
2443 libs[commonlibs] = libs1[k];
2444 commonlibs++;
2445 }
2446
2447 return commonlibs;
2448 }
2449 }
2450 else {
2451 findlib(str1, MAXLIBS, all_libs1);
2452 libs1 = all_libs1;
2453 }
2454
2455 for (k = 0; k < liberties1; k++)
2456 if (NEIGHBOR_OF_STRING(libs1[k], string_number[str2], board[str2])) {
2457 if (commonlibs < maxlib)
2458 libs[commonlibs] = libs1[k];
2459 commonlibs++;
2460 }
2461
2462 return commonlibs;
2463}
2464
2465
2466/* Determine whether two strings have at least one common liberty.
2467 * If they do and lib != NULL, one common liberty is returned in *lib.
2468 */
2469int
2470have_common_lib(int str1, int str2, int *lib)
2471{
2472 int all_libs1[MAXLIBS], *libs1;
2473 int liberties1;
2474 int k, n, tmp;
2475
2476 ASSERT_ON_BOARD1(str1);
2477 ASSERT_ON_BOARD1(str2);
2478 ASSERT1(IS_STONE(board[str1]), str1);
2479 ASSERT1(IS_STONE(board[str2]), str2);
2480
2481 n = string_number[str1];
2482 liberties1 = string[n].liberties;
2483
2484 if (liberties1 > string[string_number[str2]].liberties) {
2485 n = string_number[str2];
2486 liberties1 = string[n].liberties;
2487 tmp = str1;
2488 str1 = str2;
2489 str2 = tmp;
2490 }
2491
2492 if (liberties1 <= MAX_LIBERTIES)
2493 /* Speed optimization: don't copy liberties with findlib */
2494 libs1 = string_libs[n].list;
2495 else {
2496 findlib(str1, MAXLIBS, all_libs1);
2497 libs1 = all_libs1;
2498 }
2499
2500 for (k = 0; k < liberties1; k++) {
2501 if (NEIGHBOR_OF_STRING(libs1[k], string_number[str2], board[str2])) {
2502 if (lib)
2503 *lib = libs1[k];
2504 return 1;
2505 }
2506 }
2507
2508 return 0;
2509}
2510
2511
2512
2513/*
2514 * Report the number of stones in a string.
2515 */
2516
2517int
2518countstones(int str)
2519{
2520 ASSERT_ON_BOARD1(str);
2521 ASSERT1(IS_STONE(board[str]), str);
2522
2523 return COUNTSTONES(str);
2524}
2525
2526
2527/* Find the stones of the string at str. str must not be
2528 * empty. The locations of up to maxstones stones are written into
2529 * stones[]. The full number of stones is returned.
2530 */
2531
2532int
2533findstones(int str, int maxstones, int *stones)
2534{
2535 int s;
2536 int size;
2537 int pos;
2538 int k;
2539
2540 ASSERT_ON_BOARD1(str);
2541 ASSERT1(IS_STONE(board[str]), str);
2542
2543 s = string_number[str];
2544 size = string[s].size;
2545
2546 /* Traverse the stones of the string, by following the cyclic chain. */
2547 pos = FIRST_STONE(s);
2548 for (k = 0; k < maxstones && k < size; k++) {
2549 stones[k] = pos;
2550 pos = NEXT_STONE(pos);
2551 }
2552
2553 return size;
2554}
2555
2556
2557/* Counts how many stones in str1 are directly adjacent to str2.
2558 * A limit can be given in the maxstones parameter so that the
2559 * function returns immediately. See fast_defense() in reading.c
2560 */
2561
2562int
2563count_adjacent_stones(int str1, int str2, int maxstones)
2564{
2565 int s1, s2;
2566 int size;
2567 int pos;
2568 int k;
2569 int count = 0;
2570
2571 ASSERT_ON_BOARD1(str1);
2572 ASSERT1(IS_STONE(board[str1]), str1);
2573 ASSERT_ON_BOARD1(str2);
2574 ASSERT1(IS_STONE(board[str2]), str2);
2575
2576 s1 = string_number[str1];
2577 s2 = string_number[str2];
2578 size = string[s1].size;
2579
2580 /* Traverse the stones of the string, by following the cyclic chain. */
2581 pos = FIRST_STONE(s1);
2582 for (k = 0; k < size && count < maxstones; k++) {
2583 if (NEIGHBOR_OF_STRING(pos, s2, board[str2]))
2584 count++;
2585 pos = NEXT_STONE(pos);
2586 }
2587
2588 return count;
2589}
2590
2591
2592/* chainlinks returns (in the (adj) array) the chains surrounding
2593 * the string at (str). The number of chains is returned.
2594 */
2595
2596int
2597chainlinks(int str, int adj[MAXCHAIN])
2598{
2599 struct string_data *s;
2600 struct string_neighbors_data *sn;
2601 int k;
2602
2603 ASSERT1(IS_STONE(board[str]), str);
2604
2605 /* We already have the list ready, just copy it and fill in the
2606 * desired information.
2607 */
2608 s = &string[string_number[str]];
2609 sn = &string_neighbors[string_number[str]];
2610 for (k = 0; k < s->neighbors; k++)
2611 adj[k] = string[sn->list[k]].origin;
2612
2613 return s->neighbors;
2614}
2615
2616
2617/* chainlinks2 returns (in adj array) those chains surrounding
2618 * the string at str which have exactly lib liberties. The number
2619 * of such chains is returned.
2620 */
2621
2622int
2623chainlinks2(int str, int adj[MAXCHAIN], int lib)
2624{
2625 struct string_data *s, *t;
2626 struct string_neighbors_data *sn;
2627 int k;
2628 int neighbors;
2629
2630 ASSERT1(IS_STONE(board[str]), str);
2631
2632 /* We already have the list ready, just copy the strings with the
2633 * right number of liberties.
2634 */
2635 neighbors = 0;
2636 s = &string[string_number[str]];
2637 sn = &string_neighbors[string_number[str]];
2638 for (k = 0; k < s->neighbors; k++) {
2639 t = &string[sn->list[k]];
2640 if (t->liberties == lib)
2641 adj[neighbors++] = t->origin;
2642 }
2643 return neighbors;
2644}
2645
2646
2647/* chainlinks3 returns (in adj array) those chains surrounding
2648 * the string at str, which have less or equal lib liberties.
2649 * The number of such chains is returned.
2650 */
2651
2652int
2653chainlinks3(int str, int adj[MAXCHAIN], int lib)
2654{
2655 struct string_data *s, *t;
2656 struct string_neighbors_data *sn;
2657 int k;
2658 int neighbors;
2659
2660 ASSERT1(IS_STONE(board[str]), str);
2661
2662 /* We already have the list ready, just copy the strings with the
2663 * right number of liberties.
2664 */
2665 neighbors = 0;
2666 s = &string[string_number[str]];
2667 sn = &string_neighbors[string_number[str]];
2668 for (k = 0; k < s->neighbors; k++) {
2669 t = &string[sn->list[k]];
2670 if (t->liberties <= lib)
2671 adj[neighbors++] = t->origin;
2672 }
2673 return neighbors;
2674}
2675
2676
2677/* extended_chainlinks() returns (in the (adj) array) the opponent
2678 * strings being directly adjacent to (str) or having a common liberty
2679 * with (str). The number of such strings is returned.
2680 *
2681 * If the both_colors parameter is true, also own strings sharing a
2682 * liberty are returned.
2683 */
2684
2685int
2686extended_chainlinks(int str, int adj[MAXCHAIN], int both_colors)
2687{
2688 struct string_data *s;
2689 struct string_neighbors_data *sn;
2690 int n;
2691 int k;
2692 int r;
2693 int libs[MAXLIBS];
2694 int liberties;
2695
2696 ASSERT1(IS_STONE(board[str]), str);
2697
2698 /* We already have the list of directly adjacent strings ready, just
2699 * copy it and mark the strings.
2700 */
2701 s = &string[string_number[str]];
2702 sn = &string_neighbors[string_number[str]];
2703 string_mark++;
2704 for (n = 0; n < s->neighbors; n++) {
2705 adj[n] = string[sn->list[n]].origin;
2706 MARK_STRING(adj[n]);
2707 }
2708
2709 /* Get the liberties. */
2710 liberties = findlib(str, MAXLIBS, libs);
2711
2712 /* Look for unmarked opponent strings next to a liberty and add the
2713 * ones which are found to the output.
2714 */
2715 for (r = 0; r < liberties; r++) {
2716 for (k = 0; k < 4; k++) {
2717 if ((board[libs[r] + delta[k]] == OTHER_COLOR(board[str])
2718 || (both_colors && board[libs[r] + delta[k]] == board[str]))
2719 && UNMARKED_STRING(libs[r] + delta[k])) {
2720 adj[n] = string[string_number[libs[r] + delta[k]]].origin;
2721 MARK_STRING(adj[n]);
2722 n++;
2723 }
2724 }
2725 }
2726
2727 return n;
2728}
2729
2730
2731/* Returns true if a move by (color) fits a shape like:
2732 *
2733 * -----
2734 * O.O*X (O=color)
2735 * OOXXX
2736 *
2737 * More specifically the move should have the following properties:
2738 * - The move is a self-atari
2739 * - The move forms a string of exactly two stones
2740 * - When the opponent captures, the capturing stone becomes a single
2741 * stone in atari
2742 * - When capturing back the original position is repeated
2743 */
2744
2745int
2746send_two_return_one(int move, int color)
2747{
2748 int other = OTHER_COLOR(color);
2749 int lib = NO_MOVE;
2750 int friendly_neighbor = NO_MOVE;
2751 int k;
2752
2753 ASSERT1(board[move] == EMPTY, move);
2754
2755 for (k = 0; k < 4; k++) {
2756 int pos = move + delta[k];
2757 if (board[pos] == EMPTY)
2758 return 0;
2759 if (board[pos] == color) {
2760 int s;
2761 if (friendly_neighbor != NO_MOVE)
2762 return 0;
2763 friendly_neighbor = pos;
2764 s = string_number[pos];
2765 if (string[s].size != 1 || string[s].liberties != 2)
2766 return 0;
2767 lib = string_libs[s].list[0] + string_libs[s].list[1] - move;
2768 }
2769 else if (board[pos] == other
2770 && string[string_number[pos]].liberties == 1)
2771 return 0;
2772 }
2773
2774 if (friendly_neighbor == NO_MOVE)
2775 return 0;
2776
2777 for (k = 0; k < 4; k++) {
2778 int pos = lib + delta[k];
2779 if (board[pos] == EMPTY || board[pos] == other)
2780 return 0;
2781 if (board[pos] == color &&
2782 string[string_number[pos]].liberties < 2)
2783 return 0;
2784 }
2785
2786 return 1;
2787}
2788
2789
2790/*
2791 * Find the origin of a worm, i.e. the point with the
2792 * smallest 1D board coordinate. The idea is to have a canonical
2793 * reference point for a string.
2794 */
2795
2796int
2797find_origin(int str)
2798{
2799 ASSERT1(IS_STONE(board[str]), str);
2800
2801 return string[string_number[str]].origin;
2802}
2803
2804
2805/* Determine whether a move by color at (pos) would be a self atari,
2806 * i.e. whether it would get more than one liberty. This function
2807 * returns true also for the case of a suicide move.
2808 */
2809
2810int
2811is_self_atari(int pos, int color)
2812{
2813 int other = OTHER_COLOR(color);
2814 /* number of empty neighbors */
2815 int trivial_liberties = 0;
2816 /* number of captured opponent strings */
2817 int captures = 0;
2818 /* Whether there is a friendly neighbor with a spare liberty. If it
2819 * has more than one spare liberty we immediately return 0.
2820 */
2821 int far_liberties = 0;
2822
2823 ASSERT_ON_BOARD1(pos);
2824 ASSERT1(board[pos] == EMPTY, pos);
2825 ASSERT1(IS_STONE(color), pos);
2826
2827 /* 1. Try first to solve the problem without much work. */
2828 string_mark++;
2829
2830 if (LIBERTY(SOUTH(pos)))
2831 trivial_liberties++;
2832 else if (board[SOUTH(pos)] == color) {
2833 if (LIBERTIES(SOUTH(pos)) > 2)
2834 return 0;
2835 if (LIBERTIES(SOUTH(pos)) == 2)
2836 far_liberties++;
2837 }
2838 else if (board[SOUTH(pos)] == other
2839 && LIBERTIES(SOUTH(pos)) == 1 && UNMARKED_STRING(SOUTH(pos))) {
2840 captures++;
2841 MARK_STRING(SOUTH(pos));
2842 }
2843
2844 if (LIBERTY(WEST(pos)))
2845 trivial_liberties++;
2846 else if (board[WEST(pos)] == color) {
2847 if (LIBERTIES(WEST(pos)) > 2)
2848 return 0;
2849 if (LIBERTIES(WEST(pos)) == 2)
2850 far_liberties++;
2851 }
2852 else if (board[WEST(pos)] == other
2853 && LIBERTIES(WEST(pos)) == 1 && UNMARKED_STRING(WEST(pos))) {
2854 captures++;
2855 MARK_STRING(WEST(pos));
2856 }
2857
2858 if (LIBERTY(NORTH(pos)))
2859 trivial_liberties++;
2860 else if (board[NORTH(pos)] == color) {
2861 if (LIBERTIES(NORTH(pos)) > 2)
2862 return 0;
2863 if (LIBERTIES(NORTH(pos)) == 2)
2864 far_liberties++;
2865 }
2866 else if (board[NORTH(pos)] == other
2867 && LIBERTIES(NORTH(pos)) == 1 && UNMARKED_STRING(NORTH(pos))) {
2868 captures++;
2869 MARK_STRING(NORTH(pos));
2870 }
2871
2872 if (LIBERTY(EAST(pos)))
2873 trivial_liberties++;
2874 else if (board[EAST(pos)] == color) {
2875 if (LIBERTIES(EAST(pos)) > 2)
2876 return 0;
2877 if (LIBERTIES(EAST(pos)) == 2)
2878 far_liberties++;
2879 }
2880 else if (board[EAST(pos)] == other
2881 && LIBERTIES(EAST(pos)) == 1 && UNMARKED_STRING(EAST(pos))) {
2882 captures++;
2883#if 0
2884 MARK_STRING(EAST(pos));
2885#endif
2886 }
2887
2888 /* Each captured string is guaranteed to produce at least one
2889 * liberty. These are disjoint from both trivial liberties and far
2890 * liberties. The two latter may however coincide.
2891 */
2892 if (trivial_liberties + captures >= 2)
2893 return 0;
2894
2895 if ((far_liberties > 0) + captures >= 2)
2896 return 0;
2897
2898 if (captures == 0 && far_liberties + trivial_liberties <= 1)
2899 return 1;
2900
2901 /* 2. It was not so easy. We use accuratelib() in this case. */
2902 return accuratelib(pos, color, 2, NULL) <= 1;
2903}
2904
2905
2906/*
2907 * Returns true if pos is a liberty of the string at str.
2908 */
2909
2910int
2911liberty_of_string(int pos, int str)
2912{
2913 ASSERT_ON_BOARD1(pos);
2914 ASSERT_ON_BOARD1(str);
2915 if (IS_STONE(board[pos]))
2916 return 0;
2917
2918 return NEIGHBOR_OF_STRING(pos, string_number[str], board[str]);
2919}
2920
2921
2922/*
2923 * Returns true if pos is a second order liberty of the string at str.
2924 */
2925int
2926second_order_liberty_of_string(int pos, int str)
2927{
2928 int k;
2929 ASSERT_ON_BOARD1(pos);
2930 ASSERT_ON_BOARD1(str);
2931
2932 for (k = 0; k < 4; k++)
2933 if (board[pos + delta[k]] == EMPTY
2934 && NEIGHBOR_OF_STRING(pos + delta[k], string_number[str], board[str]))
2935 return 1;
2936
2937 return 0;
2938}
2939
2940
2941/*
2942 * Returns true if pos is adjacent to the string at str.
2943 */
2944
2945int
2946neighbor_of_string(int pos, int str)
2947{
2948 int color = board[str];
2949
2950 ASSERT1(IS_STONE(color), str);
2951 ASSERT_ON_BOARD1(pos);
2952
2953 return NEIGHBOR_OF_STRING(pos, string_number[str], color);
2954}
2955
2956/*
2957 * Returns true if (pos) has a neighbor of color (color).
2958 */
2959
2960int
2961has_neighbor(int pos, int color)
2962{
2963 ASSERT_ON_BOARD1(pos);
2964 ASSERT1(IS_STONE(color), pos);
2965
2966 return (board[SOUTH(pos)] == color
2967 || board[WEST(pos)] == color
2968 || board[NORTH(pos)] == color
2969 || board[EAST(pos)] == color);
2970}
2971
2972/*
2973 * Returns true if str1 and str2 belong to the same string.
2974 */
2975
2976int
2977same_string(int str1, int str2)
2978{
2979 ASSERT_ON_BOARD1(str1);
2980 ASSERT_ON_BOARD1(str2);
2981 ASSERT1(IS_STONE(board[str1]), str1);
2982 ASSERT1(IS_STONE(board[str2]), str2);
2983
2984 return string_number[str1] == string_number[str2];
2985}
2986
2987
2988/*
2989 * Returns true if the strings at str1 and str2 are adjacent.
2990 */
2991
2992int
2993adjacent_strings(int str1, int str2)
2994{
2995 int s1, s2;
2996 int k;
2997
2998 ASSERT_ON_BOARD1(str1);
2999 ASSERT_ON_BOARD1(str2);
3000 ASSERT1(IS_STONE(board[str1]), str1);
3001 ASSERT1(IS_STONE(board[str2]), str2);
3002
3003 s1 = string_number[str1];
3004 s2 = string_number[str2];
3005
3006 for (k = 0; k < string[s1].neighbors; k++)
3007 if (string_neighbors[s1].list[k] == s2)
3008 return 1;
3009
3010 return 0;
3011}
3012
3013
3014/*
3015 * Return true if the move (pos) by (color) is a ko capture
3016 * (whether capture is legal on this move or not). If so,
3017 * and if ko_pos is not a NULL pointer, then
3018 * *ko_pos returns the location of the captured ko stone.
3019 * If the move is not a ko capture, *ko_pos is set to 0.
3020 *
3021 * A move is a ko capture if and only if
3022 * 1. All neighbors are opponent stones.
3023 * 2. The number of captured stones is exactly one.
3024 */
3025
3026int
3027is_ko(int pos, int color, int *ko_pos)
3028{
3029 int other = OTHER_COLOR(color);
3030 int captures = 0;
3031 int kpos = 0;
3032
3033 ASSERT_ON_BOARD1(pos);
3034 ASSERT1(color == WHITE || color == BLACK, pos);
3035
3036 if (ON_BOARD(SOUTH(pos))) {
3037 if (board[SOUTH(pos)] != other)
3038 return 0;
3039 else if (LIBERTIES(SOUTH(pos)) == 1) {
3040 kpos = SOUTH(pos);
3041 captures += string[string_number[SOUTH(pos)]].size;
3042 if (captures > 1)
3043 return 0;
3044 }
3045 }
3046
3047 if (ON_BOARD(WEST(pos))) {
3048 if (board[WEST(pos)] != other)
3049 return 0;
3050 else if (LIBERTIES(WEST(pos)) == 1) {
3051 kpos = WEST(pos);
3052 captures += string[string_number[WEST(pos)]].size;
3053 if (captures > 1)
3054 return 0;
3055 }
3056 }
3057
3058 if (ON_BOARD(NORTH(pos))) {
3059 if (board[NORTH(pos)] != other)
3060 return 0;
3061 else if (LIBERTIES(NORTH(pos)) == 1) {
3062 kpos = NORTH(pos);
3063 captures += string[string_number[NORTH(pos)]].size;
3064 if (captures > 1)
3065 return 0;
3066 }
3067 }
3068
3069 if (ON_BOARD(EAST(pos))) {
3070 if (board[EAST(pos)] != other)
3071 return 0;
3072 else if (LIBERTIES(EAST(pos)) == 1) {
3073 kpos = EAST(pos);
3074 captures += string[string_number[EAST(pos)]].size;
3075 if (captures > 1)
3076 return 0;
3077 }
3078 }
3079
3080 if (captures == 1) {
3081 if (ko_pos)
3082 *ko_pos = kpos;
3083 return 1;
3084 }
3085 return 0;
3086}
3087
3088
3089/* Return true if pos is either a stone, which if captured would give
3090 * ko, or if pos is an empty intersection adjacent to a ko stone.
3091 */
3092int
3093is_ko_point(int pos)
3094{
3095 ASSERT_ON_BOARD1(pos);
3096
3097 if (board[pos] == EMPTY) {
3098 int color;
3099 if (ON_BOARD(SOUTH(pos)))
3100 color = board[SOUTH(pos)];
3101 else
3102 color = board[NORTH(pos)];
3103 if (IS_STONE(color) && is_ko(pos, OTHER_COLOR(color), NULL))
3104 return 1;
3105 }
3106 else {
3107 struct string_data *s = &string[string_number[pos]];
3108 struct string_liberties_data *sl = &string_libs[string_number[pos]];
3109 if (s->liberties == 1 && s->size == 1
3110 && is_ko(sl->list[0], OTHER_COLOR(s->color), NULL))
3111 return 1;
3112 }
3113
3114 return 0;
3115}
3116
3117
3118/* Return true if a move by color at pos is a superko violation
3119 * according to the specified type of ko rules. This function does not
3120 * detect simple ko unless it's also a superko violation.
3121 *
3122 * The superko detection is done by comparing board hashes from
3123 * previous positions. For this to work correctly it's necessary to
3124 * remove the contribution to the hash from the simple ko position.
3125 * The move_history_hash array contains board hashes for previous
3126 * positions, also without simple ko position contributions.
3127 */
3128static int
3129is_superko_violation(int pos, int color, enum ko_rules type)
3130{
3131 Hash_data this_board_hash = board_hash;
3132 Hash_data new_board_hash;
3133 int k;
3134
3135 /* No superko violations if the ko rule is not a superko rule. */
3136 if (type == NONE || type == SIMPLE)
3137 return 0;
3138
3139 if (board_ko_pos != NO_MOVE)
3140 hashdata_invert_ko(&this_board_hash, board_ko_pos);
3141
3142 really_do_trymove(pos, color);
3143 new_board_hash = board_hash;
3144 if (board_ko_pos != NO_MOVE)
3145 hashdata_invert_ko(&new_board_hash, board_ko_pos);
3146 undo_trymove();
3147
3148 /* The current position is only a problem with positional superko
3149 * and a single stone suicide.
3150 */
3151 if (type == PSK && hashdata_is_equal(this_board_hash, new_board_hash))
3152 return 1;
3153
3154 for (k = move_history_pointer - 1; k >= 0; k--)
3155 if (hashdata_is_equal(move_history_hash[k], new_board_hash)
3156 && (type == PSK
3157 || move_history_color[k] == OTHER_COLOR(color)))
3158 return 1;
3159
3160 return 0;
3161}
3162
3163/* Returns 1 if at least one string is captured when color plays at pos.
3164 */
3165int
3166does_capture_something(int pos, int color)
3167{
3168 int other = OTHER_COLOR(color);
3169
3170 ASSERT1(board[pos] == EMPTY, pos);
3171
3172 if (board[SOUTH(pos)] == other && LIBERTIES(SOUTH(pos)) == 1)
3173 return 1;
3174
3175 if (board[WEST(pos)] == other && LIBERTIES(WEST(pos)) == 1)
3176 return 1;
3177
3178 if (board[NORTH(pos)] == other && LIBERTIES(NORTH(pos)) == 1)
3179 return 1;
3180
3181 if (board[EAST(pos)] == other && LIBERTIES(EAST(pos)) == 1)
3182 return 1;
3183
3184 return 0;
3185}
3186
3187
3188/* For each stone in the string at pos, set mx to value mark. */
3189void
3190mark_string(int str, signed char mx[BOARDMAX], signed char mark)
3191{
3192 int pos = str;
3193
3194 ASSERT1(IS_STONE(board[str]), str);
3195
3196 do {
3197 mx[pos] = mark;
3198 pos = NEXT_STONE(pos);
3199 } while (pos != str);
3200}
3201
3202
3203/* Returns true if at least one move has been played at pos
3204 * at deeper than level 'cutoff' in the reading tree.
3205 */
3206int
3207move_in_stack(int pos, int cutoff)
3208{
3209 int k;
3210 for (k = cutoff; k < stackp; k++)
3211 if (stack[k] == pos)
3212 return 1;
3213
3214 return 0;
3215}
3216
3217
3218/* Retrieve a move from the move stack. */
3219void
3220get_move_from_stack(int k, int *move, int *color)
3221{
3222 gg_assert(k < stackp);
3223 *move = stack[k];
3224 *color = move_color[k];
3225}
3226
3227/* Return the number of stones of the indicated color(s) on the board.
3228 * This only counts stones in the permanent position, not stones placed
3229 * by trymove() or tryko(). Use stones_on_board(BLACK | WHITE) to get
3230 * the total number of stones on the board.
3231 *
3232 * FIXME: This seems wrong, it uses the modified board, not the permanent
3233 * one. /ab
3234 */
3235int
3236stones_on_board(int color)
3237{
3238 static int stone_count_for_position = -1;
3239 static int white_stones = 0;
3240 static int black_stones = 0;
3241
3242 gg_assert(stackp == 0);
3243
3244 if (stone_count_for_position != position_number) {
3245 int pos;
3246 white_stones = 0;
3247 black_stones = 0;
3248 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
3249 if (board[pos] == WHITE)
3250 white_stones++;
3251 else if (board[pos] == BLACK)
3252 black_stones++;
3253 }
3254
3255 stone_count_for_position = position_number;
3256 }
3257
3258 return ((color & BLACK ? black_stones : 0) +
3259 (color & WHITE ? white_stones : 0));
3260}
3261
3262
3263/* ===================== Statistics ============================= */
3264
3265
3266/* Clear statistics. */
3267void
3268reset_trymove_counter()
3269{
3270 trymove_counter = 0;
3271}
3272
3273
3274/* Retrieve statistics. */
3275int
3276get_trymove_counter()
3277{
3278 return trymove_counter;
3279}
3280
3281
3282/* ================================================================ */
3283/* Lower level functions */
3284/* ================================================================ */
3285
3286
3287/* This function should be called if the board is modified by other
3288 * means than do_play_move() or undo_trymove().
3289 *
3290 * We have reached a new position. Increase the position counter and
3291 * re-initialize the incremental strings.
3292 *
3293 * Set up incremental board structures and populate them with the
3294 * strings available in the position given by board[]. Clear the stacks
3295 * and start the mark numbers from zero. All undo information is lost
3296 * by calling this function.
3297 */
3298
3299static void
3300new_position(void)
3301{
3302 int pos;
3303 int s;
3304
3305 position_number++;
3306 next_string = 0;
3307 liberty_mark = 0;
3308 string_mark = 0;
3309 CLEAR_STACKS();
3310
3311 memset(string, 0, sizeof(string));
3312 memset(string_libs, 0, sizeof(string_libs));
3313 memset(string_neighbors, 0, sizeof(string_neighbors));
3314 memset(ml, 0, sizeof(ml));
3315 VALGRIND_MAKE_WRITABLE(next_stone, sizeof(next_stone));
3316
3317 /* propagate_string relies on non-assigned stones to have
3318 * string_number -1.
3319 */
3320 for (pos = BOARDMIN; pos < BOARDMAX; pos++)
3321 if (ON_BOARD(pos))
3322 string_number[pos] = -1;
3323
3324 /* Find the existing strings. */
3325 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
3326 if (!ON_BOARD(pos))
3327 continue;
3328 if (IS_STONE(board[pos]) && string_number[pos] == -1) {
3329 string_number[pos] = next_string;
3330 string[next_string].size = propagate_string(pos, pos);
3331 string[next_string].color = board[pos];
3332 string[next_string].origin = pos;
3333 string[next_string].mark = 0;
3334 next_string++;
3335 PARANOID1(next_string < MAX_STRINGS, pos);
3336 }
3337 }
3338
3339 /* Fill in liberty and neighbor info. */
3340 for (s = 0; s < next_string; s++) {
3341 find_liberties_and_neighbors(s);
3342 }
3343}
3344
3345
3346#if 0
3347
3348/*
3349 * Debug function. Dump all string information.
3350 */
3351
3352static void
3353dump_incremental_board(void)
3354{
3355 int pos;
3356 int s;
3357 int i;
3358
3359 for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
3360 if (!ON_BOARD(pos))
3361 continue;
3362 if (board[pos] == EMPTY)
3363 fprintf(stderr, " . ");
3364 else
3365 fprintf(stderr, "%2d ", string_number[pos]);
3366 fprintf(stderr, "\n");
3367 }
3368
3369 for (s = 0; s < next_string; s++) {
3370 if (board[string[s].origin] == EMPTY)
3371 continue;
3372
3373 gprintf("%o%d %s %1m size %d, %d liberties, %d neighbors\n", s,
3374 color_to_string(string[s].color),
3375 string[s].origin, string[s].size,
3376 string[s].liberties, string[s].neighbors);
3377 gprintf("%ostones:");
3378
3379 pos = FIRST_STONE(s);
3380 do {
3381 gprintf("%o %1m", pos);
3382 pos = NEXT_STONE(pos);
3383 } while (!BACK_TO_FIRST_STONE(s, pos));
3384
3385 gprintf("%o\nliberties:");
3386 for (i = 0; i < string[s].liberties; i++)
3387 gprintf("%o %1m", string[s].libs[i]);
3388
3389 gprintf("%o\nneighbors:");
3390 for (i = 0; i < string[s].neighbors; i++)
3391 gprintf("%o %d(%1m)", string[s].neighborlist[i],
3392 string[string[s].neighborlist[i]].origin);
3393 gprintf("%o\n\n");
3394 }
3395}
3396#endif
3397
3398
3399/* Build a string and its cyclic list representation from scratch.
3400 * propagate_string(stone, str) adds the stone (stone) to the string
3401 * (str) and recursively continues with not already included friendly
3402 * neighbors. To start a new string at (stone), use
3403 * propagate_string(stone, stone). The size of the string is returned.
3404 */
3405
3406static int
3407propagate_string(int stone, int str)
3408{
3409 int size = 1;
3410 int k;
3411
3412 if (stone == str) {
3413 /* Start a new string. */
3414 next_stone[stone] = stone;
3415 }
3416 else {
3417 /* Link the stone at (stone) to the string including (str) */
3418 string_number[stone] = string_number[str];
3419 next_stone[stone] = next_stone[str];
3420 next_stone[str] = stone;
3421 }
3422
3423 /* Look in all four directions for more stones to add. */
3424 for (k = 0; k < 4; k++) {
3425 int d = delta[k];
3426 if (ON_BOARD(stone + d)
3427 && board[stone + d] == board[stone]
3428 && string_number[stone + d] == -1)
3429 size += propagate_string(stone + d, str);
3430 }
3431
3432 return size;
3433}
3434
3435
3436/* Build the lists of liberties and neighbors of a string from
3437 * scratch. No information is pushed onto the stack by this function.
3438 */
3439
3440static void
3441find_liberties_and_neighbors(int s)
3442{
3443 int pos;
3444 int other = OTHER_COLOR(string[s].color);
3445
3446 /* Clear the marks. */
3447 liberty_mark++;
3448 string_mark++;
3449
3450 /* Traverse the stones of the string, by following the cyclic chain. */
3451 pos = FIRST_STONE(s);
3452 do {
3453 /* Look in each direction for new liberties or new neighbors. Mark
3454 * already visited liberties and neighbors.
3455 */
3456 if (UNMARKED_LIBERTY(SOUTH(pos))) {
3457 ADD_AND_MARK_LIBERTY(s, SOUTH(pos));
3458 }
3459 else if (UNMARKED_COLOR_STRING(SOUTH(pos), other)) {
3460 ADD_NEIGHBOR(s, SOUTH(pos));
3461 MARK_STRING(SOUTH(pos));
3462 }
3463
3464 if (UNMARKED_LIBERTY(WEST(pos))) {
3465 ADD_AND_MARK_LIBERTY(s, WEST(pos));
3466 }
3467 else if (UNMARKED_COLOR_STRING(WEST(pos), other)) {
3468 ADD_NEIGHBOR(s, WEST(pos));
3469 MARK_STRING(WEST(pos));
3470 }
3471
3472 if (UNMARKED_LIBERTY(NORTH(pos))) {
3473 ADD_AND_MARK_LIBERTY(s, NORTH(pos));
3474 }
3475 else if (UNMARKED_COLOR_STRING(NORTH(pos), other)) {
3476 ADD_NEIGHBOR(s, NORTH(pos));
3477 MARK_STRING(NORTH(pos));
3478 }
3479
3480 if (UNMARKED_LIBERTY(EAST(pos))) {
3481 ADD_AND_MARK_LIBERTY(s, EAST(pos));
3482 }
3483 else if (UNMARKED_COLOR_STRING(EAST(pos), other)) {
3484 ADD_NEIGHBOR(s, EAST(pos));
3485 MARK_STRING(EAST(pos));
3486 }
3487
3488 pos = NEXT_STONE(pos);
3489 } while (!BACK_TO_FIRST_STONE(s, pos));
3490}
3491
3492
3493/* Update the liberties of a string from scratch, first pushing the
3494 * old information.
3495 */
3496
3497static void
3498update_liberties(int s)
3499{
3500 int pos;
3501 int k;
3502
3503 /* Push the old information. */
3504 PUSH_VALUE(string[s].liberties);
3505 for (k = 0; k < string[s].liberties && k < MAX_LIBERTIES; k++) {
3506 PUSH_VALUE(string_libs[s].list[k]);
3507 }
3508 string[s].liberties = 0;
3509
3510 /* Clear the liberty mark. */
3511 liberty_mark++;
3512
3513 /* Traverse the stones of the string, by following the cyclic chain. */
3514 pos = FIRST_STONE(s);
3515 do {
3516 /* Look in each direction for new liberties. Mark already visited
3517 * liberties.
3518 */
3519 if (UNMARKED_LIBERTY(SOUTH(pos))) {
3520 ADD_AND_MARK_LIBERTY(s, SOUTH(pos));
3521 }
3522
3523 if (UNMARKED_LIBERTY(WEST(pos))) {
3524 ADD_AND_MARK_LIBERTY(s, WEST(pos));
3525 }
3526
3527 if (UNMARKED_LIBERTY(NORTH(pos))) {
3528 ADD_AND_MARK_LIBERTY(s, NORTH(pos));
3529 }
3530
3531 if (UNMARKED_LIBERTY(EAST(pos))) {
3532 ADD_AND_MARK_LIBERTY(s, EAST(pos));
3533 }
3534
3535 pos = NEXT_STONE(pos);
3536 } while (!BACK_TO_FIRST_STONE(s, pos));
3537}
3538
3539
3540/* Remove a string from the list of neighbors and push the changed
3541 * information.
3542 */
3543
3544static void
3545remove_neighbor(int str_number, int n)
3546{
3547 int k;
3548 int done = 0;
3549 struct string_data *s = &string[str_number];
3550 struct string_neighbors_data *sn = &string_neighbors[str_number];
3551 for (k = 0; k < s->neighbors; k++)
3552 if (sn->list[k] == n) {
3553 /* We need to push the last entry too because it may become
3554 * destroyed later.
3555 */
3556 PUSH_VALUE(sn->list[s->neighbors - 1]);
3557 PUSH_VALUE(sn->list[k]);
3558 PUSH_VALUE(s->neighbors);
3559 sn->list[k] = sn->list[s->neighbors - 1];
3560 s->neighbors--;
3561 done = 1;
3562 break;
3563 }
3564 gg_assert(done);
3565}
3566
3567
3568/* Remove one liberty from the list of liberties, pushing changed
3569 * information. If the string had more liberties than the size of the
3570 * list, rebuild the list from scratch.
3571 */
3572
3573static void
3574remove_liberty(int str_number, int pos)
3575{
3576 int k;
3577 struct string_data *s = &string[str_number];
3578 struct string_liberties_data *sl = &string_libs[str_number];
3579
3580 if (s->liberties > MAX_LIBERTIES)
3581 update_liberties(str_number);
3582 else {
3583 for (k = 0; k < s->liberties; k++)
3584 if (sl->list[k] == pos) {
3585 /* We need to push the last entry too because it may become
3586 * destroyed later.
3587 */
3588 PUSH_VALUE(sl->list[s->liberties - 1]);
3589 PUSH_VALUE(sl->list[k]);
3590 PUSH_VALUE(s->liberties);
3591 sl->list[k] = sl->list[s->liberties - 1];
3592 s->liberties--;
3593 break;
3594 }
3595 }
3596}
3597
3598
3599/* Remove a string from the board, pushing necessary information to
3600 * restore it. Return the number of removed stones.
3601 */
3602
3603static int
3604do_remove_string(int s)
3605{
3606 int pos;
3607 int k;
3608 int size = string[s].size;
3609
3610 /* Traverse the stones of the string, by following the cyclic chain. */
3611 pos = FIRST_STONE(s);
3612 do {
3613 /* Push color, string number and cyclic chain pointers. */
3614 PUSH_VALUE(string_number[pos]);
3615 PUSH_VALUE(next_stone[pos]);
3616 DO_REMOVE_STONE(pos);
3617 pos = NEXT_STONE(pos);
3618 } while (!BACK_TO_FIRST_STONE(s, pos));
3619
3620 /* The neighboring strings have obtained some new liberties and lost
3621 * a neighbor. For speed reasons we handle two most common cases
3622 * when string size is 1 or 2 stones here instead of calling
3623 * update_liberties().
3624 */
3625 if (size == 1) {
3626 for (k = 0; k < string[s].neighbors; k++) {
3627 int neighbor = string_neighbors[s].list[k];
3628
3629 remove_neighbor(neighbor, s);
3630 PUSH_VALUE(string[neighbor].liberties);
3631
3632 if (string[neighbor].liberties < MAX_LIBERTIES)
3633 string_libs[neighbor].list[string[neighbor].liberties] = pos;
3634 string[neighbor].liberties++;
3635 }
3636 }
3637 else if (size == 2) {
3638 int other = OTHER_COLOR(string[s].color);
3639 int pos2 = NEXT_STONE(pos);
3640
3641 for (k = 0; k < string[s].neighbors; k++) {
3642 int neighbor = string_neighbors[s].list[k];
3643
3644 remove_neighbor(neighbor, s);
3645 PUSH_VALUE(string[neighbor].liberties);
3646
3647 if (NEIGHBOR_OF_STRING(pos, neighbor, other)) {
3648 if (string[neighbor].liberties < MAX_LIBERTIES)
3649 string_libs[neighbor].list[string[neighbor].liberties] = pos;
3650 string[neighbor].liberties++;
3651 }
3652
3653 if (NEIGHBOR_OF_STRING(pos2, neighbor, other)) {
3654 if (string[neighbor].liberties < MAX_LIBERTIES)
3655 string_libs[neighbor].list[string[neighbor].liberties] = pos2;
3656 string[neighbor].liberties++;
3657 }
3658 }
3659 }
3660 else {
3661 for (k = 0; k < string[s].neighbors; k++) {
3662 remove_neighbor(string_neighbors[s].list[k], s);
3663 update_liberties(string_neighbors[s].list[k]);
3664 }
3665 }
3666
3667 /* Update the number of captured stones. These are assumed to
3668 * already have been pushed.
3669 */
3670 if (string[s].color == WHITE)
3671 white_captured += size;
3672 else
3673 black_captured += size;
3674
3675 return size;
3676}
3677
3678
3679/* We have played an isolated new stone and need to create a new
3680 * string for it.
3681 */
3682static void
3683create_new_string(int pos)
3684{
3685 int s;
3686 int color = board[pos];
3687 int other = OTHER_COLOR(color);
3688
3689 /* Get the next free string number. */
3690 PUSH_VALUE(next_string);
3691 s = next_string++;
3692 PARANOID1(s < MAX_STRINGS, pos);
3693 string_number[pos] = s;
3694 /* Set up a size one cycle for the string. */
3695 next_stone[pos] = pos;
3696
3697 /* Set trivially known values and initialize the rest to zero. */
3698 string[s].color = color;
3699 string[s].size = 1;
3700 string[s].origin = pos;
3701 string[s].liberties = 0;
3702 string[s].neighbors = 0;
3703 string[s].mark = 0;
3704
3705 /* Clear the string mark. */
3706 string_mark++;
3707
3708 /* In each direction, look for a liberty or a nonmarked opponent
3709 * neighbor. Mark visited neighbors. There is no need to mark the
3710 * liberties since we can't find them twice. */
3711 if (LIBERTY(SOUTH(pos))) {
3712 ADD_LIBERTY(s, SOUTH(pos));
3713 }
3714 else if (UNMARKED_COLOR_STRING(SOUTH(pos), other)) {
3715 int s2 = string_number[SOUTH(pos)];
3716 /* Add the neighbor to our list. */
3717 ADD_NEIGHBOR(s, SOUTH(pos));
3718 /* Add us to our neighbor's list. */
3719 PUSH_VALUE(string[s2].neighbors);
3720 ADD_NEIGHBOR(s2, pos);
3721 MARK_STRING(SOUTH(pos));
3722 }
3723
3724 if (LIBERTY(WEST(pos))) {
3725 ADD_LIBERTY(s, WEST(pos));
3726 }
3727 else if (UNMARKED_COLOR_STRING(WEST(pos), other)) {
3728 int s2 = string_number[WEST(pos)];
3729 /* Add the neighbor to our list. */
3730 ADD_NEIGHBOR(s, WEST(pos));
3731 /* Add us to our neighbor's list. */
3732 PUSH_VALUE(string[s2].neighbors);
3733 ADD_NEIGHBOR(s2, pos);
3734 MARK_STRING(WEST(pos));
3735 }
3736
3737 if (LIBERTY(NORTH(pos))) {
3738 ADD_LIBERTY(s, NORTH(pos));
3739 }
3740 else if (UNMARKED_COLOR_STRING(NORTH(pos), other)) {
3741 int s2 = string_number[NORTH(pos)];
3742 /* Add the neighbor to our list. */
3743 ADD_NEIGHBOR(s, NORTH(pos));
3744 /* Add us to our neighbor's list. */
3745 PUSH_VALUE(string[s2].neighbors);
3746 ADD_NEIGHBOR(s2, pos);
3747 MARK_STRING(NORTH(pos));
3748 }
3749
3750 if (LIBERTY(EAST(pos))) {
3751 ADD_LIBERTY(s, EAST(pos));
3752 }
3753 else if (UNMARKED_COLOR_STRING(EAST(pos), other)) {
3754 int s2 = string_number[EAST(pos)];
3755 /* Add the neighbor to our list. */
3756 ADD_NEIGHBOR(s, EAST(pos));
3757 /* Add us to our neighbor's list. */
3758 PUSH_VALUE(string[s2].neighbors);
3759 ADD_NEIGHBOR(s2, pos);
3760 /* No need to mark since no visits left. */
3761#if 0
3762 MARK_STRING(EAST(pos));
3763#endif
3764 }
3765}
3766
3767
3768/* We have played a stone with exactly one friendly neighbor. Add the
3769 * new stone to that string.
3770 */
3771static void
3772extend_neighbor_string(int pos, int s)
3773{
3774 int k;
3775 int liberties_updated = 0;
3776 int color = board[pos];
3777 int other = OTHER_COLOR(color);
3778
3779 /* Link in the stone in the cyclic list. */
3780 int pos2 = string[s].origin;
3781 next_stone[pos] = next_stone[pos2];
3782 PUSH_VALUE(next_stone[pos2]);
3783 next_stone[pos2] = pos;
3784
3785 /* Do we need to update the origin? */
3786 if (pos < pos2) {
3787 PUSH_VALUE(string[s].origin);
3788 string[s].origin = pos;
3789 }
3790
3791 string_number[pos] = s;
3792
3793 /* The size of the string has increased by one. */
3794 PUSH_VALUE(string[s].size);
3795 string[s].size++;
3796
3797 /* If s has too many liberties, we don't know where they all are and
3798 * can't update the liberties with the algorithm we otherwise
3799 * use. In that case we can only recompute the liberties from
3800 * scratch.
3801 */
3802 if (string[s].liberties > MAX_LIBERTIES) {
3803 update_liberties(s);
3804 liberties_updated = 1;
3805 }
3806 else {
3807 /* The place of the new stone is no longer a liberty. */
3808 remove_liberty(s, pos);
3809 }
3810
3811 /* Mark old neighbors of the string. */
3812 string_mark++;
3813 for (k = 0; k < string[s].neighbors; k++)
3814 string[string_neighbors[s].list[k]].mark = string_mark;
3815
3816 /* Look at the neighbor locations of pos for new liberties and/or
3817 * neighbor strings.
3818 */
3819
3820 /* If we find a liberty, look two steps away to determine whether
3821 * this already is a liberty of s.
3822 */
3823 if (LIBERTY(SOUTH(pos))) {
3824 if (!liberties_updated
3825 && !NON_SOUTH_NEIGHBOR_OF_STRING(SOUTH(pos), s, color))
3826 ADD_LIBERTY(s, SOUTH(pos));
3827 }
3828 else if (UNMARKED_COLOR_STRING(SOUTH(pos), other)) {
3829 int s2 = string_number[SOUTH(pos)];
3830 PUSH_VALUE(string[s].neighbors);
3831 ADD_NEIGHBOR(s, SOUTH(pos));
3832 PUSH_VALUE(string[s2].neighbors);
3833 ADD_NEIGHBOR(s2, pos);
3834 MARK_STRING(SOUTH(pos));
3835 }
3836
3837 if (LIBERTY(WEST(pos))) {
3838 if (!liberties_updated
3839 && !NON_WEST_NEIGHBOR_OF_STRING(WEST(pos), s, color))
3840 ADD_LIBERTY(s, WEST(pos));
3841 }
3842 else if (UNMARKED_COLOR_STRING(WEST(pos), other)) {
3843 int s2 = string_number[WEST(pos)];
3844 PUSH_VALUE(string[s].neighbors);
3845 ADD_NEIGHBOR(s, WEST(pos));
3846 PUSH_VALUE(string[s2].neighbors);
3847 ADD_NEIGHBOR(s2, pos);
3848 MARK_STRING(WEST(pos));
3849 }
3850
3851 if (LIBERTY(NORTH(pos))) {
3852 if (!liberties_updated
3853 && !NON_NORTH_NEIGHBOR_OF_STRING(NORTH(pos), s, color))
3854 ADD_LIBERTY(s, NORTH(pos));
3855 }
3856 else if (UNMARKED_COLOR_STRING(NORTH(pos), other)) {
3857 int s2 = string_number[NORTH(pos)];
3858 PUSH_VALUE(string[s].neighbors);
3859 ADD_NEIGHBOR(s, NORTH(pos));
3860 PUSH_VALUE(string[s2].neighbors);
3861 ADD_NEIGHBOR(s2, pos);
3862 MARK_STRING(NORTH(pos));
3863 }
3864
3865 if (LIBERTY(EAST(pos))) {
3866 if (!liberties_updated
3867 && !NON_EAST_NEIGHBOR_OF_STRING(EAST(pos), s, color))
3868 ADD_LIBERTY(s, EAST(pos));
3869 }
3870 else if (UNMARKED_COLOR_STRING(EAST(pos), other)) {
3871 int s2 = string_number[EAST(pos)];
3872 PUSH_VALUE(string[s].neighbors);
3873 ADD_NEIGHBOR(s, EAST(pos));
3874 PUSH_VALUE(string[s2].neighbors);
3875 ADD_NEIGHBOR(s2, pos);
3876#if 0
3877 MARK_STRING(EAST(pos));
3878#endif
3879 }
3880
3881}
3882
3883
3884/* Incorporate the string at pos with the string s.
3885 */
3886
3887static void
3888assimilate_string(int s, int pos)
3889{
3890 int k;
3891 int last;
3892 int s2 = string_number[pos];
3893 string[s].size += string[s2].size;
3894
3895 /* Walk through the s2 stones and change string number. Also pick up
3896 * the last stone in the cycle for later use.
3897 */
3898 pos = FIRST_STONE(s2);
3899 do {
3900 PUSH_VALUE(string_number[pos]);
3901 string_number[pos] = s;
3902 last = pos;
3903 pos = NEXT_STONE(pos);
3904 } while (!BACK_TO_FIRST_STONE(s2, pos));
3905
3906 /* Link the two cycles together. */
3907 {
3908 int pos2 = string[s].origin;
3909 PUSH_VALUE(next_stone[last]);
3910 PUSH_VALUE(next_stone[pos2]);
3911 next_stone[last] = next_stone[pos2];
3912 next_stone[pos2] = string[s2].origin;
3913
3914 /* Do we need to update the origin? */
3915 if (string[s2].origin < pos2)
3916 string[s].origin = string[s2].origin;
3917 }
3918
3919 /* Pick up the liberties of s2 that we don't already have.
3920 * It is assumed that the liberties of s have been marked before
3921 * this function is called.
3922 */
3923 if (string[s2].liberties <= MAX_LIBERTIES) {
3924 for (k = 0; k < string[s2].liberties; k++) {
3925 int pos2 = string_libs[s2].list[k];
3926 if (UNMARKED_LIBERTY(pos2)) {
3927 ADD_AND_MARK_LIBERTY(s, pos2);
3928 }
3929 }
3930 }
3931 else {
3932 /* If s2 had too many liberties the above strategy wouldn't be
3933 * effective, since not all liberties are listed in
3934 * libs[] the chain of stones for s2 is no
3935 * longer available (it has already been merged with s) so we
3936 * can't reconstruct the s2 liberties. Instead we capitulate and
3937 * rebuild the list of liberties for s (including the neighbor
3938 * strings assimilated so far) from scratch.
3939 */
3940 liberty_mark++; /* Reset the mark. */
3941 string[s].liberties = 0; /* To avoid pushing the current list. */
3942 update_liberties(s);
3943 }
3944
3945 /* Remove s2 as neighbor to the neighbors of s2 and instead add s if
3946 * they don't already have added it. Also add the neighbors of s2 as
3947 * neighbors of s, unless they already have been added. The already
3948 * known neighbors of s are assumed to have been marked before this
3949 * function is called.
3950 */
3951 for (k = 0; k < string[s2].neighbors; k++) {
3952 int t = string_neighbors[s2].list[k];
3953 remove_neighbor(t, s2);
3954 if (string[t].mark != string_mark) {
3955 PUSH_VALUE(string[t].neighbors);
3956 string_neighbors[t].list[string[t].neighbors++] = s;
3957 string_neighbors[s].list[string[s].neighbors++] = t;
3958 string[t].mark = string_mark;
3959 }
3960 }
3961}
3962
3963
3964/* Create a new string for the stone at pos and assimilate all
3965 * friendly neighbor strings.
3966 */
3967
3968static void
3969assimilate_neighbor_strings(int pos)
3970{
3971 int s;
3972 int color = board[pos];
3973 int other = OTHER_COLOR(color);
3974
3975 /* Get the next free string number. */
3976 PUSH_VALUE(next_string);
3977 s = next_string++;
3978 PARANOID1(s < MAX_STRINGS, pos);
3979 string_number[pos] = s;
3980 /* Set up a size one cycle for the string. */
3981 next_stone[pos] = pos;
3982
3983 /* Set trivially known values and initialize the rest to zero. */
3984 string[s].color = color;
3985 string[s].size = 1;
3986 string[s].origin = pos;
3987 string[s].liberties = 0;
3988 string[s].neighbors = 0;
3989
3990 /* Clear the marks. */
3991 liberty_mark++;
3992 string_mark++;
3993
3994 /* Mark ourselves. */
3995 string[s].mark = string_mark;
3996
3997 /* Look in each direction for
3998 *
3999 * 1. liberty: Add if not already visited.
4000 * 2. opponent string: Add it among our neighbors and us among its
4001 * neighbors, unless already visited.
4002 * 3. friendly string: Assimilate.
4003 */
4004 if (UNMARKED_LIBERTY(SOUTH(pos))) {
4005 ADD_AND_MARK_LIBERTY(s, SOUTH(pos));
4006 }
4007 else if (UNMARKED_COLOR_STRING(SOUTH(pos), other)) {
4008 ADD_NEIGHBOR(s, SOUTH(pos));
4009 PUSH_VALUE(string[string_number[SOUTH(pos)]].neighbors);
4010 ADD_NEIGHBOR(string_number[SOUTH(pos)], pos);
4011 MARK_STRING(SOUTH(pos));
4012 }
4013 else if (UNMARKED_COLOR_STRING(SOUTH(pos), color)) {
4014 assimilate_string(s, SOUTH(pos));
4015 }
4016
4017 if (UNMARKED_LIBERTY(WEST(pos))) {
4018 ADD_AND_MARK_LIBERTY(s, WEST(pos));
4019 }
4020 else if (UNMARKED_COLOR_STRING(WEST(pos), other)) {
4021 ADD_NEIGHBOR(s, WEST(pos));
4022 PUSH_VALUE(string[string_number[WEST(pos)]].neighbors);
4023 ADD_NEIGHBOR(string_number[WEST(pos)], pos);
4024 MARK_STRING(WEST(pos));
4025 }
4026 else if (UNMARKED_COLOR_STRING(WEST(pos), color)) {
4027 assimilate_string(s, WEST(pos));
4028 }
4029
4030 if (UNMARKED_LIBERTY(NORTH(pos))) {
4031 ADD_AND_MARK_LIBERTY(s, NORTH(pos));
4032 }
4033 else if (UNMARKED_COLOR_STRING(NORTH(pos), other)) {
4034 ADD_NEIGHBOR(s, NORTH(pos));
4035 PUSH_VALUE(string[string_number[NORTH(pos)]].neighbors);
4036 ADD_NEIGHBOR(string_number[NORTH(pos)], pos);
4037 MARK_STRING(NORTH(pos));
4038 }
4039 else if (UNMARKED_COLOR_STRING(NORTH(pos), color)) {
4040 assimilate_string(s, NORTH(pos));
4041 }
4042
4043 if (UNMARKED_LIBERTY(EAST(pos))) {
4044#if 0
4045 ADD_AND_MARK_LIBERTY(s, EAST(pos));
4046#else
4047 ADD_LIBERTY(s, EAST(pos));
4048#endif
4049 }
4050 else if (UNMARKED_COLOR_STRING(EAST(pos), other)) {
4051 ADD_NEIGHBOR(s, EAST(pos));
4052 PUSH_VALUE(string[string_number[EAST(pos)]].neighbors);
4053 ADD_NEIGHBOR(string_number[EAST(pos)], pos);
4054#if 0
4055 MARK_STRING(EAST(pos));
4056#endif
4057 }
4058 else if (UNMARKED_COLOR_STRING(EAST(pos), color)) {
4059 assimilate_string(s, EAST(pos));
4060 }
4061}
4062
4063
4064/* Suicide at `pos' (the function assumes that the move is indeed suicidal).
4065 * Remove the neighboring friendly strings.
4066 */
4067
4068static void
4069do_commit_suicide(int pos, int color)
4070{
4071 if (board[SOUTH(pos)] == color)
4072 do_remove_string(string_number[SOUTH(pos)]);
4073
4074 if (board[WEST(pos)] == color)
4075 do_remove_string(string_number[WEST(pos)]);
4076
4077 if (board[NORTH(pos)] == color)
4078 do_remove_string(string_number[NORTH(pos)]);
4079
4080 if (board[EAST(pos)] == color)
4081 do_remove_string(string_number[EAST(pos)]);
4082
4083 /* Count the stone we "played" as captured. */
4084 if (color == WHITE)
4085 white_captured++;
4086 else
4087 black_captured++;
4088}
4089
4090
4091/* Play a move without legality checking. This is a low-level function,
4092 * it assumes that the move is not a suicide. Such cases must be handled
4093 * where the function is called.
4094 */
4095
4096static void
4097do_play_move(int pos, int color)
4098{
4099 int other = OTHER_COLOR(color);
4100 int captured_stones = 0;
4101 int neighbor_allies = 0;
4102 int s = -1;
4103
4104 /* Clear string mark. */
4105 string_mark++;
4106
4107 /* Put down the stone. We also set its string number to -1 for a while
4108 * so that NEIGHBOR_OF_STRING() and friends don't get confused with the
4109 * stone.
4110 */
4111 DO_ADD_STONE(pos, color);
4112 string_number[pos] = -1;
4113
4114 /* Look in all directions. Count the number of neighbor strings of the same
4115 * color, remove captured strings and remove `pos' as liberty for opponent
4116 * strings that are not captured.
4117 */
4118 if (board[SOUTH(pos)] == color) {
4119 neighbor_allies++;
4120 s = string_number[SOUTH(pos)];
4121 MARK_STRING(SOUTH(pos));
4122 }
4123 else if (board[SOUTH(pos)] == other) {
4124 if (LIBERTIES(SOUTH(pos)) > 1) {
4125 remove_liberty(string_number[SOUTH(pos)], pos);
4126 MARK_STRING(SOUTH(pos));
4127 }
4128 else
4129 captured_stones += do_remove_string(string_number[SOUTH(pos)]);
4130 }
4131
4132 if (UNMARKED_COLOR_STRING(WEST(pos), color)) {
4133 neighbor_allies++;
4134 s = string_number[WEST(pos)];
4135 MARK_STRING(WEST(pos));
4136 }
4137 else if (UNMARKED_COLOR_STRING(WEST(pos), other)) {
4138 if (LIBERTIES(WEST(pos)) > 1) {
4139 remove_liberty(string_number[WEST(pos)], pos);
4140 MARK_STRING(WEST(pos));
4141 }
4142 else
4143 captured_stones += do_remove_string(string_number[WEST(pos)]);
4144 }
4145
4146 if (UNMARKED_COLOR_STRING(NORTH(pos), color)) {
4147 neighbor_allies++;
4148 s = string_number[NORTH(pos)];
4149 MARK_STRING(NORTH(pos));
4150 }
4151 else if (UNMARKED_COLOR_STRING(NORTH(pos), other)) {
4152 if (LIBERTIES(NORTH(pos)) > 1) {
4153 remove_liberty(string_number[NORTH(pos)], pos);
4154 MARK_STRING(NORTH(pos));
4155 }
4156 else
4157 captured_stones += do_remove_string(string_number[NORTH(pos)]);
4158 }
4159
4160 if (UNMARKED_COLOR_STRING(EAST(pos), color)) {
4161 neighbor_allies++;
4162 s = string_number[EAST(pos)];
4163#if 0
4164 MARK_STRING(EAST(pos));
4165#endif
4166 }
4167 else if (UNMARKED_COLOR_STRING(EAST(pos), other)) {
4168 if (LIBERTIES(EAST(pos)) > 1) {
4169 remove_liberty(string_number[EAST(pos)], pos);
4170#if 0
4171 MARK_STRING(EAST(pos));
4172#endif
4173 }
4174 else
4175 captured_stones += do_remove_string(string_number[EAST(pos)]);
4176 }
4177
4178 /* Choose strategy depending on the number of friendly neighbors. */
4179 if (neighbor_allies == 0)
4180 create_new_string(pos);
4181 else if (neighbor_allies == 1) {
4182 gg_assert(s >= 0);
4183 extend_neighbor_string(pos, s);
4184 return; /* can't be a ko, we're done */
4185 }
4186 else {
4187 assimilate_neighbor_strings(pos);
4188 return; /* can't be a ko, we're done */
4189 }
4190
4191 /* Check whether this move was a ko capture and if so set
4192 * board_ko_pos.
4193 *
4194 * No need to push board_ko_pos on the stack,
4195 * because this has been done earlier.
4196 */
4197 s = string_number[pos];
4198 if (string[s].liberties == 1
4199 && string[s].size == 1
4200 && captured_stones == 1) {
4201 /* In case of a double ko: clear old ko position first. */
4202 if (board_ko_pos != NO_MOVE)
4203 hashdata_invert_ko(&board_hash, board_ko_pos);
4204 board_ko_pos = string_libs[s].list[0];
4205 hashdata_invert_ko(&board_hash, board_ko_pos);
4206 }
4207}
4208
4209
4210
4211/* ================================================================ *
4212 * The following functions don't actually belong here. They are
4213 * only here because they are faster here where they have access to
4214 * the incremental data structures.
4215 * ================================================================ */
4216
4217
4218/* Help collect the data needed by order_moves() in reading.c.
4219 * It's the caller's responsibility to initialize the result parameters.
4220 */
4221#define NO_UNROLL 0
4222void
4223incremental_order_moves(int move, int color, int str,
4224 int *number_edges, int *number_same_string,
4225 int *number_own, int *number_opponent,
4226 int *captured_stones, int *threatened_stones,
4227 int *saved_stones, int *number_open)
4228{
4229#if NO_UNROLL == 1
4230 int pos;
4231 int k;
4232
4233 /* Clear the string mark. */
4234 string_mark++;
4235
4236 for (k = 0; k < 4; k++) {
4237 pos = move + delta[k];
4238 if (!ON_BOARD(pos))
4239 (*number_edges)++;
4240 else if (board[pos] == EMPTY)
4241 (*number_open)++;
4242 else {
4243 int s = string_number[pos];
4244 if (string_number[str] == s)
4245 (*number_same_string)++;
4246
4247 if (board[pos] == color) {
4248 (*number_own)++;
4249 if (string[s].liberties == 1)
4250 (*saved_stones) += string[s].size;
4251 }
4252 else {
4253 (*number_opponent)++;
4254 if (string[s].liberties == 1) {
4255 int r;
4256 struct string_data *t;
4257 (*captured_stones) += string[s].size;
4258 for (r = 0; r < string[s].neighbors; r++) {
4259 t = &string[string[s].neighborlist[r]];
4260 if (t->liberties == 1)
4261 (*saved_stones) += t->size;
4262 }
4263 }
4264 else if (string[s].liberties == 2 && UNMARKED_STRING(pos)) {
4265 (*threatened_stones) += string[s].size;
4266 MARK_STRING(pos);
4267 }
4268 }
4269 }
4270 }
4271
4272#else
4273#define code1(arg) \
4274 if (!ON_BOARD(arg)) \
4275 (*number_edges)++; \
4276 else if (board[arg] == EMPTY) \
4277 (*number_open)++; \
4278 else { \
4279 int s = string_number[arg]; \
4280 if (string_number[str] == s) \
4281 (*number_same_string)++; \
4282 if (board[arg] == color) { \
4283 (*number_own)++; \
4284 if (string[s].liberties == 1) \
4285 (*saved_stones) += string[s].size; \
4286 } \
4287 else { \
4288 (*number_opponent)++; \
4289 if (string[s].liberties == 1) { \
4290 int r; \
4291 struct string_data *t; \
4292 (*captured_stones) += string[s].size; \
4293 for (r = 0; r < string[s].neighbors; r++) { \
4294 t = &string[string_neighbors[s].list[r]]; \
4295 if (t->liberties == 1) \
4296 (*saved_stones) += t->size; \
4297 } \
4298 } \
4299 else if (string[s].liberties == 2 && UNMARKED_STRING(arg)) { \
4300 (*threatened_stones) += string[s].size; \
4301 MARK_STRING(arg); \
4302 } \
4303 } \
4304 }
4305
4306 /* Clear the string mark. */
4307 string_mark++;
4308
4309 code1(SOUTH(move));
4310 code1(WEST(move));
4311 code1(NORTH(move));
4312 code1(EAST(move));
4313#endif
4314}
4315
4316
4317int
4318square_dist(int pos1, int pos2)
4319{
4320 int idist = I(pos1) - I(pos2);
4321 int jdist = J(pos1) - J(pos2);
4322 return idist*idist + jdist*jdist;
4323}
4324
4325
4326/*
4327 * Local Variables:
4328 * tab-width: 8
4329 * c-basic-offset: 2
4330 * End:
4331 */