Ticket #148: code.diff

File code.diff, 224.1 KB (added by draqo, 4 years ago)

unnecessary inlines removed

  • gnugo/config.h.in

    RCS file: /sources/gnugo/gnugo/config.h.in,v
    retrieving revision 1.43
    diff -u -r1.43 config.h.in
     
    1212/* Center oriented influence. Disabled by default. */ 
    1313#undef COSMIC_GNUGO 
    1414 
    15 /* Default level (strength). Up to 10 supported */ 
     15/* Default level (strength). Up to 12 is recommended. */ 
    1616#undef DEFAULT_LEVEL 
    1717 
    1818/* Default hash table size in megabytes */ 
     
    2727/* GAIN/LOSS codes. Disabled by default. */ 
    2828#undef EXPERIMENTAL_OWL_EXT 
    2929 
     30/* Disable unneeded things. 0 standard. */ 
     31#undef FINAL_RELEASE 
     32 
    3033/* The concatenation of the strings "GNU ", and PACKAGE. */ 
    3134#undef GNU_PACKAGE 
    3235 
     
    103106/* Semeai Variations. 500 default */ 
    104107#undef SEMEAI_NODE_LIMIT 
    105108 
     109/* The size of a `int', as computed by sizeof. */ 
     110#undef SIZEOF_INT 
     111 
    106112/* The size of a `long', as computed by sizeof. */ 
    107113#undef SIZEOF_LONG 
    108114 
  • gnugo/configure

    RCS file: /sources/gnugo/gnugo/configure,v
    retrieving revision 1.125
    diff -u -r1.125 configure
     
    22# Guess values for system-dependent variables and create Makefiles. 
    33# Generated by Autoconf 2.52. 
    44# 
    5 # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 
     5# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2006 
    66# Free Software Foundation, Inc. 
    77# This configure script is free software; the Free Software Foundation 
    88# gives unlimited permission to copy, distribute and modify it. 
     
    673673                                         analysis (default) 
    674674  --disable-socket-support           don't compile GTP over TCP/IP support 
    675675  --enable-socket-support            compile TCP/IP support (default) 
     676  --enable-final-release             turn off additional chekcs, stats, etc. 
     677  --disable-final-release            turn on additional chekcs, stats, etc. 
    676678 
    677679Optional Packages: 
    678680  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes] 
     
    14441446 
    14451447fi; 
    14461448 
     1449# Check whether --enable-final-release or --disable-final-release was given. 
     1450if test "${enable-final-release+set}" = set; then 
     1451  enableval="$enable_final_release" 
     1452 
     1453fi; 
     1454 
    14471455ac_ext=c 
    14481456ac_cpp='$CPP $CPPFLAGS' 
    14491457ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 
     
    33773385#define SIZEOF_LONG $ac_cv_sizeof_long 
    33783386EOF 
    33793387 
     3388echo "$as_me:3181: checking size of int" >&5 
     3389echo $ECHO_N "checking size of int... $ECHO_C" >&6 
     3390cat >conftest.$ac_ext <<_ACEOF 
     3391#line 3391 "configure" 
     3392#include "confdefs.h" 
     3393#include <stdio.h> 
     3394 
     3395int 
     3396main () 
     3397{ 
     3398FILE *f = fopen ("conftest.val", "w"); 
     3399if (!f) 
     3400  exit (1); 
     3401fprintf (f, "%d", (sizeof (int))); 
     3402fclose (f); 
     3403  ; 
     3404  return 0; 
     3405} 
     3406_ACEOF 
     3407rm -f conftest$ac_exeext 
     3408if { (eval echo "$as_me:3408: \"$ac_link\"") >&5 
     3409  (eval $ac_link) 2>&5 
     3410  ac_status=$? 
     3411  echo "$as_me:3411: \$? = $ac_status" >&5 
     3412  (exit $ac_status); } && { ac_try='./conftest$ac_exeext' 
     3413  { (eval echo "$as_me:3413: \"$ac_try\"") >&5 
     3414  (eval $ac_try) 2>&5 
     3415  ac_status=$? 
     3416  echo "$as_me:3416: \$? = $ac_status" >&5 
     3417  (exit $ac_status); }; }; then 
     3418  ac_cv_sizeof_int=`cat conftest.val` 
     3419else 
     3420  echo "$as_me: program exited with status $ac_status" >&5 
     3421echo "$as_me: failed program was:" >&5 
     3422cat conftest.$ac_ext >&5 
     3423fi 
     3424rm -f conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext 
     3425rm -f conftest.val 
     3426echo "$as_me:3426: result: $ac_cv_sizeof_int" >&5 
     3427echo "${ECHO_T}$ac_cv_sizeof_int" >&6 
     3428cat >>confdefs.h <<EOF 
     3429#define SIZEOF_INT $ac_cv_sizeof_int 
     3430EOF 
     3431 
    33803432for ac_func in vsnprintf gettimeofday usleep times 
    33813433do 
    33823434as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` 
     
    41044156 
    41054157fi 
    41064158 
     4159if test "$enable_final_release" = "yes" ; then 
     4160   cat >>confdefs.h <<\EOF 
     4161#define FINAL_RELEASE 1 
     4162EOF 
     4163 
     4164else 
     4165   cat >>confdefs.h <<\EOF 
     4166#define FINAL_RELEASE 0 
     4167EOF 
     4168 
     4169fi 
     4170 
    41074171if test "$enable_cosmic_gnugo" = "yes" ; then 
    41084172   cat >>confdefs.h <<\EOF 
    41094173#define COSMIC_GNUGO 1 
  • gnugo/configure.in

    RCS file: /sources/gnugo/gnugo/configure.in,v
    retrieving revision 1.136
    diff -u -r1.136 configure.in
     
    124124AC_ARG_ENABLE(socket-support, 
    125125 [  --disable-socket-support           don't compile GTP over TCP/IP support 
    126126  --enable-socket-support            compile TCP/IP support (default)]) 
     127   
     128AC_ARG_ENABLE(final-release, 
     129 [  --enable-final-release     turn off additional chekcs, stats, etc. 
     130  --disable-final-release    turn on additional chekcs, stats, etc. (default)]) 
    127131 
    128132AC_PROG_CC 
    129133 
     
    178182   term_header="no" 
    179183fi 
    180184 
     185AC_CHECK_SIZEOF(int,,[#include <stdio.h>]) 
    181186AC_CHECK_SIZEOF(long,,[#include <stdio.h>]) 
    182187 
    183188dnl vsnprintf not universally available 
     
    338343dnl ------------ set default level  ---------- 
    339344 
    340345AH_TEMPLATE([DEFAULT_LEVEL], 
    341 [Default level (strength). Up to 10 supported]) 
     346[Default level (strength). Up to 12 is recommended.]) 
    342347 
    343348if test "$enable_level" ; then 
    344349   AC_DEFINE_UNQUOTED(DEFAULT_LEVEL, $enable_level) 
     
    491496   AC_DEFINE(OWL_THREATS, 0) 
    492497fi 
    493498 
     499dnl ------------ Final release ------------------- 
     500 
     501AH_TEMPLATE([FINAL_RELEASE], 
     502[Disable unneeded things. 0 standard.]) 
     503 
     504if test "$enable_final_release" = "yes" ; then 
     505   AC_DEFINE(FINAL_RELEASE, 1) 
     506else 
     507   AC_DEFINE(FINAL_RELEASE, 0) 
     508fi 
     509 
    494510dnl ------------ additional valgrind macros ------ 
    495511 
    496512AH_TEMPLATE([USE_VALGRIND], 
  • gnugo/engine/aftermath.c

    RCS file: /sources/gnugo/gnugo/engine/aftermath.c,v
    retrieving revision 1.61
    diff -u -r1.61 aftermath.c
     
    288288    for (k = 0; k < 4; k++) { 
    289289      int dir = delta[k]; 
    290290      int right = delta[(k+1)%4]; 
     291      int checked_pos = pos + dir; 
     292 
    291293      if (!ON_BOARD(pos - dir) 
    292           && board[pos + dir] == color 
    293           && board[pos + dir + right] == other 
    294           && board[pos + dir - right] == other 
    295           && (libs > countlib(pos + dir) 
    296               || (libs > 4 
    297                   && libs == countlib(pos + dir))) 
    298           && (DRAGON2(pos + dir).safety == INVINCIBLE 
    299               || DRAGON2(pos + dir).safety == STRONGLY_ALIVE)) { 
    300         int this_score = 20 * (owl_hotspot[pos] + reading_hotspot[pos]); 
    301         if (this_score > best_score) { 
    302           best_score = this_score; 
    303           best_scoring_move = pos; 
    304         } 
     294          && board[checked_pos] == color 
     295          && board[checked_pos + right] == other 
     296          && board[checked_pos - right] == other) { 
     297 
     298            int count_lib = countlib(checked_pos); 
     299            int safety; 
     300 
     301            if ((libs > count_lib 
     302                || (libs > 4 && libs == count_lib)) 
     303            && ((safety = DRAGON2(checked_pos).safety) == INVINCIBLE 
     304                || safety == STRONGLY_ALIVE)) { 
     305 
     306          int this_score = 20 * (owl_hotspot[pos] + reading_hotspot[pos]); 
     307          if (this_score > best_score) { 
     308            best_score = this_score; 
     309            best_scoring_move = pos; 
     310          } 
     311            } 
    305312      } 
    306313    } 
    307314  } 
     
    363370            score--; 
    364371          else { 
    365372            if (board[pos2] == color) { 
     373              int count_stones = countstones(pos2); 
     374              int count_lib = countlib(pos2); 
    366375              move_ok = 1; 
    367376              score += 7; 
    368               if (countstones(pos2) > 2) 
    369                 score++; 
    370               if (countstones(pos2) > 4) 
     377              if (count_stones > 4) 
     378                score += 2; 
     379              else if (count_stones > 2) 
    371380                score++; 
    372               if (countlib(pos2) < 4) 
    373                 score++; 
    374               if (countlib(pos2) < 3) 
     381              if (count_lib < 3) 
     382                score += 2; 
     383              else if (count_lib < 4) 
    375384                score++; 
    376385            } 
    377             else { 
     386            else { /* board[pos2] == other */ 
    378387              int deltalib = (approxlib(pos, other, MAXLIBS, NULL) 
    379388                              - countlib(pos2)); 
    380389              move_ok = 1; 
    381390              score++; 
    382               if (deltalib >= 0) 
    383                 score++; 
    384391              if (deltalib > 0) 
     392                score += 2; 
     393              else if (deltalib >= 0) 
    385394                score++; 
    386395            } 
    387396            mark_string(pos2, mx, mark); 
     
    470479 
    471480        if (!mx[origin] && dragon[pos2].status == DEAD) { 
    472481          bonus++; 
    473           if (k < 4  
    474               && countlib(pos2) <= 2  
    475               && countstones(pos2) >= 3) 
    476             bonus++; 
     482          if (k < 4) { 
     483            int count_lib = countlib(pos2); 
     484            if (count_lib <= 2 
     485                && countstones(pos2) >= 3) 
     486              bonus++; 
    477487           
    478           if (k < 4 && countlib(pos2) == 1) 
    479             bonus += 3; 
     488            if (count_lib == 1) 
     489              bonus += 3; 
     490          } 
    480491        } 
    481492        mx[origin] = 1; 
    482       } 
     493          } 
    483494      else if (board[pos2] == color) { 
    484495        dragons[pos] = pos2; 
    485496         
     
    491502         
    492503        if (k < 4) { 
    493504          int apos = worm[pos2].origin; 
     505          int count_lib = countlib(apos); 
    494506           
    495507          if (!mx[apos]) { 
    496508            own_worms++; 
    497509            if (countstones(apos) == 1) 
    498510              bonus += 2; 
    499             if (countlib(apos) < 6 
    500                 && approxlib(pos, color, 5, NULL) < countlib(apos)) 
     511            if (count_lib < 6 
     512                && approxlib(pos, color, 5, NULL) < count_lib) 
    501513              bonus -= 5; 
    502514            mx[apos] = 1; 
    503515          } 
    504516           
    505           if (countlib(apos) <= 2) { 
     517          if (count_lib <= 2) { 
    506518            int r; 
    507519            int important = 0; 
    508520            int safe_atari = 0; 
     
    612624      int move_ok = 1; 
    613625      if (libs < 5) { 
    614626        for (k = 0; k < 4; k++) { 
    615           if (board[move + delta[k]] == color 
    616               && countlib(move + delta[k]) > libs) 
     627          int checked_pos = move + delta[k]; 
     628          if (board[checked_pos] == color 
     629              && countlib(checked_pos) > libs) 
    617630            break; 
    618631        } 
    619632        if (k < 4) { 
     
    733746     * potential move possible. 
    734747     */ 
    735748    if (!self_atari_ok) { 
    736       while (countlib(pos) == 1) { 
     749      int count_lib; 
     750      while ((count_lib = countlib(pos)) == 1) { 
    737751        int lib; 
    738752        findlib(pos, 1, &lib); 
    739753        move = lib; 
     
    741755          break; 
    742756      } 
    743757       
    744       if (countlib(pos) == 1) 
     758      if (count_lib == 1) 
    745759        move = NO_MOVE; 
    746760    } 
    747761 
  • gnugo/engine/board.c

    RCS file: /sources/gnugo/gnugo/engine/board.c,v
    retrieving revision 1.119
    diff -u -r1.119 board.c
     
    3232#include "hash.h" 
    3333#include "sgftree.h" 
    3434#include "gg_utils.h" 
     35#include "gnugo.h" 
    3536 
    3637#include <stdio.h> 
    3738#include <string.h> 
     
    9192 * exceeds 40. But since we have no way to recover from running out of 
    9293 * stack space, we allocate with a substantial safety margin. 
    9394 */ 
     95#ifdef INT_INTERSECTION 
     96#define STACK_SIZE 2 * 80 * MAXSTACK 
     97#else 
    9498#define STACK_SIZE 80 * MAXSTACK 
     99#endif 
     100 
     101#ifdef INT_INTERSECTION 
     102 
     103#define CLEAR_STACKS() do { \ 
     104  change_stack_pointer = change_stack; \ 
     105  VALGRIND_MAKE_WRITABLE(change_stack, sizeof(change_stack)); \ 
     106} while (0) 
     107 
     108/* Begin a record : address == NULL */ 
     109#define BEGIN_CHANGE_RECORD()\ 
     110((change_stack_pointer++)->address = NULL) 
     111 
     112/* PUSH_VERTEX should be the same as PUSH_VALUE when Intersection is 
     113 * int type */ 
     114 
     115/* Save a value : store the address and the value in the stack */ 
     116#define PUSH_VALUE(v)\ 
     117(change_stack_pointer->address = &(v),\ 
     118 (change_stack_pointer++)->value = (v)) 
     119 
     120/* Save a board value : store the address and the value in the stack */ 
     121#define PUSH_VERTEX(v)\ 
     122(change_stack_pointer->address = &(v),\ 
     123 (change_stack_pointer++)->value = (v)) 
     124 
     125#define POP_MOVE()\ 
     126  while ((--change_stack_pointer)->address)\ 
     127  *(change_stack_pointer->address) =\ 
     128  change_stack_pointer->value 
    95129 
     130#else 
    96131 
    97132#define CLEAR_STACKS() do { \ 
    98133  change_stack_pointer = change_stack; \ 
     
    119154#define POP_MOVE()\ 
    120155  while ((--change_stack_pointer)->address)\ 
    121156  *(change_stack_pointer->address) =\ 
    122   change_stack_pointer->value 
    123  
    124  
    125 #define POP_VERTICES()\ 
     157  change_stack_pointer->value; 
    126158  while ((--vertex_stack_pointer)->address)\ 
    127159  *(vertex_stack_pointer->address) =\ 
    128160  vertex_stack_pointer->value 
     161#endif 
    129162 
    130163 
    131164/* ================================================================ */ 
     
    138171static struct string_liberties_data string_libs[MAX_STRINGS]; 
    139172static struct string_neighbors_data string_neighbors[MAX_STRINGS]; 
    140173 
    141 /* Stacks and stack pointers. */ 
     174/* Stacks and stack pointers. Used for undoing changes on the board */ 
    142175static struct change_stack_entry change_stack[STACK_SIZE]; 
    143176static struct change_stack_entry *change_stack_pointer; 
    144177 
     178#ifndef INT_INTERSECTION 
    145179static struct vertex_stack_entry vertex_stack[STACK_SIZE]; 
    146180static struct vertex_stack_entry *vertex_stack_pointer; 
     181#endif 
    147182 
    148183 
    149184/* Index into list of strings. The index is only valid if there is a 
     
    164199/* Macros to traverse the stones of a string. 
    165200 * 
    166201 * Usage: 
    167  * int s, pos; 
    168  * s = find_the_string() 
    169  * pos = FIRST_STONE(s); 
     202 * int first, s, pos; 
     203 * s = find_the_string(); 
     204 * first = FIRST_STONE(s); 
     205 * pos = first; 
    170206 *   do { 
    171207 *    use_stone(pos); 
    172208 *    pos = NEXT_STONE(pos); 
    173  *  } while (!BACK_TO_FIRST_STONE(s, pos)); 
     209 *  } while (pos != first); 
    174210 */ 
    175211#define FIRST_STONE(s) \ 
    176212  (string[s].origin) 
     
    178214#define NEXT_STONE(pos) \ 
    179215  (next_stone[pos]) 
    180216 
    181 #define BACK_TO_FIRST_STONE(s, pos) \ 
    182   ((pos) == string[s].origin) 
    183  
    184217 
    185218/* Assorted useful macros. 
    186219 * 
     
    197230#define MARK_LIBERTY(pos) \ 
    198231  ml[pos] = liberty_mark 
    199232 
    200 #define UNMARKED_STRING(pos) \ 
    201   (string[string_number[pos]].mark != string_mark) 
     233#define UNMARKED_STRING(str_nr) \ 
     234  (string[str_nr].mark != string_mark) 
    202235 
    203236/* Note that these two macros are not complementary. Both return 
    204237 * false if board[pos] != color. 
     
    211244  (board[pos] == color\ 
    212245   && string[string_number[pos]].mark == string_mark) 
    213246 
    214 #define MARK_STRING(pos) string[string_number[pos]].mark = string_mark 
     247#define MARK_STRING(str_nr) string[str_nr].mark = string_mark 
    215248 
    216249#define STRING_AT_VERTEX(pos, s, color)\ 
    217   ((board[pos] == color) && string_number[pos] == (s)) 
     250  ((board[pos] == (color)) && string_number[pos] == (s)) 
    218251 
    219252#define NEIGHBOR_OF_STRING(pos, s, color)\ 
    220253  (STRING_AT_VERTEX(SOUTH(pos), s, color)\ 
     
    245278  (STRING_AT_VERTEX(EAST(pos), s, color)\ 
    246279   || STRING_AT_VERTEX(SOUTH(pos), s, color)\ 
    247280   || STRING_AT_VERTEX(NORTH(pos), s, color)) 
    248    
    249 #define LIBERTIES(pos)\ 
    250   string[string_number[pos]].liberties 
    251281 
    252 #define COUNTSTONES(pos) \ 
    253   string[string_number[pos]].size 
     282#define LIBERTIES(str_nr)\ 
     283  string[str_nr].liberties 
     284 
     285#define COUNTSTONES(str_nr) \ 
     286  string[str_nr].size 
    254287 
    255288#define ADD_LIBERTY(s, pos)\ 
    256289  do {\ 
     
    267300    ml[pos] = liberty_mark;\ 
    268301  } while (0) 
    269302 
    270 #define ADD_NEIGHBOR(s, pos)\ 
    271   string_neighbors[s].list[string[s].neighbors++] = string_number[pos] 
     303#define ADD_NEIGHBOR(s1, s2)\ 
     304  string_neighbors[s1].list[string[s1].neighbors++] = s2 
    272305 
    273306#define DO_ADD_STONE(pos, color)\ 
    274307  do {\ 
     
    304337static int do_trymove(int pos, int color, int ignore_ko); 
    305338static void undo_trymove(void); 
    306339 
    307 static int do_approxlib(int pos, int color, int maxlib, int *libs); 
    308 static int slow_approxlib(int pos, int color, int maxlib, int *libs); 
    309 static int do_accuratelib(int pos, int color, int maxlib, int *libs); 
     340 
     341struct board_cache_entry { 
     342  int threshold; /* a number of checked, possible liberties 
     343                  * (liberties <= threshold) */ 
     344  int liberties; /* number of liberties (if liberties == threshold 
     345                  * there is maybe more liberties) */ 
     346  Hash_data position_hash; 
     347}; 
     348 
     349inline static int do_approxlib(int pos, int color, int maxlib, int *libs, 
     350                                                           struct board_cache_entry *entry); 
     351inline static int slow_approxlib(int pos, int color, int maxlib, int *libs, 
     352                                                                 struct board_cache_entry *entry); 
     353inline static int do_accuratelib(int pos, int color, int maxlib, int *libs, 
     354                                                                 struct board_cache_entry *entry); 
    310355 
    311356static int is_superko_violation(int pos, int color, enum ko_rules type); 
    312357 
    313358static void new_position(void); 
    314 static int propagate_string(int stone, int str); 
    315 static void find_liberties_and_neighbors(int s); 
    316 static int do_remove_string(int s); 
     359static int propagate_string(int stone_pos, int str_pos, int color); 
     360static void find_liberties_and_neighbors(int str_nr); 
     361static int do_remove_string(int str_nr); 
    317362static void do_commit_suicide(int pos, int color); 
    318363static void do_play_move(int pos, int color); 
    319364 
     
    326371/* Coordinates for the eight directions, ordered 
    327372 * south, west, north, east, southwest, northwest, northeast, southeast. 
    328373 */ 
    329 int deltai[8] = { 1,  0, -1,  0,  1, -1, -1, 1}; 
    330 int deltaj[8] = { 0, -1,  0,  1, -1, -1,  1, 1}; 
    331 int delta[8]  = { NS, -1, -NS, 1, NS-1, -NS-1, -NS+1, NS+1}; 
     374const int deltai[8] = { 1,  0, -1,  0,  1, -1, -1, 1}; 
     375const int deltaj[8] = { 0, -1,  0,  1, -1, -1,  1, 1}; 
     376const int delta[8]  = { NS, -WE, -NS, WE, NS-WE, -NS-WE, -NS+WE, NS+WE}; 
    332377 
    333378 
    334379/* ================================================================ */ 
     
    448493 
    449494  handicap = 0; 
    450495   
    451   hashdata_recalc(&board_hash, board, board_ko_pos); 
     496  hashdata_recalc(&board_hash, board, NO_MOVE); 
    452497  new_position(); 
    453498} 
    454499 
     
    496541 *   }    
    497542 * 
    498543 * The message can be written as a comment to an sgf file using  
    499  * sgfdump(). str can be NO_MOVE if it is not needed but otherwise   
    500  * the location of str is included in the comment. 
     544 * sgfdump(). 
     545 * str_pos is currently not used by function 
    501546 */ 
    502547 
    503548int  
    504 trymove(int pos, int color, const char *message, int str) 
     549trymove(int pos, int color, const char *message, int str_pos) 
    505550{ 
    506   UNUSED(str); 
     551  UNUSED(str_pos); 
     552 
    507553  /* Do the real work elsewhere. */ 
    508554  if (!do_trymove(pos, color, 0)) 
    509555    return 0; 
    510556 
     557#ifndef GG_TURN_OFF_TRACES 
    511558  /* Store the move in an sgf tree if one is available. */ 
    512559  if (sgf_dumptree) { 
    513560    char buf[100]; 
     
    540587    sgftreeAddPlayLast(sgf_dumptree, color, I(pos), J(pos)); 
    541588    sgftreeAddComment(sgf_dumptree, buf); 
    542589  } 
    543    
     590#else 
     591  UNUSED(message); 
     592#endif 
     593 
    544594  if (count_variations) 
    545595    count_variations++; 
     596 
     597#ifndef GG_TURN_OFF_STATS 
    546598  stats.nodes++; 
     599#endif 
    547600 
    548601  return 1; 
    549602} 
     
    567620  if (!do_trymove(pos, color, 1)) 
    568621    return 0; 
    569622 
     623#ifndef GG_TURN_OFF_TRACES 
    570624  if (sgf_dumptree) { 
    571625    char buf[100]; 
    572626    if (message == NULL) 
    573627      message = "UNKNOWN"; 
    574628    if (komaster != EMPTY) 
    575       gg_snprintf(buf, 100, "tryko: %s (variation %d, %s, komaster %s:%s)",  
    576                   message, count_variations, hashdata_to_string(&board_hash), 
     629      gg_snprintf(buf, 100, "tryko: %s at %s (variation %d, hash %s, komaster %s:%s)",  
     630                  message, location_to_string(pos), count_variations, 
     631                  hashdata_to_string(&board_hash), 
    577632                  color_to_string(komaster), location_to_string(kom_pos)); 
    578633    else 
    579       gg_snprintf(buf, 100, "tryko: %s (variation %d, %s)", message, 
     634      gg_snprintf(buf, 100, "tryko: %s at %s (variation %d, hash %s)", message, 
     635                  location_to_string(pos), 
    580636                  count_variations, hashdata_to_string(&board_hash)); 
    581637 
    582638    /* Add two pass moves to the SGF output to simulate the ko threat 
     
    595651    sgftreeAddPlayLast(sgf_dumptree, color, I(pos), J(pos)); 
    596652    sgftreeAddComment(sgf_dumptree, buf); 
    597653  } 
     654#else 
     655  UNUSED(message); 
     656#endif 
    598657   
    599658  if (count_variations) 
    600659    count_variations++; 
     660 
     661#ifndef GG_TURN_OFF_STATS 
    601662  stats.nodes++; 
     663#endif 
     664 
     665  return 1; 
     666} 
     667 
     668/* 
     669 * This function is used by komaster_trymove(). It performs checks made by trymove() 
     670 * and tryko(), so these functions have not to be called twice. It works like 
     671 * trymove() and it returns (by ko_move_allowed) the result of tryko(), but it 
     672 * doesn't call really_do_trymove() - we have to call it ourselves and function 
     673 * trykomaster_move does it for us. 
     674 */ 
     675 
     676inline static int 
     677check_komaster_move(int pos, int color, int *ko_move_allowed) 
     678{ 
     679  *ko_move_allowed = 0; 
     680 
     681  /* 1. The color must be BLACK or WHITE. */ 
     682  gg_assert(color == BLACK || color == WHITE); 
     683  
     684  if (pos != PASS_MOVE) { 
     685    /* 2. Unless pass, the move must be inside the board. */ 
     686    ASSERT_ON_BOARD1(pos); 
     687     
     688    /* Update the reading tree shadow. */ 
     689    shadow[pos] = 1; 
     690 
     691    /* 3. The location must be empty. */ 
     692    if (board[pos] != EMPTY) 
     693      return 0; 
     694     
     695    /* 4. Test if the location is the ko point. */ 
     696        if (pos == board_ko_pos) { 
     697      /*    The ko position is guaranteed to have all neighbors of the 
     698       *    same color, or off board. If that color is the same as the 
     699       *    move the ko is being filled, it is always allowed. This 
     700       *    could be tested with has_neighbor() but here a faster test 
     701       *    suffices. 
     702       */ 
     703          if (board[WEST(pos)] == OTHER_COLOR(color) 
     704              || board[EAST(pos)] == OTHER_COLOR(color)) 
     705        *ko_move_allowed = 1; 
     706        } 
     707 
     708    /* 5. Test for suicide. */ 
     709        if (is_suicide(pos, color)) { 
     710      *ko_move_allowed = 0; 
     711      return 0; 
     712    } 
     713  } 
     714 
     715  /* Check for stack overflow. */ 
     716  if (stackp >= MAXSTACK-2) { 
     717    fprintf(stderr,  
     718            "gnugo: Truncating search. This is beyond my reading ability!\n"); 
     719    /* FIXME: Perhaps it's best to just assert here and be done with it? */ 
     720#if 0 
     721      ASSERT1(0 && "check_komaster_move stack overflow", pos); 
     722#endif 
     723#if 0 
     724    if (verbose > 0) { 
     725      showboard(0); 
     726      dump_stack(); 
     727    } 
     728#endif 
     729    fflush(stderr); 
     730    *ko_move_allowed = 0; 
     731    return 0; 
     732  } 
     733 
     734  if (*ko_move_allowed) 
     735    return 0; 
    602736 
    603737  return 1; 
    604738} 
    605739 
     740/* 
     741 * Function calls really_do_trymove, counts stats and does all traces. 
     742 * It is called by komaster_trymove after check_komaster_move checks 
     743 * if the move is possible. 
     744 */ 
     745 
     746static void 
     747really_do_komastermove(int pos, int color, const char *message, int ko_move) 
     748{ 
     749#ifndef GG_TURN_OFF_STATS 
     750  /* Only count trymove when we do create a new position. */ 
     751  trymove_counter++; 
     752#endif 
     753   
     754  /* So far, so good. Now push the move on the move stack. These are 
     755   * needed for dump_stack(). 
     756   */ 
     757  stack[stackp] = pos; 
     758  move_color[stackp] = color; 
     759 
     760  really_do_trymove(pos, color); 
     761 
     762#ifndef GG_TURN_OFF_TRACES 
     763  if (sgf_dumptree) { 
     764    char buf[100]; 
     765 
     766    if (message == NULL) 
     767      message = "UNKNOWN"; 
     768     
     769    if (pos == NO_MOVE) { 
     770      if (komaster != EMPTY) 
     771        gg_snprintf(buf, 100, "komaster_trymove: %s (variation %d, hash %s, komaster %s:%s)",  
     772                    message, count_variations, hashdata_to_string(&board_hash), 
     773                    color_to_string(komaster), location_to_string(kom_pos)); 
     774      else 
     775        gg_snprintf(buf, 100, "komaster_trymove: %s (variation %d, hash %s)", message, 
     776                    count_variations, hashdata_to_string(&board_hash)); 
     777    } 
     778    else { 
     779      if (komaster != EMPTY) 
     780        gg_snprintf(buf, 100,  
     781                    "komaster_trymove: %s at %s (variation %d, hash %s, komaster %s:%s)",  
     782                    message, location_to_string(pos), count_variations, 
     783                    hashdata_to_string(&board_hash), 
     784                    color_to_string(komaster), 
     785                    location_to_string(kom_pos)); 
     786      else 
     787        gg_snprintf(buf, 100, "komaster_trymove: %s at %s (variation %d, hash %s)",  
     788                    message, location_to_string(pos), count_variations, 
     789                    hashdata_to_string(&board_hash)); 
     790    } 
     791 
     792    /* Add two pass moves to the SGF output to simulate the ko threat 
     793     * and the answer. 
     794     * 
     795     * The reason we add these is that certain SGF viewers, including 
     796     * Cgoban 1, won't properly display variations with illegal ko 
     797     * captures. SGF FF[4] compliant browsers should have no problem 
     798     * with this, though. 
     799     */ 
     800    if (ko_move) { 
     801      sgftreeAddPlayLast(sgf_dumptree, color, -1, -1); 
     802      sgftreeAddComment(sgf_dumptree, "tenuki (ko threat)"); 
     803      sgftreeAddPlayLast(sgf_dumptree, OTHER_COLOR(color), -1, -1); 
     804      sgftreeAddComment(sgf_dumptree, "tenuki (answers ko threat)"); 
     805    } 
     806 
     807    sgftreeAddPlayLast(sgf_dumptree, color, I(pos), J(pos)); 
     808    sgftreeAddComment(sgf_dumptree, buf); 
     809  } 
     810#else 
     811  UNUSED(message); 
     812  UNUSED(ko_move); 
     813#endif 
     814   
     815  if (count_variations) 
     816    count_variations++; 
     817 
     818#ifndef GG_TURN_OFF_STATS 
     819  stats.nodes++; 
     820#endif 
     821} 
     822 
     823 
    606824/* Really, really make a temporary move. It is assumed that all 
    607825 * necessary checks have already been made and likewise that various 
    608826 * administrative bookkeeping outside of the actual board logic has 
     
    614832  BEGIN_CHANGE_RECORD(); 
    615833  PUSH_VALUE(board_ko_pos); 
    616834 
    617   /* 
    618    * FIXME: Do we really have to store board_hash in a stack? 
    619    * 
    620    * Answer: No, we don't.  But for every stone that we add 
    621    *         or remove, we must call hashdata_invert_stone(). This is 
    622    *         not difficult per se, but the whole board.c  
    623    *         will have to be checked, and there is lots of room 
    624    *         for mistakes. 
    625    * 
    626    *         At the same time, profiling shows that storing the 
    627    *         hashdata in a stack doesn't take a lot of time, so 
    628    *         this is not an urgent FIXME. 
    629    */ 
     835  /* Restoring a hash value is faster than xoring hash codes of all 
     836   * undone stones */ 
    630837  memcpy(&board_hash_stack[stackp], &board_hash, sizeof(board_hash)); 
    631838 
    632839  if (board_ko_pos != NO_MOVE) 
     
    667874      return 0; 
    668875     
    669876    /* 4. The location must not be the ko point, unless ignore_ko == 1. */ 
    670     if (!ignore_ko && pos == board_ko_pos) { 
     877        if (!ignore_ko && pos == board_ko_pos) { 
     878      /*    The ko position is guaranteed to have all neighbors of the 
     879       *    same color, or off board. If that color is the same as the 
     880       *    move the ko is being filled, it is always allowed. This 
     881       *    could be tested with has_neighbor() but here a faster test 
     882       *    suffices. 
     883       */ 
    671884      if (board[WEST(pos)] == OTHER_COLOR(color) 
    672           || board[EAST(pos)] == OTHER_COLOR(color)) { 
    673         return 0; 
    674       } 
    675     } 
     885          || board[EAST(pos)] == OTHER_COLOR(color)) 
     886        return 0; 
     887        } 
    676888 
    677889    /* 5. Test for suicide. */ 
    678890    if (is_suicide(pos, color)) 
     
    684896    fprintf(stderr,  
    685897            "gnugo: Truncating search. This is beyond my reading ability!\n"); 
    686898    /* FIXME: Perhaps it's best to just assert here and be done with it? */ 
    687     if (0) { 
     899#if 0 
    688900      ASSERT1(0 && "trymove stack overflow", pos); 
    689     } 
     901#endif 
    690902#if 0 
    691903    if (verbose > 0) { 
    692904      showboard(0); 
     
    698910  } 
    699911 
    700912 
     913#ifndef GG_TURN_OFF_STATS 
    701914  /* Only count trymove when we do create a new position. */ 
    702915  trymove_counter++; 
     916#endif 
    703917   
    704918  /* So far, so good. Now push the move on the move stack. These are 
    705919   * needed for dump_stack(). 
     
    722936{ 
    723937  undo_trymove(); 
    724938   
     939#ifndef GG_TURN_OFF_TRACES 
    725940  if (sgf_dumptree) { 
    726941    char buf[100]; 
    727942    int is_tryko = 0; 
     
    742957    if (is_tryko) 
    743958      sgf_dumptree->lastnode = sgf_dumptree->lastnode->parent->parent; 
    744959  } 
     960#endif 
    745961} 
    746962 
    747963 
     
    760976{ 
    761977  gg_assert(change_stack_pointer - change_stack <= STACK_SIZE); 
    762978 
    763   if (0) { 
    764     gprintf("Change stack size = %d\n", change_stack_pointer - change_stack); 
    765     gprintf("Vertex stack size = %d\n", vertex_stack_pointer - vertex_stack); 
    766   } 
     979#if 0 
     980  gprintf("Change stack size = %d\n", change_stack_pointer - change_stack); 
     981#ifdef INT_INTERSECTION 
     982  gprintf("Intersection is int, so we don't use vertex stack (all is on change stack)\n"); 
     983#else 
     984  gprintf("Vertex stack size = %d\n", vertex_stack_pointer - vertex_stack); 
     985#endif 
     986#endif 
    767987 
    768988  POP_MOVE(); 
    769   POP_VERTICES(); 
    770989   
    771990  stackp--; 
    772991  memcpy(&board_hash, &(board_hash_stack[stackp]), sizeof(board_hash)); 
     
    10151234get_last_opponent_move(int color) 
    10161235{ 
    10171236  int k; 
     1237  const int other = OTHER_COLOR(color); 
    10181238   
    10191239  for (k = move_history_pointer - 1; k >= 0; k--) 
    1020     if (move_history_color[k] == OTHER_COLOR(color)) 
     1240    if (move_history_color[k] == other) 
    10211241      return move_history_pos[k]; 
    10221242 
    10231243  return PASS_MOVE; 
     
    10601280int 
    10611281is_pass(int pos) 
    10621282{ 
    1063   return pos == 0; 
     1283  return pos == PASS_MOVE; 
    10641284} 
    10651285 
    10661286 
     
    10781298is_legal(int pos, int color) 
    10791299{ 
    10801300  /* 0. A pass move is always legal. */ 
    1081   if (pos == 0) 
     1301  if (pos == PASS_MOVE) 
    10821302    return 1; 
    10831303 
    10841304  /* 1. The move must be inside the board. */ 
     
    10921312  if (pos == board_ko_pos) { 
    10931313    /*    The ko position is guaranteed to have all neighbors of the 
    10941314     *    same color, or off board. If that color is the same as the 
    1095      *    move the ko is being filled, which is always allowed. This 
     1315     *    move the ko is being filled, it is always allowed. This 
    10961316     *    could be tested with has_neighbor() but here a faster test 
    10971317     *    suffices. 
    10981318     */ 
    1099     if (board[WEST(pos)] == OTHER_COLOR(color) 
    1100         || board[EAST(pos)] == OTHER_COLOR(color)) { 
     1319    if (board[WEST(pos)] == OTHER_COLOR(color)  
     1320        || board[EAST(pos)] == OTHER_COLOR(color)) 
    11011321      return 0; 
    1102     } 
    11031322  } 
    11041323 
    11051324  /* Check for stack overflow. */ 
     
    11071326    fprintf(stderr,  
    11081327            "gnugo: Truncating search. This is beyond my reading ability!\n"); 
    11091328    /* FIXME: Perhaps it's best to just assert here and be done with it? */ 
    1110     if (0) { 
     1329#if 0 
    11111330      ASSERT1(0 && "is_legal stack overflow", pos); 
    1112     } 
     1331#endif 
    11131332    return 0; 
    11141333  } 
    11151334 
     
    11331352int  
    11341353is_suicide(int pos, int color) 
    11351354{ 
     1355  int checked_pos; 
     1356  int stone; 
    11361357  ASSERT_ON_BOARD1(pos); 
    11371358  ASSERT1(board[pos] == EMPTY, pos); 
    11381359 
    11391360  /* Check for suicide. */ 
    1140   if (LIBERTY(SOUTH(pos)) 
    1141       || (ON_BOARD(SOUTH(pos)) 
    1142           && ((board[SOUTH(pos)] == color) ^ (LIBERTIES(SOUTH(pos)) == 1)))) 
     1361  checked_pos = SOUTH(pos); 
     1362  stone = board[checked_pos]; 
     1363  if (stone == EMPTY 
     1364      || (ON_BOARD(checked_pos) 
     1365          && ((stone == color) ^ (LIBERTIES(string_number[checked_pos]) == 1)))) 
    11431366    return 0; 
    11441367 
    1145   if (LIBERTY(WEST(pos)) 
    1146       || (ON_BOARD(WEST(pos)) 
    1147           && ((board[WEST(pos)] == color) ^ (LIBERTIES(WEST(pos)) == 1)))) 
     1368  checked_pos = WEST(pos); 
     1369  stone = board[checked_pos]; 
     1370  if (stone == EMPTY 
     1371      || (ON_BOARD(checked_pos) 
     1372          && ((stone == color) ^ (LIBERTIES(string_number[checked_pos]) == 1)))) 
    11481373    return 0; 
    11491374 
    1150   if (LIBERTY(NORTH(pos)) 
    1151       || (ON_BOARD(NORTH(pos)) 
    1152           && ((board[NORTH(pos)] == color) ^ (LIBERTIES(NORTH(pos)) == 1)))) 
     1375  checked_pos = NORTH(pos); 
     1376  stone = board[checked_pos]; 
     1377  if (stone == EMPTY 
     1378      || (ON_BOARD(checked_pos) 
     1379          && ((stone == color) ^ (LIBERTIES(string_number[checked_pos]) == 1)))) 
    11531380    return 0; 
    11541381 
    1155   if (LIBERTY(EAST(pos)) 
    1156       || (ON_BOARD(EAST(pos)) 
    1157           && ((board[EAST(pos)] == color) ^ (LIBERTIES(EAST(pos)) == 1)))) 
     1382  checked_pos = EAST(pos); 
     1383  stone = board[checked_pos]; 
     1384  if (stone == EMPTY 
     1385      || (ON_BOARD(checked_pos) 
     1386          && ((stone == color) ^ (LIBERTIES(string_number[checked_pos]) == 1)))) 
    11581387    return 0; 
    11591388 
    11601389  return 1; 
     
    11721401  ASSERT1(board[pos] == EMPTY, pos); 
    11731402 
    11741403  return (pos == board_ko_pos 
     1404    /*    The ko position is guaranteed to have all neighbors of the 
     1405     *    same color, or off board. If that color is the same as the 
     1406     *    move the ko is being filled, it is always allowed. This 
     1407     *    could be tested with has_neighbor() but here a faster test 
     1408     *    suffices. 
     1409     */ 
    11751410          && ((board[WEST(pos)] == OTHER_COLOR(color)) 
    11761411              || (board[EAST(pos)] == OTHER_COLOR(color)))); 
    11771412} 
     
    12091444   *    suffices. 
    12101445   */ 
    12111446  if (ko_rule != NONE 
    1212       && pos == board_ko_pos 
    1213       && (board[WEST(pos)] == OTHER_COLOR(color) 
    1214           || board[EAST(pos)] == OTHER_COLOR(color))) 
    1215     return 0; 
     1447          && pos == board_ko_pos) { 
     1448    /*    The ko position is guaranteed to have all neighbors of the 
     1449     *    same color, or off board. If that color is the same as the 
     1450     *    move the ko is being filled, it is always allowed. This 
     1451     *    could be tested with has_neighbor() but here a faster test 
     1452     *    suffices. 
     1453     */ 
     1454      if (board[WEST(pos)] == OTHER_COLOR(color) 
     1455          || board[EAST(pos)] == OTHER_COLOR(color)) 
     1456        return 0; 
     1457  } 
    12161458 
    12171459  /* 5. Check for suicide. Suicide rule options: 
    12181460   *    FORBIDDEN   - No suicides allowed. 
     
    12311473   *    SSK          - Repetition of a previous position with the same 
    12321474   *                   player to move forbidden. 
    12331475   */ 
    1234   if (is_superko_violation(pos, color, ko_rule)) 
    1235     return 0; 
     1476  if (ko_rule != SIMPLE && ko_rule != NONE) 
     1477    if (is_superko_violation(pos, color, ko_rule)) 
     1478      return 0; 
    12361479   
    12371480  return 1; 
    12381481} 
     
    12651508 * 3.5.1 four of them were removed to simplify the code and because it 
    12661509 * no longer seemed interesting to be able to switch. The remaining 
    12671510 * komaster scheme was previously known as komaster scheme 5 (or V). 
    1268  * 
    1269  * FIXME: This function could be optimized by integrating the 
    1270  * trymove()/tryko() code. 
    12711511 */ 
    12721512 
    12731513/* V. Complex scheme, O to move. 
     
    12841524 * 2. Komaster is O: 
    12851525 * 2a) Only nested ko captures are allowed. Kom_pos is moved to the 
    12861526 *     new removed stone. 
    1287  * 2b) If komaster fills the ko at kom_pos then komaster reverts to 
    1288  *     EMPTY. 
     1527 * 2b) If the ko has been resolved in favor of the komaster (when the ko is 
     1528 *     filled or kom_pos is no longer a ko because of some capture) then the 
     1529 *     komaster reverts to EMPTY. 
    12891530 *  
    12901531 * 3. Komaster is X: 
    1291  *    Play at kom_pos is not allowed. Any other ko capture 
    1292  *    is allowed. If O takes another ko, komaster becomes GRAY_X. 
     1532 *    Play at kom_pos is not allowed if it is the ko recapture. Any other 
     1533 *    ko capture is allowed. If O takes another ko, komaster becomes GRAY_X. 
    12931534 *  
    12941535 * 4. Komaster is GRAY_O or GRAY_X: 
    1295  *    Ko captures are not allowed. If the ko at kom_pos is 
    1296  *    filled then the komaster reverts to EMPTY. 
     1536 *    Ko captures are not allowed. If the ko has been resolved in favor of 
     1537 *    the komaster (when the ko is filled or kom_pos is no longer a ko because 
     1538 *    of some capture) then the komaster reverts to EMPTY. 
    12971539 * 
    12981540 * 5. Komaster is WEAK_KO: 
    12991541 * 5a) After a non-ko move komaster reverts to EMPTY. 
    13001542 * 5b) Unconditional ko capture is only allowed if it is nested ko capture. 
    1301  *     Komaster is changed to WEAK_X and kom_pos to the old value of 
    1302  *     board_ko_pos. 
     1543 *     Kom_pos is moved to the old value of board_ko_pos. 
    13031544 * 5c) Conditional ko capture is allowed according to the rules of 1b. 
    13041545 */ 
    13051546int 
    13061547komaster_trymove(int pos, int color, const char *message, int str, 
    13071548                 int *is_conditional_ko, int consider_conditional_ko) 
    13081549{ 
    1309   int other = OTHER_COLOR(color); 
    13101550  int ko_move; 
    13111551  int kpos; 
    1312   int previous_board_ko_pos = board_ko_pos; 
     1552  int previous_board_ko_pos; 
     1553  int ko_move_allowed; 
     1554 
     1555  UNUSED(str); 
    13131556 
    13141557  *is_conditional_ko = 0; 
    13151558  ko_move = is_ko(pos, color, &kpos); 
    13161559 
    13171560  if (ko_move) { 
    1318     /* If opponent is komaster we may not capture his ko. */ 
    1319     if (komaster == other && pos == kom_pos) 
    1320       return 0; 
    1321  
    1322     /* If komaster is gray we may not capture ko at all. */ 
    1323     if (komaster == GRAY_WHITE || komaster == GRAY_BLACK) 
    1324       return 0; 
    1325  
    1326     /* If we are komaster, we may only do nested captures. */ 
    1327     if (komaster == color && !DIAGONAL_NEIGHBORS(kpos, kom_pos)) 
    1328       return 0; 
    1329  
    1330     /* If komaster is WEAK_KO, we may only do nested ko capture or 
    1331      * conditional ko capture. 
    1332      */ 
    1333     if (komaster == WEAK_KO) { 
    1334       if (pos != board_ko_pos && !DIAGONAL_NEIGHBORS(kpos, kom_pos)) 
    1335         return 0; 
     1561    switch (komaster) { 
     1562      case EMPTY: 
     1563        break; 
     1564 
     1565      case GRAY_WHITE: 
     1566      case GRAY_BLACK: 
     1567        /* If komaster is gray we may not capture ko at all. */ 
     1568        return 0; 
     1569 
     1570      case WEAK_KO: 
     1571        /* If komaster is WEAK_KO, we may only do nested ko capture or 
     1572         * conditional ko capture. 
     1573         */ 
     1574        if (pos != board_ko_pos && !DIAGONAL_NEIGHBORS(kpos, kom_pos)) 
     1575              return 0; 
     1576        break; 
     1577 
     1578      default: 
     1579        if (komaster == color) { 
     1580          /* If we are komaster, we may only do nested captures. */ 
     1581          if (!DIAGONAL_NEIGHBORS(kpos, kom_pos)) 
     1582            return 0; 
     1583        } 
     1584        else { // komaster == OTHER_COLOR(color) 
     1585          /* If opponent is komaster we may not capture his ko. */ 
     1586          if (pos == kom_pos) 
     1587            return 0; 
     1588        } 
     1589        break; 
    13361590    } 
    13371591  } 
    13381592 
    1339   if (!trymove(pos, color, message, str)) { 
     1593  previous_board_ko_pos = board_ko_pos; 
     1594 
     1595  if (check_komaster_move(pos, color, &ko_move_allowed)) 
     1596    really_do_komastermove(pos, color, message, 0); 
     1597  else { 
     1598    /* Conditional ko capture */ 
    13401599    if (!consider_conditional_ko) 
    13411600      return 0; 
    13421601 
    1343     if (!tryko(pos, color, message)) 
     1602    if (!ko_move_allowed) 
    13441603      return 0; /* Suicide. */ 
     1604 
     1605    really_do_komastermove(pos, color, message, 1); 
    13451606       
    13461607    *is_conditional_ko = 1; 
    13471608 
    1348     /* Conditional ko capture, set komaster parameters. */ 
     1609    /* Conditional ko capture, set komaster parameters (1b and 5c). */ 
    13491610    if (komaster == EMPTY || komaster == WEAK_KO) { 
    13501611      set_new_komaster(color); 
    13511612      set_new_kom_pos(kpos); 
     
    13551616 
    13561617  if (!ko_move) { 
    13571618    /* If we are komaster, check whether the ko was resolved by the 
    1358      * current move. If that is the case, revert komaster to EMPTY. 
     1619     * current move. If that is the case, revert komaster to EMPTY (2b and 4). 
    13591620     * 
    13601621     * The ko has been resolved in favor of the komaster if it has 
    1361      * been filled, or if it is no longer a ko and an opponent move 
    1362      * there is suicide. 
     1622     * been filled, or if an opponent move there is suicide (it is no 
     1623     * longer a ko then). 
    13631624     */ 
    1364     if (((komaster == color 
     1625    if ((komaster == color 
    13651626          || (komaster == GRAY_WHITE && color == WHITE) 
    13661627          || (komaster == GRAY_BLACK && color == BLACK)) 
    1367          && (IS_STONE(board[kom_pos]) 
    1368              || (!is_ko(kom_pos, other, NULL) 
    1369                  && is_suicide(kom_pos, other))))) { 
     1628         && (board[kom_pos] == color 
     1629             || (board[kom_pos] == EMPTY 
     1630                 && is_suicide(kom_pos, OTHER_COLOR(color))))) { 
    13701631      set_new_komaster(EMPTY); 
    13711632      set_new_kom_pos(NO_MOVE); 
    13721633    } 
    1373  
    1374     if (komaster == WEAK_KO) { 
     1634    /* After the non-ko move set the komaster to EMPTY (5a). */ 
     1635    else if (komaster == WEAK_KO) { 
    13751636      set_new_komaster(EMPTY); 
    13761637      set_new_kom_pos(NO_MOVE); 
    13771638    } 
     
    13791640    return 1; 
    13801641  } 
    13811642 
    1382   if (komaster == other) { 
     1643  if (komaster == OTHER_COLOR(color)) { 
     1644    /* After a ko capture set komaster to GRAY_X (3). */ 
    13831645    if (color == WHITE) 
    13841646      set_new_komaster(GRAY_BLACK); 
    13851647    else 
    13861648      set_new_komaster(GRAY_WHITE); 
    13871649  } 
    13881650  else if (komaster == color) { 
    1389     /* This is where we update kom_pos after a nested capture. */ 
     1651    /* This is where we update kom_pos after a nested capture (2a). */ 
    13901652    set_new_kom_pos(kpos); 
    13911653  } 
    13921654  else { 
    13931655    /* We can reach here when komaster is EMPTY or WEAK_KO. If previous 
    1394      * move was also a ko capture, we now set komaster to WEAK_KO. 
     1656     * move was also a ko capture, we now set komaster to WEAK_KO (1a and 5b). 
    13951657     */ 
    13961658    if (previous_board_ko_pos != NO_MOVE) { 
    13971659      set_new_komaster(WEAK_KO); 
     
    14511713} 
    14521714 
    14531715 
    1454 /* Returns true if the empty vertex respectively the string at pos1 is 
    1455  * adjacent to the empty vertex respectively the string at pos2. 
     1716/* Returns true if the empty vertex or the string at pos1 is 
     1717 * adjacent to the empty vertex or the string at pos2. 
    14561718 */ 
    14571719int 
    14581720are_neighbors(int pos1, int pos2) 
     
    14711733  } 
    14721734} 
    14731735 
    1474  
    1475 /* Count the number of liberties of the string at pos. pos must not be 
    1476  * empty. 
     1736/* Count the number of liberties of the string at str_pos. 
     1737 * str_pos must not be empty 
    14771738 */ 
    14781739int 
    1479 countlib(int str) 
     1740countlib(int str_pos) 
    14801741{ 
    1481   ASSERT1(IS_STONE(board[str]), str); 
    1482    
     1742  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
     1743 
    14831744  /* We already know the number of liberties. Just look it up. */ 
    1484   return string[string_number[str]].liberties; 
     1745  return string[string_number[str_pos]].liberties; 
    14851746} 
    14861747 
    14871748 
    1488 /* Find the liberties of the string at str. str must not be 
     1749/* Find the liberties of the string at str_pos. str_pos must not be 
    14891750 * empty. The locations of up to maxlib liberties are written into 
    14901751 * libs[]. The full number of liberties is returned. 
    14911752 * 
     
    14951756 */ 
    14961757 
    14971758int 
    1498 findlib(int str, int maxlib, int *libs) 
     1759findlib(int str_pos, int maxlib, int *libs) 
    14991760{ 
    15001761  int k; 
    15011762  int liberties; 
    1502   int s; 
    1503    
    1504   ASSERT1(IS_STONE(board[str]), str); 
    1505   ASSERT1(libs != NULL, str); 
    1506    
     1763  int to_copy; 
     1764  int str_nr; 
     1765 
     1766  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
     1767  ASSERT1(libs != NULL, str_pos); 
     1768 
    15071769  /* We already have the list of liberties and only need to copy it to 
    15081770   * libs[]. 
    15091771   * 
     
    15121774   * we have to traverse the stones in the string in order to find 
    15131775   * where the liberties are. 
    15141776   */ 
    1515   s = string_number[str]; 
    1516   liberties = string[s].liberties; 
     1777  str_nr = string_number[str_pos]; 
     1778  liberties = string[str_nr].liberties; 
     1779  to_copy = maxlib > liberties ? liberties : maxlib; 
    15171780 
    15181781  if (liberties <= MAX_LIBERTIES || maxlib <= MAX_LIBERTIES) { 
    15191782    /* The easy case, it suffices to copy liberty locations from the 
    15201783     * incrementally updated list. 
    15211784     */ 
    1522     for (k = 0; k < maxlib && k < liberties; k++) 
    1523       libs[k] = string_libs[s].list[k]; 
     1785    for (k = 0; k < to_copy; k++) 
     1786      libs[k] = string_libs[str_nr].list[k]; 
    15241787  } 
    15251788  else { 
    15261789    /* The harder case, where we have to traverse the stones in the 
     
    15281791     * the start of the chain since we will run out of liberties 
    15291792     * before that happens. 
    15301793     */ 
    1531     int pos; 
     1794    int pos, checked_pos; 
    15321795    liberty_mark++; 
    1533     for (k = 0, pos = FIRST_STONE(s); 
    1534          k < maxlib && k < liberties; 
     1796    for (k = 0, pos = FIRST_STONE(str_nr); 
     1797         k < to_copy; 
    15351798         pos = NEXT_STONE(pos)) { 
    1536       if (UNMARKED_LIBERTY(SOUTH(pos))) { 
    1537         libs[k++] = SOUTH(pos); 
    1538         MARK_LIBERTY(SOUTH(pos)); 
    1539         if (k >= maxlib) 
     1799      checked_pos = SOUTH(pos); 
     1800      if (UNMARKED_LIBERTY(checked_pos)) { 
     1801        libs[k++] = checked_pos; 
     1802        MARK_LIBERTY(checked_pos); 
     1803        if (k >= to_copy) 
    15401804          break; 
    15411805      } 
    15421806       
    1543       if (UNMARKED_LIBERTY(WEST(pos))) { 
    1544         libs[k++] = WEST(pos); 
    1545         MARK_LIBERTY(WEST(pos)); 
    1546         if (k >= maxlib) 
     1807      checked_pos = WEST(pos); 
     1808      if (UNMARKED_LIBERTY(checked_pos)) { 
     1809        libs[k++] = checked_pos; 
     1810        MARK_LIBERTY(checked_pos); 
     1811        if (k >= to_copy) 
    15471812          break; 
    15481813      } 
    15491814       
    1550       if (UNMARKED_LIBERTY(NORTH(pos))) { 
    1551         libs[k++] = NORTH(pos); 
    1552         MARK_LIBERTY(NORTH(pos)); 
    1553         if (k >= maxlib) 
     1815      checked_pos = NORTH(pos); 
     1816      if (UNMARKED_LIBERTY(checked_pos)) { 
     1817        libs[k++] = checked_pos; 
     1818        MARK_LIBERTY(checked_pos); 
     1819        if (k >= to_copy) 
    15541820          break; 
    15551821      } 
    15561822       
    1557       if (UNMARKED_LIBERTY(EAST(pos))) { 
    1558         libs[k++] = EAST(pos); 
    1559         MARK_LIBERTY(EAST(pos)); 
    1560         if (k >= maxlib) 
     1823      checked_pos = EAST(pos); 
     1824      if (UNMARKED_LIBERTY(checked_pos)) { 
     1825        libs[k++] = checked_pos; 
     1826        MARK_LIBERTY(checked_pos); 
     1827        if (k >= to_copy) 
    15611828          break; 
    15621829      } 
    15631830    } 
     
    15881855  int ally1 = -1; 
    15891856  int ally2 = -1; 
    15901857  int fast_liberties = 0; 
     1858  int checked_pos; 
     1859  int str_nr; 
    15911860 
    15921861  ASSERT1(board[pos] == EMPTY, pos); 
    15931862  ASSERT1(IS_STONE(color), pos); 
     
    15991868    ally1 = string_number[SOUTH(pos)]; 
    16001869 
    16011870    if (board[WEST(pos)] == color 
    1602         && string_number[WEST(pos)] != ally1) { 
    1603       ally2 = string_number[WEST(pos)]; 
     1871        && (str_nr = string_number[WEST(pos)]) != ally1) { 
     1872      ally2 = str_nr; 
    16041873 
    16051874      if (board[NORTH(pos)] == color 
    1606           && string_number[NORTH(pos)] != ally1 
    1607           && string_number[NORTH(pos)] != ally2) 
     1875          && (str_nr = string_number[NORTH(pos)]) != ally1 
     1876          && str_nr != ally2) 
    16081877        return -1; 
    16091878    } 
    16101879    else if (board[NORTH(pos)] == color 
    1611              && string_number[NORTH(pos)] != ally1) 
    1612       ally2 = string_number[NORTH(pos)]; 
     1880             && (str_nr = string_number[NORTH(pos)]) != ally1) 
     1881      ally2 = str_nr; 
    16131882 
    1614     if (board[EAST(pos)] == color 
    1615         && string_number[EAST(pos)] != ally1) { 
     1883    if (board[checked_pos = EAST(pos)] == color 
     1884        && string_number[checked_pos] != ally1) { 
    16161885      if (ally2 < 0) 
    1617         ally2 = string_number[EAST(pos)]; 
    1618       else if (string_number[EAST(pos)] != ally2) 
     1886        ally2 = string_number[checked_pos]; 
     1887      else if (string_number[checked_pos] != ally2) 
    16191888        return -1; 
    16201889    } 
    16211890  } 
     
    16231892    ally1 = string_number[WEST(pos)]; 
    16241893 
    16251894    if (board[NORTH(pos)] == color 
    1626         && string_number[NORTH(pos)] != ally1) { 
    1627       ally2 = string_number[NORTH(pos)]; 
     1895        && (str_nr = string_number[NORTH(pos)]) != ally1) { 
     1896      ally2 = str_nr; 
    16281897 
    16291898      if (board[EAST(pos)] == color 
    1630           && string_number[EAST(pos)] != ally1 
    1631           && string_number[EAST(pos)] != ally2) 
     1899          && (str_nr = string_number[EAST(pos)]) != ally1 
     1900          && str_nr != ally2) 
    16321901        return -1; 
    16331902    } 
    16341903    else if (board[EAST(pos)] == color 
    1635              && string_number[EAST(pos)] != ally1) 
    1636       ally2 = string_number[EAST(pos)]; 
     1904             && (str_nr = string_number[EAST(pos)]) != ally1) 
     1905      ally2 = str_nr; 
    16371906  } 
    16381907  else if (board[NORTH(pos)] == color) { 
    16391908    ally1 = string_number[NORTH(pos)]; 
    16401909     
    16411910    if (board[EAST(pos)] == color 
    1642         && string_number[EAST(pos)] != ally1) 
    1643       ally2 = string_number[EAST(pos)]; 
     1911        && (str_nr = string_number[EAST(pos)]) != ally1) 
     1912      ally2 = str_nr; 
    16441913  } 
    16451914  else if (board[EAST(pos)] == color) 
    16461915    ally1 = string_number[EAST(pos)]; 
     
    16741943      fast_liberties += string[ally1].liberties - 1; 
    16751944    } 
    16761945    else {                              /* Two allies */ 
    1677       if (LIBERTY(SOUTH(pos)) 
    1678           && !NON_SOUTH_NEIGHBOR_OF_STRING(SOUTH(pos), ally1, color) 
    1679           && !NON_SOUTH_NEIGHBOR_OF_STRING(SOUTH(pos), ally2, color)) 
     1946      int checked_pos = SOUTH(pos); 
     1947      if (LIBERTY(checked_pos) 
     1948          && !NON_SOUTH_NEIGHBOR_OF_STRING(checked_pos, ally1, color) 
     1949          && !NON_SOUTH_NEIGHBOR_OF_STRING(checked_pos, ally2, color)) 
    16801950        fast_liberties++; 
    1681       if (LIBERTY(WEST(pos)) 
    1682           && !NON_WEST_NEIGHBOR_OF_STRING(WEST(pos), ally1, color) 
    1683           && !NON_WEST_NEIGHBOR_OF_STRING(WEST(pos), ally2, color)) 
     1951      checked_pos = WEST(pos); 
     1952      if (LIBERTY(checked_pos) 
     1953          && !NON_WEST_NEIGHBOR_OF_STRING(checked_pos, ally1, color) 
     1954          && !NON_WEST_NEIGHBOR_OF_STRING(checked_pos, ally2, color)) 
    16841955        fast_liberties++; 
    1685       if (LIBERTY(NORTH(pos)) 
    1686           && !NON_NORTH_NEIGHBOR_OF_STRING(NORTH(pos), ally1, color) 
    1687           && !NON_NORTH_NEIGHBOR_OF_STRING(NORTH(pos), ally2, color)) 
     1956      checked_pos = NORTH(pos); 
     1957      if (LIBERTY(checked_pos) 
     1958          && !NON_NORTH_NEIGHBOR_OF_STRING(checked_pos, ally1, color) 
     1959          && !NON_NORTH_NEIGHBOR_OF_STRING(checked_pos, ally2, color)) 
    16881960        fast_liberties++; 
    1689       if (LIBERTY(EAST(pos)) 
    1690           && !NON_EAST_NEIGHBOR_OF_STRING(EAST(pos), ally1, color) 
    1691           && !NON_EAST_NEIGHBOR_OF_STRING(EAST(pos), ally2, color)) 
     1961      checked_pos = EAST(pos); 
     1962      if (LIBERTY(checked_pos) 
     1963          && !NON_EAST_NEIGHBOR_OF_STRING(checked_pos, ally1, color) 
     1964          && !NON_EAST_NEIGHBOR_OF_STRING(checked_pos, ally2, color)) 
    16921965        fast_liberties++; 
    16931966 
    16941967      fast_liberties += string[ally1].liberties + string[ally2].liberties 
     
    17001973   */ 
    17011974  else { 
    17021975    int k; 
     1976    int other = OTHER_COLOR(color); 
    17031977 
    17041978    for (k = 0; k < 4; k++) { 
    1705       int neighbor = pos + delta[k]; 
     1979      int neighbor_pos = pos + delta[k]; 
    17061980 
    1707       if (LIBERTY(neighbor) 
    1708           && (ally1 < 0 || !NEIGHBOR_OF_STRING(neighbor, ally1, color)) 
    1709           && (ally2 < 0 || !NEIGHBOR_OF_STRING(neighbor, ally2, color))) 
     1981      if (LIBERTY(neighbor_pos) 
     1982          && (ally1 < 0 || !NEIGHBOR_OF_STRING(neighbor_pos, ally1, color)) 
     1983          && (ally2 < 0 || !NEIGHBOR_OF_STRING(neighbor_pos, ally2, color))) 
    17101984        fast_liberties++; 
    1711       else if (board[neighbor] == OTHER_COLOR(color)    /* A capture */ 
    1712                && LIBERTIES(neighbor) == 1) { 
    1713         int neighbor_size = COUNTSTONES(neighbor); 
     1985      else if (board[neighbor_pos] == other 
     1986               && LIBERTIES(string_number[neighbor_pos]) == 1) { /* A capture */ 
     1987        int neighbor_size = COUNTSTONES(string_number[neighbor_pos]); 
    17141988 
    17151989        if (neighbor_size == 1 || (neighbor_size == 2 && ally1 < 0)) 
    17161990          fast_liberties++; 
     
    17221996    if (ally1 >= 0) { 
    17231997      fast_liberties += string[ally1].liberties - 1; 
    17241998      if (ally2 >= 0) 
    1725         fast_liberties += string[ally2].liberties 
     1999    fast_liberties += string[ally2].liberties 
    17262000          - count_common_libs(string[ally1].origin, string[ally2].origin); 
    17272001    } 
    17282002  } 
     
    17302004  return fast_liberties; 
    17312005} 
    17322006 
     2007#define USE_BOARD_CACHES 1 
    17332008 
    1734 /* Effectively true unless we store full position in hash. */ 
    1735 #define USE_BOARD_CACHES        (NUM_HASHVALUES <= 4) 
    1736  
    1737 struct board_cache_entry { 
    1738   int threshold; 
    1739   int liberties; 
    1740   Hash_data position_hash; 
    1741 }; 
    1742  
    1743  
    1744 /* approxlib() cache. */ 
     2009/* approxlib() cache. Stores data for both colors */ 
    17452010static struct board_cache_entry approxlib_cache[BOARDMAX][2]; 
    17462011 
    17472012 
     
    17512016void 
    17522017clear_approxlib_cache(void) 
    17532018{ 
    1754   int pos; 
    1755  
    1756   for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    1757     approxlib_cache[pos][0].threshold = 0; 
    1758     approxlib_cache[pos][1].threshold = 0; 
    1759   } 
     2019  memset(approxlib_cache, 0, sizeof(approxlib_cache)); 
    17602020} 
    17612021 
    17622022 
     
    17782038 
    17792039#ifdef USE_BOARD_CACHES 
    17802040 
    1781   struct board_cache_entry *entry = &approxlib_cache[pos][color - 1]; 
     2041  struct board_cache_entry *entry = &approxlib_cache[pos][color - WHITE]; 
    17822042 
    17832043  ASSERT1(board[pos] == EMPTY, pos); 
    17842044  ASSERT1(IS_STONE(color), pos); 
     
    18122072  entry->threshold = maxlib; 
    18132073 
    18142074  if (maxlib <= MAX_LIBERTIES) 
    1815     liberties = do_approxlib(pos, color, maxlib, libs); 
     2075    liberties = do_approxlib(pos, color, maxlib, libs, entry); 
    18162076  else 
    1817     liberties = slow_approxlib(pos, color, maxlib, libs); 
     2077    liberties = slow_approxlib(pos, color, maxlib, libs, entry); 
    18182078 
    18192079  entry->liberties = liberties; 
    18202080  entry->position_hash = board_hash; 
     
    18422102 
    18432103 
    18442104/* Does the real work of approxlib(). */ 
    1845 static int 
    1846 do_approxlib(int pos, int color, int maxlib, int *libs) 
     2105inline static int 
     2106do_approxlib(int pos, int color, int maxlib, int *libs, 
     2107             struct board_cache_entry *entry) 
    18472108{ 
    18482109  int k; 
    18492110  int liberties = 0; 
     2111  int checked_pos, str_nr, str_libs, checked_lib; 
    18502112 
    18512113  /* Look for empty neighbors and the liberties of the adjacent 
    18522114   * strings of the given color. The algorithm below won't work 
     
    18622124  liberty_mark++; 
    18632125  MARK_LIBERTY(pos); 
    18642126 
    1865   if (UNMARKED_LIBERTY(SOUTH(pos))) { 
    1866     if (libs != NULL) 
    1867       libs[liberties] = SOUTH(pos); 
    1868     liberties++; 
    1869     /* Stop counting if we reach maxlib. */ 
    1870     if (liberties >= maxlib) 
    1871       return liberties; 
    1872     MARK_LIBERTY(SOUTH(pos)); 
     2127  checked_pos = SOUTH(pos); 
     2128  if (board[checked_pos] == EMPTY) { 
     2129    if (ml[checked_pos] != liberty_mark) { 
     2130      if (libs != NULL) 
     2131        libs[liberties] = checked_pos; 
     2132      liberties++; 
     2133      /* Stop counting if we reach maxlib. */ 
     2134      if (liberties >= maxlib) 
     2135        return liberties; 
     2136      MARK_LIBERTY(checked_pos); 
     2137    } 
    18732138  } 
    1874   else if (board[SOUTH(pos)] == color) { 
    1875     int s = string_number[SOUTH(pos)]; 
    1876     for (k = 0; k < string[s].liberties; k++) { 
    1877       int lib = string_libs[s].list[k]; 
    1878       if (UNMARKED_LIBERTY(lib)) { 
     2139  else if (board[checked_pos] == color) { 
     2140    str_nr = string_number[checked_pos]; 
     2141    str_libs = string[str_nr].liberties; 
     2142    for (k = 0; k < str_libs; k++) { 
     2143      checked_lib = string_libs[str_nr].list[k]; 
     2144      if (UNMARKED_LIBERTY(checked_lib)) { 
    18792145        if (libs != NULL) 
    1880           libs[liberties] = lib; 
     2146          libs[liberties] = checked_lib; 
    18812147        liberties++; 
    18822148        if (liberties >= maxlib) 
    18832149          return liberties; 
    1884         MARK_LIBERTY(lib); 
     2150        MARK_LIBERTY(checked_lib); 
    18852151      } 
    18862152    } 
    18872153  } 
    18882154   
    1889   if (UNMARKED_LIBERTY(WEST(pos))) { 
    1890     if (libs != NULL) 
    1891       libs[liberties] = WEST(pos); 
    1892     liberties++; 
    1893     /* Stop counting if we reach maxlib. */ 
    1894     if (liberties >= maxlib) 
    1895       return liberties; 
    1896     MARK_LIBERTY(WEST(pos)); 
     2155  checked_pos = WEST(pos); 
     2156  if (board[checked_pos] == EMPTY) { 
     2157    if (ml[checked_pos] != liberty_mark) { 
     2158      if (libs != NULL) 
     2159        libs[liberties] = checked_pos; 
     2160      liberties++; 
     2161      /* Stop counting if we reach maxlib. */ 
     2162      if (liberties >= maxlib) 
     2163        return liberties; 
     2164      MARK_LIBERTY(checked_pos); 
     2165    } 
    18972166  } 
    1898   else if (board[WEST(pos)] == color) { 
    1899     int s = string_number[WEST(pos)]; 
    1900     for (k = 0; k < string[s].liberties; k++) { 
    1901       int lib = string_libs[s].list[k]; 
    1902       if (UNMARKED_LIBERTY(lib)) { 
     2167  else if (board[checked_pos] == color) { 
     2168    str_nr = string_number[checked_pos]; 
     2169    str_libs = string[str_nr].liberties; 
     2170    for (k = 0; k < str_libs; k++) { 
     2171      checked_lib = string_libs[str_nr].list[k]; 
     2172      if (UNMARKED_LIBERTY(checked_lib)) { 
    19032173        if (libs != NULL) 
    1904           libs[liberties] = lib; 
     2174          libs[liberties] = checked_lib; 
    19052175        liberties++; 
    19062176        if (liberties >= maxlib) 
    19072177          return liberties; 
    1908         MARK_LIBERTY(lib); 
     2178        MARK_LIBERTY(checked_lib); 
    19092179      } 
    19102180    } 
    19112181  } 
    19122182   
    1913   if (UNMARKED_LIBERTY(NORTH(pos))) { 
    1914     if (libs != NULL) 
    1915       libs[liberties] = NORTH(pos); 
    1916     liberties++; 
    1917     /* Stop counting if we reach maxlib. */ 
    1918     if (liberties >= maxlib) 
    1919       return liberties; 
    1920     MARK_LIBERTY(NORTH(pos)); 
     2183  checked_pos = NORTH(pos); 
     2184  if (board[checked_pos] == EMPTY) { 
     2185    if (ml[checked_pos] != liberty_mark) { 
     2186      if (libs != NULL) 
     2187        libs[liberties] = checked_pos; 
     2188      liberties++; 
     2189      /* Stop counting if we reach maxlib. */ 
     2190      if (liberties >= maxlib) 
     2191        return liberties; 
     2192      MARK_LIBERTY(checked_pos); 
     2193    } 
    19212194  } 
    1922   else if (board[NORTH(pos)] == color) { 
    1923     int s = string_number[NORTH(pos)]; 
    1924     for (k = 0; k < string[s].liberties; k++) { 
    1925       int lib = string_libs[s].list[k]; 
    1926       if (UNMARKED_LIBERTY(lib)) { 
     2195  else if (board[checked_pos] == color) { 
     2196    str_nr = string_number[checked_pos]; 
     2197    str_libs = string[str_nr].liberties; 
     2198    for (k = 0; k < str_libs; k++) { 
     2199      checked_lib = string_libs[str_nr].list[k]; 
     2200      if (UNMARKED_LIBERTY(checked_lib)) { 
    19272201        if (libs != NULL) 
    1928           libs[liberties] = lib; 
     2202          libs[liberties] = checked_lib; 
    19292203        liberties++; 
    19302204        if (liberties >= maxlib) 
    19312205          return liberties; 
    1932         MARK_LIBERTY(lib); 
     2206        MARK_LIBERTY(checked_lib); 
    19332207      } 
    19342208    } 
    19352209  } 
    1936    
    1937   if (UNMARKED_LIBERTY(EAST(pos))) { 
    1938     if (libs != NULL) 
    1939       libs[liberties] = EAST(pos); 
    1940     liberties++; 
    1941     /* Unneeded since we're about to leave. */ 
     2210 
     2211  checked_pos = EAST(pos); 
     2212  if (board[checked_pos] == EMPTY) { 
     2213    if (ml[checked_pos] != liberty_mark) { 
     2214      if (libs != NULL) 
     2215        libs[liberties] = checked_pos; 
     2216      liberties++; 
     2217/* Unneeded since we're about to leave. */ 
    19422218#if 0 
    1943     if (liberties >= maxlib) 
    1944       return liberties; 
    1945     MARK_LIBERTY(EAST(pos)); 
     2219      if (liberties >= maxlib) 
     2220        return liberties; 
     2221      MARK_LIBERTY(checked_pos); 
    19462222#endif 
     2223    } 
    19472224  } 
    1948   else if (board[EAST(pos)] == color) { 
    1949     int s = string_number[EAST(pos)]; 
    1950     for (k = 0; k < string[s].liberties; k++) { 
    1951       int lib = string_libs[s].list[k]; 
    1952       if (UNMARKED_LIBERTY(lib)) { 
     2225  else if (board[checked_pos] == color) { 
     2226    str_nr = string_number[checked_pos]; 
     2227    str_libs = string[str_nr].liberties; 
     2228    for (k = 0; k < str_libs; k++) { 
     2229      checked_lib = string_libs[str_nr].list[k]; 
     2230      if (UNMARKED_LIBERTY(checked_lib)) { 
    19532231        if (libs != NULL) 
    1954           libs[liberties] = lib; 
     2232          libs[liberties] = checked_lib; 
    19552233        liberties++; 
    19562234        if (liberties >= maxlib) 
    19572235          return liberties; 
    1958         MARK_LIBERTY(lib); 
     2236        MARK_LIBERTY(checked_lib); 
    19592237      } 
    19602238    } 
    1961   }   
     2239  } 
    19622240 
    19632241#if USE_BOARD_CACHES 
    19642242  /* If we reach here, then we have counted _all_ the liberties, so 
    19652243   * we set threshold to MAXLIBS (the result is the same regardless 
    19662244   * of `maxlib' value). 
    19672245   */ 
    1968   if (!libs) 
    1969     approxlib_cache[pos][color - 1].threshold = MAXLIBS; 
     2246  entry->threshold = MAXLIBS; 
    19702247#endif 
     2248 
    19712249  return liberties; 
    19722250} 
    19732251 
     
    19772255 * strings. This is a fallback used by approxlib() when a faster 
    19782256 * algorithm can't be used. 
    19792257 */ 
    1980 static int 
    1981 slow_approxlib(int pos, int color, int maxlib, int *libs) 
     2258inline static int 
     2259slow_approxlib(int pos, int color, int maxlib, int *libs, 
     2260               struct board_cache_entry *entry) 
    19822261{ 
    19832262  int k; 
    19842263  int liberties = 0; 
     2264  int checked_pos, checked_pos2; 
     2265  int pos2, str_nr, first_stone; 
    19852266 
    19862267  liberty_mark++; 
    19872268  MARK_LIBERTY(pos); 
    19882269  string_mark++; 
     2270 
    19892271  for (k = 0; k < 4; k++) { 
    1990     int d = delta[k]; 
    1991     if (UNMARKED_LIBERTY(pos + d)) { 
    1992       if (libs) 
    1993         libs[liberties] = pos + d; 
    1994       liberties++; 
    1995       if (liberties == maxlib) 
    1996         return liberties; 
    1997       MARK_LIBERTY(pos + d); 
    1998     } 
    1999     else if (board[pos + d] == color 
    2000              && UNMARKED_STRING(pos + d)) { 
    2001       int s = string_number[pos + d]; 
    2002       int pos2; 
    2003       pos2 = FIRST_STONE(s); 
     2272    checked_pos = pos + delta[k]; 
     2273    if (board[checked_pos] == EMPTY) { 
     2274      if (ml[checked_pos] != liberty_mark) { 
     2275        if (libs) 
     2276          libs[liberties] = checked_pos; 
     2277        liberties++; 
     2278        if (liberties >= maxlib) 
     2279          return liberties; 
     2280        MARK_LIBERTY(checked_pos); 
     2281      } 
     2282    } 
     2283    else if (board[checked_pos] == color 
     2284             && UNMARKED_STRING(str_nr = string_number[checked_pos])) { 
     2285      first_stone = FIRST_STONE(str_nr); 
     2286      pos2 = first_stone; 
    20042287      do { 
    20052288        int l; 
    20062289        for (l = 0; l < 4; l++) { 
    2007           int d2 = delta[l]; 
    2008           if (UNMARKED_LIBERTY(pos2 + d2)) { 
     2290          checked_pos2 = pos2 + delta[l]; 
     2291          if (UNMARKED_LIBERTY(checked_pos2)) { 
    20092292            if (libs) 
    2010               libs[liberties] = pos2 + d2; 
     2293              libs[liberties] = checked_pos2; 
    20112294            liberties++; 
    2012             if (liberties == maxlib) 
     2295            if (liberties >= maxlib) 
    20132296              return liberties; 
    2014             MARK_LIBERTY(pos2 + d2); 
     2297            MARK_LIBERTY(checked_pos2); 
    20152298          } 
    20162299        } 
    20172300 
    20182301        pos2 = NEXT_STONE(pos2); 
    2019       } while (!BACK_TO_FIRST_STONE(s, pos2)); 
    2020       MARK_STRING(pos + d); 
     2302      } while (pos2 != first_stone); 
     2303      MARK_STRING(str_nr); 
    20212304    } 
    20222305  } 
    20232306 
     
    20262309   * we set threshold to MAXLIBS (the result is the same regardless 
    20272310   * of `maxlib' value). 
    20282311   */ 
    2029   if (!libs) 
    2030     approxlib_cache[pos][color - 1].threshold = MAXLIBS; 
     2312  entry->threshold = MAXLIBS; 
    20312313#endif 
    20322314  return liberties; 
    20332315} 
    20342316 
    20352317 
    2036 /* accuratelib() cache. */ 
     2318/* accuratelib() cache. Stores data for both colors */ 
    20372319static struct board_cache_entry accuratelib_cache[BOARDMAX][2]; 
    20382320 
    20392321 
     
    20432325void 
    20442326clear_accuratelib_cache(void) 
    20452327{ 
    2046   int pos; 
    2047  
    2048   for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    2049     accuratelib_cache[pos][0].threshold = 0; 
    2050     accuratelib_cache[pos][1].threshold = 0; 
    2051   } 
     2328  memset(accuratelib_cache, 0, sizeof(accuratelib_cache)); 
    20522329} 
    20532330 
    20542331 
     
    20762353 
    20772354#ifdef USE_BOARD_CACHES 
    20782355 
    2079   struct board_cache_entry *entry = &accuratelib_cache[pos][color - 1]; 
     2356  struct board_cache_entry *entry = &accuratelib_cache[pos][color - WHITE]; 
    20802357 
    20812358  ASSERT1(board[pos] == EMPTY, pos); 
    20822359  ASSERT1(IS_STONE(color), pos); 
     
    21022379    } 
    21032380  } 
    21042381 
    2105   liberties = do_accuratelib(pos, color, maxlib, libs); 
    2106  
    2107   /* If accuratelib() found less than `maxlib' liberties, then its 
    2108    * result is certainly independent of `maxlib' and we set threshold 
    2109    * to MAXLIBS. 
     2382  /* We initialize the cache entry threshold to `maxlib'. If do_accuratelib() 
     2383   * finds all the liberties (that is, it doesn't use `maxlib' value for 
     2384   * an early return), it will set threshold to MAXLIBS itself. 
    21102385   */ 
    2111   entry->threshold = liberties < maxlib ? MAXLIBS : maxlib; 
     2386  entry->threshold = maxlib; 
     2387 
     2388  liberties = do_accuratelib(pos, color, maxlib, libs, entry); 
     2389 
    21122390  entry->liberties = liberties; 
    21132391  entry->position_hash = board_hash; 
    21142392 
     
    21322410 
    21332411 
    21342412/* Does the real work of accuratelib(). */ 
    2135 static int 
    2136 do_accuratelib(int pos, int color, int maxlib, int *libs) 
     2413inline static int 
     2414do_accuratelib(int pos, int color, int maxlib, int *libs, 
     2415               struct board_cache_entry *entry) 
    21372416{ 
    21382417  int k, l; 
    2139   int liberties = 0; 
     2418  int lib_count = 0; 
    21402419  int lib; 
    21412420  int captured[4]; 
    21422421  int captures = 0; 
     2422  int first_stone; 
     2423  int stone_pos; 
     2424  int checked_lib; 
    21432425 
    21442426  string_mark++; 
    21452427  liberty_mark++; 
    21462428  MARK_LIBERTY(pos); 
    21472429 
    21482430  for (k = 0; k < 4; k++) { 
    2149     int pos2 = pos + delta[k]; 
    2150     if (UNMARKED_LIBERTY(pos2)) { 
    2151       /* A trivial liberty */ 
    2152       if (libs) 
    2153         libs[liberties] = pos2; 
    2154       liberties++; 
    2155       if (liberties >= maxlib) 
    2156         return liberties; 
     2431    int checked_pos = pos + delta[k]; 
     2432    if (board[checked_pos] == EMPTY) { 
     2433      if (ml[checked_pos] != liberty_mark) { 
     2434        /* A trivial liberty */ 
     2435        if (libs) 
     2436          libs[lib_count] = checked_pos; 
     2437        lib_count++; 
     2438        if (lib_count >= maxlib) 
     2439          return lib_count; 
    21572440 
    2158       MARK_LIBERTY(pos2); 
    2159     } 
    2160     else if (UNMARKED_COLOR_STRING(pos2, color)) { 
    2161       /* An own neighbor string */ 
    2162       struct string_data *s = &string[string_number[pos2]]; 
    2163       struct string_liberties_data *sl = &string_libs[string_number[pos2]]; 
    2164  
    2165       if (s->liberties <= MAX_LIBERTIES || maxlib <= MAX_LIBERTIES - 1) { 
    2166         /* The easy case - we already have all (necessary) liberties of 
    2167          * the string listed 
    2168          */ 
    2169         for (l = 0; l < s->liberties; l++) { 
    2170           lib = sl->list[l]; 
    2171           if (UNMARKED_LIBERTY(lib)) { 
    2172             if (libs) 
    2173               libs[liberties] = lib; 
    2174             liberties++; 
    2175             if (liberties >= maxlib) 
    2176               return liberties; 
    2177  
    2178             MARK_LIBERTY(lib); 
    2179           } 
    2180         } 
     2441        MARK_LIBERTY(checked_pos); 
    21812442      } 
    2182       else { 
    2183         /* The harder case - we need to find all the liberties of the 
    2184          * string by traversing its stones. We stop as soon as we have 
    2185          * traversed all the stones or have reached maxlib. Unfortunately, 
    2186          * we cannot use the trick from findlib() since some of the 
    2187          * liberties may already have been marked. 
    2188          */ 
    2189         int stone = pos2; 
    2190         do { 
    2191           if (UNMARKED_LIBERTY(SOUTH(stone))) { 
    2192             if (libs) 
    2193               libs[liberties] = SOUTH(stone); 
    2194             liberties++; 
    2195             if (liberties >= maxlib) 
    2196               return liberties; 
    2197  
    2198             MARK_LIBERTY(SOUTH(stone)); 
    2199           } 
    2200  
    2201           if (UNMARKED_LIBERTY(WEST(stone))) { 
    2202             if (libs) 
    2203               libs[liberties] = WEST(stone); 
    2204             liberties++; 
    2205             if (liberties >= maxlib) 
    2206               return liberties; 
    2207  
    2208             MARK_LIBERTY(WEST(stone)); 
    2209           } 
    2210  
    2211           if (UNMARKED_LIBERTY(NORTH(stone))) { 
    2212             if (libs) 
    2213               libs[liberties] = NORTH(stone); 
    2214             liberties++; 
    2215             if (liberties >= maxlib) 
    2216               return liberties; 
    2217  
    2218             MARK_LIBERTY(NORTH(stone)); 
    2219           } 
    2220  
    2221           if (UNMARKED_LIBERTY(EAST(stone))) { 
    2222             if (libs) 
    2223               libs[liberties] = EAST(stone); 
    2224             liberties++; 
    2225             if (liberties >= maxlib) 
    2226               return liberties; 
     2443    } 
     2444    else if (board[checked_pos] == color) { 
     2445      int neighbor_nr = string_number[checked_pos]; 
     2446      if (UNMARKED_STRING(neighbor_nr)) { 
     2447        /* An own neighbor string */ 
     2448        int liberties = string[neighbor_nr].liberties; 
     2449 
     2450        if (liberties <= MAX_LIBERTIES || maxlib <= MAX_LIBERTIES - 1) { 
     2451          /* The easy case - we already have all (necessary) liberties of 
     2452           * the string listed 
     2453           */ 
     2454          struct string_liberties_data *sl = string_libs + neighbor_nr; 
     2455          for (l = 0; l < liberties; l++) { 
     2456            lib = sl->list[l]; 
     2457            if (UNMARKED_LIBERTY(lib)) { 
     2458              if (libs) 
     2459                libs[lib_count] = lib; 
     2460              lib_count++; 
     2461              if (lib_count >= maxlib) 
     2462                return lib_count; 
    22272463 
    2228             MARK_LIBERTY(EAST(stone)); 
     2464              MARK_LIBERTY(lib); 
     2465            } 
    22292466          } 
     2467        } 
     2468        else { 
     2469          /* The harder case - we need to find all the liberties of the 
     2470           * string by traversing its stones. We stop as soon as we have 
     2471           * traversed all the stones or have reached maxlib. 
     2472           */ 
     2473          stone_pos = checked_pos; 
     2474          do { 
     2475            checked_lib = SOUTH(stone_pos); 
     2476            if (UNMARKED_LIBERTY(checked_lib)) { 
     2477              if (libs) 
     2478                libs[lib_count] = checked_lib; 
     2479              lib_count++; 
     2480              if (lib_count >= maxlib) 
     2481                return lib_count; 
     2482 
     2483              MARK_LIBERTY(checked_lib); 
     2484            } 
     2485 
     2486            checked_lib = WEST(stone_pos); 
     2487            if (UNMARKED_LIBERTY(checked_lib)) { 
     2488              if (libs) 
     2489                libs[lib_count] = checked_lib; 
     2490              lib_count++; 
     2491              if (lib_count >= maxlib) 
     2492                return lib_count; 
     2493 
     2494              MARK_LIBERTY(checked_lib); 
     2495            } 
     2496 
     2497            checked_lib = NORTH(stone_pos); 
     2498            if (UNMARKED_LIBERTY(checked_lib)) { 
     2499              if (libs) 
     2500                libs[lib_count] = checked_lib; 
     2501              lib_count++; 
     2502              if (lib_count >= maxlib) 
     2503                return lib_count; 
     2504 
     2505              MARK_LIBERTY(checked_lib); 
     2506            } 
     2507 
     2508            checked_lib = EAST(stone_pos); 
     2509            if (UNMARKED_LIBERTY(checked_lib)) { 
     2510              if (libs) 
     2511                libs[lib_count] = checked_lib; 
     2512              lib_count++; 
     2513              if (lib_count >= maxlib) 
     2514                return lib_count; 
     2515 
     2516              MARK_LIBERTY(checked_lib); 
     2517            } 
     2518 
     2519            stone_pos = NEXT_STONE(stone_pos); 
     2520          } while (stone_pos != checked_pos); 
     2521        } 
    22302522 
    2231           stone = NEXT_STONE(stone); 
    2232         } while (stone != pos2); 
     2523        MARK_STRING(neighbor_nr); 
    22332524      } 
    2234  
    2235       MARK_STRING(pos2); 
    22362525    } 
    2237     else if (board[pos2] == OTHER_COLOR(color) 
    2238              && string[string_number[pos2]].liberties == 1) { 
     2526    else if (board[checked_pos] == OTHER_COLOR(color) 
     2527             && string[string_number[checked_pos]].liberties == 1) { 
    22392528      /* A capture. */ 
    2240       captured[captures++] = pos2; 
     2529      captured[captures++] = checked_pos; 
    22412530    } 
    22422531  } 
    22432532 
    22442533  /* Now we look at all the captures found in the previous step */ 
    22452534  for (k = 0; k < captures; k++) { 
    2246     lib = captured[k]; 
     2535    int capture_nr; 
     2536    first_stone = captured[k]; 
    22472537 
    22482538    /* Add the stone adjacent to (pos) to the list of liberties if 
    22492539     * it is not also adjacent to an own marked string (otherwise, 
    22502540     * it will be added later). 
    22512541     */ 
    2252     if (!MARKED_COLOR_STRING(SOUTH(lib), color) 
    2253         && !MARKED_COLOR_STRING(WEST(lib), color) 
    2254         && !MARKED_COLOR_STRING(NORTH(lib), color) 
    2255         && !MARKED_COLOR_STRING(EAST(lib), color)) { 
     2542    if (!MARKED_COLOR_STRING(SOUTH(first_stone), color) 
     2543        && !MARKED_COLOR_STRING(WEST(first_stone), color) 
     2544        && !MARKED_COLOR_STRING(NORTH(first_stone), color) 
     2545        && !MARKED_COLOR_STRING(EAST(first_stone), color)) { 
    22562546      if (libs) 
    2257         libs[liberties] = lib; 
    2258       liberties++; 
    2259       if (liberties >= maxlib) 
    2260         return liberties; 
     2547        libs[lib_count] = first_stone; 
     2548      lib_count++; 
     2549      if (lib_count >= maxlib) 
     2550        return lib_count; 
     2551      stone_pos = NEXT_STONE(first_stone); 
     2552      if (stone_pos == first_stone) 
     2553        continue; 
    22612554    } 
     2555    else 
     2556      stone_pos = first_stone; 
    22622557 
    22632558    /* Check if we already know of this capture. */ 
     2559    capture_nr = string_number[stone_pos]; 
    22642560    for (l = 0; l < k; l++) 
    2265       if (string_number[captured[l]] == string_number[lib]) 
     2561      if (string_number[captured[l]] == capture_nr) 
    22662562        break; 
    22672563 
    22682564    if (l == k) { 
     
    22712567       * marked string. 
    22722568       */ 
    22732569      do { 
    2274         if (MARKED_COLOR_STRING(SOUTH(lib), color) 
    2275             || MARKED_COLOR_STRING(WEST(lib), color) 
    2276             || MARKED_COLOR_STRING(NORTH(lib), color) 
    2277             || MARKED_COLOR_STRING(EAST(lib), color)) { 
     2570        if (MARKED_COLOR_STRING(SOUTH(stone_pos), color) 
     2571            || MARKED_COLOR_STRING(WEST(stone_pos), color) 
     2572            || MARKED_COLOR_STRING(NORTH(stone_pos), color) 
     2573            || MARKED_COLOR_STRING(EAST(stone_pos), color)) { 
    22782574          if (libs) 
    2279             libs[liberties] = lib; 
    2280           liberties++; 
    2281           if (liberties >= maxlib) 
    2282             return liberties; 
     2575            libs[lib_count] = stone_pos; 
     2576          lib_count++; 
     2577          if (lib_count >= maxlib) 
     2578            return lib_count; 
    22832579        } 
    22842580 
    2285         lib = NEXT_STONE(lib); 
    2286       } while (lib != captured[k]); 
     2581        stone_pos = NEXT_STONE(stone_pos); 
     2582      } while (stone_pos != first_stone); 
    22872583    } 
    22882584  } 
    22892585 
    2290   return liberties; 
    2291 } 
     2586#if USE_BOARD_CACHES 
     2587  /* If we reach here, then we have counted _all_ the liberties, so 
     2588   * we set threshold to MAXLIBS (the result is the same regardless 
     2589   * of `maxlib' value). 
     2590   */ 
     2591  entry->threshold = MAXLIBS; 
     2592#endif 
    22922593 
     2594  return lib_count; 
     2595} 
    22932596 
    2294 /* Find the number of common liberties of the two strings at str1 and str2. 
     2597/* Find the number of common liberties of the two strings at 
     2598 * str1_pos and str2_pos. 
    22952599 */ 
    22962600 
    22972601int 
    2298 count_common_libs(int str1, int str2) 
     2602count_common_libs(int str1_pos, int str2_pos) 
    22992603{ 
    23002604  int all_libs1[MAXLIBS], *libs1; 
    23012605  int liberties1, liberties2; 
     2606  int str1_nr, str2_nr; 
    23022607  int commonlibs = 0; 
    2303   int k, n, tmp; 
    2304    
    2305   ASSERT_ON_BOARD1(str1); 
    2306   ASSERT_ON_BOARD1(str2); 
    2307   ASSERT1(IS_STONE(board[str1]), str1); 
    2308   ASSERT1(IS_STONE(board[str2]), str2); 
    2309    
    2310   n = string_number[str1]; 
    2311   liberties1 = string[n].liberties; 
    2312    
    2313   if (liberties1 > string[string_number[str2]].liberties) { 
    2314     n = string_number[str2]; 
    2315     liberties1 = string[n].liberties; 
    2316     tmp = str1; 
    2317     str1 = str2; 
    2318     str2 = tmp; 
     2608  int k; 
     2609  int color; 
     2610 
     2611  ASSERT_ON_BOARD1(str1_pos); 
     2612  ASSERT_ON_BOARD1(str2_pos); 
     2613  ASSERT1(IS_STONE(board[str1_pos]), str1_pos); 
     2614  ASSERT1(IS_STONE(board[str2_pos]), str2_pos); 
     2615 
     2616  str1_nr = string_number[str1_pos]; 
     2617  str2_nr = string_number[str2_pos]; 
     2618  liberties1 = string[str1_nr].liberties; 
     2619  liberties2 = string[str2_nr].liberties; 
     2620   
     2621  if (liberties1 > liberties2) { 
     2622    int tmp; 
     2623    tmp = liberties1; 
     2624    liberties1 = liberties2; 
     2625    liberties2 = tmp; 
     2626    tmp = str1_nr; 
     2627    str1_nr = str2_nr; 
     2628    str2_nr = tmp; 
    23192629  } 
    23202630 
    23212631  if (liberties1 <= MAX_LIBERTIES) { 
    23222632    /* Speed optimization: don't copy liberties with findlib */ 
    2323     libs1 = string_libs[n].list; 
    2324     n = string_number[str2]; 
    2325     liberties2 = string[n].liberties; 
     2633    libs1 = string_libs[str1_nr].list; 
    23262634     
    23272635    if (liberties2 <= MAX_LIBERTIES) { 
    23282636      /* Speed optimization: NEIGHBOR_OF_STRING is quite expensive */ 
     
    23312639      for (k = 0; k < liberties1; k++) 
    23322640        MARK_LIBERTY(libs1[k]); 
    23332641 
    2334       libs1 = string_libs[n].list; 
     2642      libs1 = string_libs[str2_nr].list; 
    23352643      for (k = 0; k < liberties2; k++) 
    2336         if (!UNMARKED_LIBERTY(libs1[k])) 
     2644        if (ml[libs1[k]] == liberty_mark) 
    23372645          commonlibs++; 
    23382646 
    23392647      return commonlibs; 
    23402648    } 
    23412649  } 
    23422650  else { 
    2343     findlib(str1, MAXLIBS, all_libs1); 
     2651    findlib(str1_pos, MAXLIBS, all_libs1); 
    23442652    libs1 = all_libs1; 
    23452653  } 
    23462654   
     2655  color = string[str2_nr].color; 
    23472656  for (k = 0; k < liberties1; k++) 
    2348     if (NEIGHBOR_OF_STRING(libs1[k], string_number[str2], board[str2])) 
     2657    if (NEIGHBOR_OF_STRING(libs1[k], str2_nr, color)) 
    23492658      commonlibs++; 
    23502659   
    23512660  return commonlibs; 
    23522661} 
    23532662 
    2354  
    2355 /* Find the common liberties of the two strings at str1 and str2. The 
    2356  * locations of up to maxlib common liberties are written into libs[]. 
    2357  * The full number of common liberties is returned. 
     2663/* Find the common liberties of the two strings at str1_pos and 
     2664 * str2_pos. The locations of up to maxlib common liberties are 
     2665 * written into libs[]. The full number of common liberties is returned. 
    23582666 * 
    23592667 * If you want the locations of all common liberties, whatever their 
    23602668 * number, you should pass MAXLIBS as the value for maxlib and 
     
    23622670 */ 
    23632671 
    23642672int 
    2365 find_common_libs(int str1, int str2, int maxlib, int *libs) 
     2673find_common_libs(int str1_pos, int str2_pos, int maxlib, int *libs) 
    23662674{ 
    23672675  int all_libs1[MAXLIBS], *libs1; 
    23682676  int liberties1, liberties2; 
     2677  int str1_nr, str2_nr; 
    23692678  int commonlibs = 0; 
    2370   int k, n, tmp; 
    2371    
    2372   ASSERT_ON_BOARD1(str1); 
    2373   ASSERT_ON_BOARD1(str2); 
    2374   ASSERT1(IS_STONE(board[str1]), str1); 
    2375   ASSERT1(IS_STONE(board[str2]), str2); 
    2376   ASSERT1(libs != NULL, str1); 
    2377    
    2378   n = string_number[str1]; 
    2379   liberties1 = string[n].liberties; 
    2380    
    2381   if (liberties1 > string[string_number[str2]].liberties) { 
    2382     n = string_number[str2]; 
    2383     liberties1 = string[n].liberties; 
    2384     tmp = str1; 
    2385     str1 = str2; 
    2386     str2 = tmp; 
     2679  int k; 
     2680  int color; 
     2681 
     2682  ASSERT_ON_BOARD1(str1_pos); 
     2683  ASSERT_ON_BOARD1(str2_pos); 
     2684  ASSERT1(IS_STONE(board[str1_pos]), str1_pos); 
     2685  ASSERT1(IS_STONE(board[str2_pos]), str2_pos); 
     2686  ASSERT1(libs != NULL, str1_pos); 
     2687 
     2688  str1_nr = string_number[str1_pos]; 
     2689  str2_nr = string_number[str2_pos]; 
     2690  liberties1 = string[str1_nr].liberties; 
     2691  liberties2 = string[str2_nr].liberties; 
     2692   
     2693  if (liberties1 > liberties2) { 
     2694    int tmp; 
     2695    tmp = liberties1; 
     2696    liberties1 = liberties2; 
     2697    liberties2 = tmp; 
     2698    tmp = str1_nr; 
     2699    str1_nr = str2_nr; 
     2700    str2_nr = tmp; 
    23872701  } 
    23882702   
    23892703  if (liberties1 <= MAX_LIBERTIES) { 
    23902704    /* Speed optimization: don't copy liberties with findlib */ 
    2391     libs1 = string_libs[n].list; 
    2392     n = string_number[str2]; 
    2393     liberties2 = string[n].liberties; 
     2705    libs1 = string_libs[str1_nr].list; 
    23942706 
    23952707    if (liberties2 <= MAX_LIBERTIES) { 
    23962708      /* Speed optimization: NEIGHBOR_OF_STRING is quite expensive */ 
     
    23992711      for (k = 0; k < liberties1; k++) 
    24002712        MARK_LIBERTY(libs1[k]); 
    24012713       
    2402       libs1 = string_libs[n].list; 
     2714      libs1 = string_libs[str2_nr].list; 
    24032715      for (k = 0; k < liberties2; k++) 
    2404         if (!UNMARKED_LIBERTY(libs1[k])) { 
     2716        if (ml[libs1[k]] == liberty_mark) { 
    24052717          if (commonlibs < maxlib) 
    24062718            libs[commonlibs] = libs1[k]; 
    24072719          commonlibs++; 
     
    24112723    } 
    24122724  } 
    24132725  else { 
    2414     findlib(str1, MAXLIBS, all_libs1); 
     2726    findlib(str1_pos, MAXLIBS, all_libs1); 
    24152727    libs1 = all_libs1; 
    24162728  } 
    24172729   
     2730  color = string[str2_nr].color; 
    24182731  for (k = 0; k < liberties1; k++) 
    2419     if (NEIGHBOR_OF_STRING(libs1[k], string_number[str2], board[str2])) { 
     2732    if (NEIGHBOR_OF_STRING(libs1[k], str2_nr, color)) { 
    24202733      if (commonlibs < maxlib) 
    24212734        libs[commonlibs] = libs1[k]; 
    24222735      commonlibs++; 
     
    24302743 * If they do and lib != NULL, one common liberty is returned in *lib. 
    24312744 */ 
    24322745int 
    2433 have_common_lib(int str1, int str2, int *lib) 
     2746have_common_lib(int str1_pos, int str2_pos, int *lib) 
    24342747{ 
    24352748  int all_libs1[MAXLIBS], *libs1; 
    2436   int liberties1; 
    2437   int k, n, tmp; 
    2438    
    2439   ASSERT_ON_BOARD1(str1); 
    2440   ASSERT_ON_BOARD1(str2); 
    2441   ASSERT1(IS_STONE(board[str1]), str1); 
    2442   ASSERT1(IS_STONE(board[str2]), str2); 
    2443    
    2444   n = string_number[str1]; 
    2445   liberties1 = string[n].liberties; 
    2446    
    2447   if (liberties1 > string[string_number[str2]].liberties) { 
    2448     n = string_number[str2]; 
    2449     liberties1 = string[n].liberties; 
    2450     tmp = str1; 
    2451     str1 = str2; 
    2452     str2 = tmp; 
     2749  int liberties1, liberties2; 
     2750  int str1_nr, str2_nr; 
     2751  int k; 
     2752  int color; 
     2753 
     2754  ASSERT_ON_BOARD1(str1_pos); 
     2755  ASSERT_ON_BOARD1(str2_pos); 
     2756  ASSERT1(IS_STONE(board[str1_pos]), str1_pos); 
     2757  ASSERT1(IS_STONE(board[str2_pos]), str2_pos); 
     2758 
     2759  str1_nr = string_number[str1_pos]; 
     2760  str2_nr = string_number[str2_pos]; 
     2761  liberties1 = string[str1_nr].liberties; 
     2762  liberties2 = string[str2_nr].liberties; 
     2763   
     2764  if (liberties1 > liberties2) { 
     2765    int tmp; 
     2766    tmp = liberties1; 
     2767    liberties1 = liberties2; 
     2768    liberties2 = tmp; 
     2769    tmp = str1_nr; 
     2770    str1_nr = str2_nr; 
     2771    str2_nr = tmp; 
    24532772  } 
    24542773   
    24552774  if (liberties1 <= MAX_LIBERTIES) 
    24562775    /* Speed optimization: don't copy liberties with findlib */ 
    2457     libs1 = string_libs[n].list; 
     2776    libs1 = string_libs[str1_nr].list; 
    24582777  else { 
    2459     findlib(str1, MAXLIBS, all_libs1); 
     2778    findlib(str1_pos, MAXLIBS, all_libs1); 
    24602779    libs1 = all_libs1; 
    24612780  } 
    24622781 
     2782  color = string[str2_nr].color; 
    24632783  for (k = 0; k < liberties1; k++) { 
    2464     if (NEIGHBOR_OF_STRING(libs1[k], string_number[str2], board[str2])) { 
     2784    if (NEIGHBOR_OF_STRING(libs1[k], str2_nr, color)) { 
    24652785      if (lib) 
    24662786        *lib = libs1[k]; 
    24672787      return 1; 
     
    24782798 */ 
    24792799 
    24802800int 
    2481 countstones(int str) 
     2801countstones(int str_pos) 
    24822802{ 
    2483   ASSERT_ON_BOARD1(str); 
    2484   ASSERT1(IS_STONE(board[str]), str); 
     2803  ASSERT_ON_BOARD1(str_pos); 
     2804  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
    24852805 
    2486   return COUNTSTONES(str); 
     2806  return COUNTSTONES(string_number[str_pos]); 
    24872807} 
    24882808 
    24892809 
    2490 /* Find the stones of the string at str. str must not be 
     2810/* Find the stones of the string at str_pos. str_pos must not be 
    24912811 * empty. The locations of up to maxstones stones are written into 
    24922812 * stones[]. The full number of stones is returned. 
    24932813 */ 
    24942814 
    24952815int 
    2496 findstones(int str, int maxstones, int *stones) 
     2816findstones(int str_pos, int maxstones, int *stones) 
    24972817{ 
    2498   int s; 
     2818  int str_nr; 
    24992819  int size; 
    25002820  int pos; 
    25012821  int k; 
    2502    
    2503   ASSERT_ON_BOARD1(str); 
    2504   ASSERT1(IS_STONE(board[str]), str); 
     2822  int limit; 
    25052823 
    2506   s = string_number[str]; 
    2507   size = string[s].size; 
     2824  ASSERT_ON_BOARD1(str_pos); 
     2825  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
     2826 
     2827  str_nr = string_number[str_pos]; 
     2828  size = string[str_nr].size; 
    25082829   
    25092830  /* Traverse the stones of the string, by following the cyclic chain. */ 
    2510   pos = FIRST_STONE(s); 
    2511   for (k = 0; k < maxstones && k < size; k++) { 
     2831  pos = FIRST_STONE(str_nr); 
     2832  limit = maxstones > size ? size : maxstones; 
     2833  for (k = 0; k < limit; k++) { 
    25122834    stones[k] = pos; 
    25132835    pos = NEXT_STONE(pos); 
    25142836  } 
     
    25172839} 
    25182840 
    25192841 
    2520 /* Counts how many stones in str1 are directly adjacent to str2. 
    2521  * A limit can be given in the maxstones parameter so that the 
    2522  * function returns immediately. See fast_defense() in reading.c 
     2842/* Counts how many stones in one string are directly adjacent to 
     2843 * the second string. A limit can be given in the maxstones parameter 
     2844 * so that the function returns immediately. 
    25232845 */ 
    25242846 
    25252847int 
    2526 count_adjacent_stones(int str1, int str2, int maxstones) 
     2848count_adjacent_stones(int str1_pos, int str2_pos, int maxstones) 
    25272849{ 
    2528   int s1, s2; 
     2850  int str1_nr, str2_nr; 
    25292851  int size; 
    25302852  int pos; 
    25312853  int k; 
    25322854  int count = 0; 
     2855  int color2; 
    25332856 
    2534   ASSERT_ON_BOARD1(str1); 
    2535   ASSERT1(IS_STONE(board[str1]), str1); 
    2536   ASSERT_ON_BOARD1(str2); 
    2537   ASSERT1(IS_STONE(board[str2]), str2); 
    2538  
    2539   s1 = string_number[str1]; 
    2540   s2 = string_number[str2]; 
    2541   size = string[s1].size; 
     2857  ASSERT_ON_BOARD1(str1_pos); 
     2858  ASSERT1(IS_STONE(board[str1_pos]), str1_pos); 
     2859  ASSERT_ON_BOARD1(str2_pos); 
     2860  ASSERT1(IS_STONE(board[str2_pos]), str2_pos); 
     2861 
     2862  str1_nr = string_number[str1_pos]; 
     2863  str2_nr = string_number[str2_pos]; 
     2864  size = string[str1_nr].size; 
    25422865 
    25432866  /* Traverse the stones of the string, by following the cyclic chain. */ 
    2544   pos = FIRST_STONE(s1); 
    2545   for (k = 0; k < size && count < maxstones; k++) { 
    2546     if (NEIGHBOR_OF_STRING(pos, s2, board[str2])) 
     2867  color2 = board[str2_pos]; 
     2868  pos = FIRST_STONE(str1_nr); 
     2869  for (k = 0; k < size; k++) { 
     2870    if (NEIGHBOR_OF_STRING(pos, str2_nr, color2)) { 
    25472871      count++; 
     2872      if (count >= maxstones) 
     2873        return count; 
     2874    } 
    25482875    pos = NEXT_STONE(pos); 
    25492876  } 
    25502877 
     
    25532880 
    25542881 
    25552882/* chainlinks returns (in the (adj) array) the chains surrounding 
    2556  * the string at (str). The number of chains is returned. 
     2883 * the string at (str_pos). The number of chains is returned. 
    25572884 */ 
    25582885 
    25592886int  
    2560 chainlinks(int str, int adj[MAXCHAIN]) 
     2887chainlinks(int str_pos, int adj[MAXCHAIN]) 
    25612888{ 
    2562   struct string_data *s; 
    25632889  struct string_neighbors_data *sn; 
    25642890  int k; 
     2891  int neighbors; 
    25652892 
    2566   ASSERT1(IS_STONE(board[str]), str); 
     2893  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
    25672894 
    25682895  /* We already have the list ready, just copy it and fill in the 
    25692896   * desired information. 
    25702897   */ 
    2571   s = &string[string_number[str]]; 
    2572   sn = &string_neighbors[string_number[str]]; 
    2573   for (k = 0; k < s->neighbors; k++) 
     2898  neighbors = string[string_number[str_pos]].neighbors; 
     2899  sn = string_neighbors + string_number[str_pos]; 
     2900  for (k = 0; k < neighbors; k++) 
    25742901    adj[k] = string[sn->list[k]].origin; 
    25752902 
    2576   return s->neighbors; 
     2903  return neighbors; 
    25772904} 
    25782905 
    25792906 
    25802907/* chainlinks2 returns (in adj array) those chains surrounding 
    2581  * the string at str which have exactly lib liberties. The number 
    2582  * of such chains is returned. 
     2908 * the string at str_pos which have exactly lib liberties. 
     2909 * The number of such chains is returned. 
    25832910 */ 
    25842911 
    25852912int 
    2586 chainlinks2(int str, int adj[MAXCHAIN], int lib) 
     2913chainlinks2(int str_pos, int adj[MAXCHAIN], int lib) 
    25872914{ 
    2588   struct string_data *s, *t; 
    25892915  struct string_neighbors_data *sn; 
    25902916  int k; 
    2591   int neighbors; 
     2917  int neighbors, max_neighbors; 
    25922918 
    2593   ASSERT1(IS_STONE(board[str]), str); 
     2919  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
    25942920 
    25952921  /* We already have the list ready, just copy the strings with the 
    25962922   * right number of liberties. 
    25972923   */ 
    25982924  neighbors = 0; 
    2599   s = &string[string_number[str]]; 
    2600   sn = &string_neighbors[string_number[str]]; 
    2601   for (k = 0; k < s->neighbors; k++) { 
    2602     t = &string[sn->list[k]]; 
    2603     if (t->liberties == lib) 
    2604       adj[neighbors++] = t->origin; 
     2925  max_neighbors = string[string_number[str_pos]].neighbors; 
     2926  sn = string_neighbors + string_number[str_pos]; 
     2927  for (k = 0; k < max_neighbors; k++) { 
     2928    if (string[sn->list[k]].liberties == lib) 
     2929      adj[neighbors++] = string[sn->list[k]].origin; 
    26052930  } 
    26062931  return neighbors; 
    26072932} 
    26082933 
    26092934 
    26102935/* chainlinks3 returns (in adj array) those chains surrounding 
    2611  * the string at str, which have less or equal lib liberties. 
     2936 * the string at str_pos, which have less or equal lib liberties. 
    26122937 * The number of such chains is returned. 
    26132938 */ 
    26142939 
    26152940int 
    2616 chainlinks3(int str, int adj[MAXCHAIN], int lib) 
     2941chainlinks3(int str_pos, int adj[MAXCHAIN], int lib) 
    26172942{ 
    2618   struct string_data *s, *t; 
    26192943  struct string_neighbors_data *sn; 
    26202944  int k; 
    2621   int neighbors; 
     2945  int neighbors, max_neighbors; 
    26222946 
    2623   ASSERT1(IS_STONE(board[str]), str); 
     2947  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
    26242948 
    26252949  /* We already have the list ready, just copy the strings with the 
    26262950   * right number of liberties. 
    26272951   */ 
    26282952  neighbors = 0; 
    2629   s = &string[string_number[str]]; 
    2630   sn = &string_neighbors[string_number[str]]; 
    2631   for (k = 0; k < s->neighbors; k++) { 
    2632     t = &string[sn->list[k]]; 
    2633     if (t->liberties <= lib) 
    2634       adj[neighbors++] = t->origin; 
     2953  max_neighbors = string[string_number[str_pos]].neighbors; 
     2954  sn = string_neighbors + string_number[str_pos]; 
     2955  for (k = 0; k < max_neighbors; k++) { 
     2956    if (string[sn->list[k]].liberties <= lib) 
     2957      adj[neighbors++] = string[sn->list[k]].origin; 
    26352958  } 
    26362959  return neighbors; 
    26372960} 
    26382961 
    26392962 
    26402963/* extended_chainlinks() returns (in the (adj) array) the opponent 
    2641  * strings being directly adjacent to (str) or having a common liberty 
    2642  * with (str). The number of such strings is returned. 
     2964 * strings being directly adjacent to string at (str_pos) or having 
     2965 * a common liberty with that string. The number of such strings is 
     2966 * returned. 
    26432967 * 
    26442968 * If the both_colors parameter is true, also own strings sharing a 
    26452969 * liberty are returned. 
    26462970 */ 
    26472971 
    26482972int  
    2649 extended_chainlinks(int str, int adj[MAXCHAIN], int both_colors) 
     2973extended_chainlinks(int str_pos, int adj[MAXCHAIN], int both_colors) 
    26502974{ 
    2651   struct string_data *s; 
    26522975  struct string_neighbors_data *sn; 
    26532976  int n; 
    2654   int k; 
    26552977  int r; 
    26562978  int libs[MAXLIBS]; 
    26572979  int liberties; 
     2980  int checked_pos; 
     2981  int color; 
     2982  int other; 
     2983  int neighbors; 
     2984  int str_nr; 
    26582985 
    2659   ASSERT1(IS_STONE(board[str]), str); 
     2986  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
     2987 
     2988  str_nr = string_number[str_pos]; 
     2989  color = string[str_nr].color; 
     2990  other = OTHER_COLOR(color); 
     2991  sn = string_neighbors + str_nr; 
     2992  string_mark++; 
    26602993 
    26612994  /* We already have the list of directly adjacent strings ready, just 
    2662    * copy it and mark the strings. 
     2995   * copy it and mark the strings. We also mark ourselves in case 
     2996   * both_colors is true. 
    26632997   */ 
    2664   s = &string[string_number[str]]; 
    2665   sn = &string_neighbors[string_number[str]]; 
    2666   string_mark++; 
    2667   for (n = 0; n < s->neighbors; n++) { 
     2998  MARK_STRING(str_nr); 
     2999 
     3000  neighbors = string[str_nr].neighbors; 
     3001  for (n = 0; n < neighbors; n++) { 
    26683002    adj[n] = string[sn->list[n]].origin; 
    2669     MARK_STRING(adj[n]); 
     3003    MARK_STRING(sn->list[n]); 
    26703004  } 
    26713005 
    26723006  /* Get the liberties. */ 
    2673   liberties = findlib(str, MAXLIBS, libs); 
     3007  liberties = findlib(str_pos, MAXLIBS, libs); 
    26743008 
    2675   /* Look for unmarked opponent strings next to a liberty and add the 
     3009  /* Look for unmarked strings next to a liberty and add the 
    26763010   * ones which are found to the output. 
    26773011   */ 
    26783012  for (r = 0; r < liberties; r++) { 
    2679     for (k = 0; k < 4; k++) { 
    2680       if ((board[libs[r] + delta[k]] == OTHER_COLOR(board[str]) 
    2681            || (both_colors && board[libs[r] + delta[k]] == board[str])) 
    2682           && UNMARKED_STRING(libs[r] + delta[k])) { 
    2683         adj[n] = string[string_number[libs[r] + delta[k]]].origin; 
    2684         MARK_STRING(adj[n]); 
    2685         n++; 
     3013    checked_pos = SOUTH(libs[r]); 
     3014    if (board[checked_pos] == other 
     3015        || (both_colors && board[checked_pos] == color)) { 
     3016      str_nr = string_number[checked_pos]; 
     3017      if (UNMARKED_STRING(str_nr)) { 
     3018        MARK_STRING(str_nr); 
     3019        adj[n++] = string[str_nr].origin; 
     3020      } 
     3021    } 
     3022 
     3023    checked_pos = WEST(libs[r]); 
     3024    if (board[checked_pos] == other 
     3025        || (both_colors && board[checked_pos] == color)) { 
     3026      str_nr = string_number[checked_pos]; 
     3027      if (UNMARKED_STRING(str_nr)) { 
     3028        MARK_STRING(str_nr); 
     3029        adj[n++] = string[str_nr].origin; 
     3030      } 
     3031    } 
     3032 
     3033    checked_pos = NORTH(libs[r]); 
     3034    if (board[checked_pos] == other 
     3035        || (both_colors && board[checked_pos] == color)) { 
     3036      str_nr = string_number[checked_pos]; 
     3037      if (UNMARKED_STRING(str_nr)) { 
     3038        MARK_STRING(str_nr); 
     3039        adj[n++] = string[str_nr].origin; 
     3040      } 
     3041    } 
     3042 
     3043    checked_pos = EAST(libs[r]); 
     3044    if (board[checked_pos] == other 
     3045        || (both_colors && board[checked_pos] == color)) { 
     3046      str_nr = string_number[checked_pos]; 
     3047      if (UNMARKED_STRING(str_nr)) { 
     3048        MARK_STRING(str_nr); 
     3049        adj[n++] = string[str_nr].origin; 
    26863050      } 
    26873051    } 
    26883052  } 
     
    26983062 */ 
    26993063 
    27003064int 
    2701 find_origin(int str) 
     3065find_origin(int str_pos) 
    27023066{ 
    2703   ASSERT1(IS_STONE(board[str]), str); 
     3067  ASSERT_ON_BOARD1(str_pos); 
     3068  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
    27043069 
    2705   return string[string_number[str]].origin; 
     3070  return string[string_number[str_pos]].origin; 
    27063071} 
    27073072 
    27083073 
     
    27233088   * has more than one spare liberty we immediately return 0. 
    27243089   */ 
    27253090  int far_liberties = 0; 
     3091  int checked_pos; 
     3092  int stone; 
     3093  int liberties; 
    27263094   
    27273095  ASSERT_ON_BOARD1(pos); 
    27283096  ASSERT1(board[pos] == EMPTY, pos); 
     
    27313099  /* 1. Try first to solve the problem without much work. */ 
    27323100  string_mark++; 
    27333101   
    2734   if (LIBERTY(SOUTH(pos))) 
     3102  checked_pos = SOUTH(pos); 
     3103  stone = board[checked_pos]; 
     3104  if (stone == EMPTY) 
    27353105    trivial_liberties++; 
    2736   else if (board[SOUTH(pos)] == color) { 
    2737     if (LIBERTIES(SOUTH(pos)) > 2) 
     3106  else if (stone == color) { 
     3107    liberties = LIBERTIES(string_number[checked_pos]); 
     3108    if (liberties > 2) 
    27383109      return 0; 
    2739     if (LIBERTIES(SOUTH(pos)) == 2) 
     3110    if (liberties == 2) 
    27403111      far_liberties++; 
    27413112  } 
    2742   else if (board[SOUTH(pos)] == other 
    2743           && LIBERTIES(SOUTH(pos)) == 1 && UNMARKED_STRING(SOUTH(pos))) { 
    2744     captures++; 
    2745     MARK_STRING(SOUTH(pos)); 
     3113  else if (stone == other) { 
     3114    int str_nr = string_number[checked_pos]; 
     3115    if (LIBERTIES(str_nr) == 1 && UNMARKED_STRING(str_nr)) { 
     3116      MARK_STRING(str_nr); 
     3117      captures++; 
     3118    } 
    27463119  } 
    27473120 
    2748   if (LIBERTY(WEST(pos))) 
     3121  checked_pos = WEST(pos); 
     3122  stone = board[checked_pos]; 
     3123  if (stone == EMPTY) 
    27493124    trivial_liberties++; 
    2750   else if (board[WEST(pos)] == color) { 
    2751     if (LIBERTIES(WEST(pos)) > 2) 
     3125  else if (stone == color) { 
     3126    liberties = LIBERTIES(string_number[checked_pos]); 
     3127    if (liberties > 2) 
    27523128      return 0; 
    2753     if (LIBERTIES(WEST(pos)) == 2) 
     3129    if (liberties == 2) 
    27543130      far_liberties++; 
    27553131  } 
    2756   else if (board[WEST(pos)] == other 
    2757           && LIBERTIES(WEST(pos)) == 1 && UNMARKED_STRING(WEST(pos))) { 
    2758     captures++; 
    2759     MARK_STRING(WEST(pos)); 
     3132  else if (stone == other) { 
     3133    int str_nr = string_number[checked_pos]; 
     3134    if (LIBERTIES(str_nr) == 1 && UNMARK