Ticket #148: unconditional.diff

File unconditional.diff, 13.8 kB (added by draqo, 2 years ago)

cleanup patch nr 2 (apply after patch nr 1)

  • engine/board.c

    diff -r -u -X .ignore gnugo-copy/engine/board.c gnugo/engine/board.c
    old new  
    22 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see       * 
    33 * http://www.gnu.org/software/gnugo/ for more information.          * 
    44 *                                                                   * 
    5  * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006      * 
     5 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 * 
    66 * by the Free Software Foundation.                                  * 
    77 *                                                                   * 
    88 * This program is free software; you can redistribute it and/or     * 
     
    17781778  liberties = string[str_nr].liberties; 
    17791779  to_copy = maxlib > liberties ? liberties : maxlib; 
    17801780 
    1781   if (liberties <= MAX_LIBERTIES || maxlib <= MAX_LIBERTIES) { 
     1781  if (to_copy <= MAX_LIBERTIES) { 
    17821782    /* The easy case, it suffices to copy liberty locations from the 
    17831783     * incrementally updated list. 
    17841784     */ 
  • engine/unconditional.c

    diff -r -u -X .ignore gnugo-copy/engine/unconditional.c gnugo/engine/unconditional.c
    old new  
    22 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see       * 
    33 * http://www.gnu.org/software/gnugo/ for more information.          * 
    44 *                                                                   * 
    5  * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006      * 
     5 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 * 
    66 * by the Free Software Foundation.                                  * 
    77 *                                                                   * 
    88 * This program is free software; you can redistribute it and/or     * 
     
    4141{ 
    4242  int other = OTHER_COLOR(color); 
    4343  int something_captured = 1; /* To get into the first turn of the loop. */ 
    44   int string_found = 0; 
     44  int invincible_found = 0; 
    4545  int moves_played = 0; 
    4646  int save_moves; 
    4747  int libs[MAXLIBS]; 
     
    5353    /* Nothing captured so far in this turn of the loop. */ 
    5454    something_captured = 0; 
    5555 
    56     /* Is there something left to try to capture? */ 
    57     string_found = 0; 
     56    /* If we found any invincible string in this turn of the loop. */ 
     57    invincible_found = 0; 
    5858     
    5959    /* Visit all friendly strings on the board. */ 
    6060    for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    61       if (board[pos] != color || find_origin(pos) != pos) 
     61      if (board[pos] != color || find_origin(pos) != pos 
     62          || exceptions[pos]) 
    6263        continue; 
    6364 
    64       if (exceptions && exceptions[pos]) 
    65         continue; 
    66  
    67       string_found = 1; 
    68        
    6965      /* Try to capture the string at pos. */ 
    7066      liberties = findlib(pos, MAXLIBS, libs); 
    7167      save_moves = moves_played; 
    72       for (k = 0; k < liberties; k++) { 
    73         if (trymove(libs[k], other, "unconditional_life", pos)) 
    74           moves_played++; 
    75       } 
     68      for (k = 0; k < liberties; k++) 
     69        moves_played += trymove(libs[k], other, "unconditional_life", pos); 
    7670       
    7771      /* Successful if already captured or a single liberty remains. 
    7872       * Otherwise we must rewind and take back the last batch of moves. 
     
    9690        moves_played++; 
    9791        something_captured = 1; 
    9892      } 
    99       else 
     93      else { 
     94        invincible_found = 1; 
     95 
    10096        while (moves_played > save_moves) { 
    10197          popgo(); 
    10298          moves_played--; 
    10399        } 
     100      } 
    104101    } 
    105102  } 
    106103 
    107104  if (none_invincible) 
    108     *none_invincible = !string_found; 
     105    *none_invincible = !invincible_found; 
    109106   
    110107  return moves_played; 
    111108} 
     
    148145 * 4. Play an opponent stone anywhere it can get one empty 
    149146 *    neighbor. (I.e. reduce two space eyes to one space eyes.) 
    150147 * 
    151  * Remaining opponent strings in atari and remaining liberties of the 
    152  * unconditionally alive strings constitute the unconditional 
    153  * territory. 
     148 * Remaining opponent strings in atari (and its only liberty) and 
     149 * remaining liberties of the unconditionally alive strings constitute 
     150 * the unconditional territory. 
    154151 * 
    155152 * Opponent strings from the initial position placed on 
    156153 * unconditional territory are unconditionally dead. 
    157154 * 
    158155 * - - - - - - - 
    159156 * 
     157 * Step 2 is done, because of such position (we have to extend a stone 
     158 * in atari before reducing an eyespace): 
     159 * 
     160 * OOXOO 
     161 * OX.XO 
     162 * OX.XO 
     163 * OXXXO 
     164 * OX.XO 
     165 * OXXXO 
     166 * OOOOO 
     167 * 
     168 * - - - - - - - 
     169 * 
    160170 * The deficiency with this algorithm is that a certain class of sekis 
    161171 * are considered as dead, e.g. this position: 
    162172 * 
     
    183193 * 1. Run algorithm 1. 
    184194 * 2. Return to the original position. 
    185195 * 3. Capture all capturable O strings which according to algorithm 1 
    186  *    do not belong to unconditional territory. 
     196 *    do belong to unconditional territory. 
    187197 * 4. Play opponent stones on all liberties of the unconditionally 
    188198 *    alive strings except where illegal. (That the move order may 
    189199 *    determine exactly which liberties can be played legally is not 
     
    197207 * 9. Play an opponent stone anywhere it can get one empty 
    198208 *    neighbor. (I.e. reduce two space eyes to one space eyes.) 
    199209 * 
    200  * Remaining opponent strings in atari and remaining liberties of the 
    201  * unconditionally alive strings constitute the unconditional 
    202  * territory. 
     210 * Remaining opponent strings in atari (and its only liberty) and 
     211 * remaining liberties of the unconditionally alive strings constitute 
     212 * the unconditional territory. 
    203213 * 
    204214 * Opponent strings from the initial position placed on 
    205215 * unconditional territory are unconditionally dead. 
     
    263273 * .OXXXOO 
    264274 * .OOOOO. 
    265275 * 
    266  * belong to different strings for the dead groups and to the same 
    267  * string for the seki groups. 
     276 * which belong to different strings for the dead groups and to the 
     277 * same string for the seki groups. 
    268278 * 
    269279 * The trick to avoid misclassifying areas where the opponent can form 
    270280 * a seki group but not an invincible group as unconditional territory 
     
    296306 * 10. Play an opponent stone anywhere it can get one empty 
    297307 *    neighbor. (I.e. reduce two space eyes to one space eyes.) 
    298308 * 
    299  * Remaining opponent strings in atari and remaining liberties of the 
    300  * unconditionally alive strings constitute the unconditional 
    301  * territory. 
     309 * Remaining opponent strings in atari (and its only liberty) and 
     310 * remaining liberties of the unconditionally alive strings constitute 
     311 * the unconditional territory. 
    302312 * 
    303313 * Opponent strings from the initial position placed on 
    304314 * unconditional territory are unconditionally dead. 
     
    313323void 
    314324unconditional_life(int unconditional_territory[BOARDMAX], int color) 
    315325{ 
    316   int found_one; 
    317326  int other = OTHER_COLOR(color); 
    318327  int libs[MAXLIBS]; 
    319328  int liberties; 
     
    335344    int isolated = 1; 
    336345    int stones[2]; 
    337346    int pos2; 
     347    int checked_stone; 
    338348     
    339349    if (board[pos] != color 
    340350        || find_origin(pos) != pos 
     
    343353     
    344354    findstones(pos, 2, stones); 
    345355    for (k = 0; k < 2 && isolated; k++) { 
     356      checked_stone = stones[k]; 
    346357      for (r = 0; r < 8; r++) { 
    347         pos2 = stones[k] + delta[r]; 
     358        pos2 = checked_stone + delta[r]; 
    348359        if (!ON_BOARD(pos2) 
    349360            || (board[pos2] == color 
    350361                && !same_string(pos, pos2))) 
     
    384395   *    alive strings except where illegal. 
    385396   */ 
    386397  for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    387     if (board[pos] != color || potential_sekis[pos] || find_origin(pos) != pos) 
     398    if (board[pos] != color || find_origin(pos) != pos || potential_sekis[pos]) 
    388399      continue; 
    389400       
    390401    /* Play as many liberties as we can. */ 
    391402    liberties = findlib(pos, MAXLIBS, libs); 
    392403    for (k = 0; k < liberties; k++) { 
    393       if (trymove(libs[k], other, "unconditional_life", pos)) 
    394         moves_played++; 
     404      moves_played += trymove(libs[k], other, "unconditional_life", pos); 
    395405    } 
    396406  } 
    397407 
    398408  /* 2. Recursively extend opponent strings in atari, except where this 
    399409   *    would be suicide. 
    400410   */ 
    401   found_one = 1; 
    402   while (found_one) { 
    403     /* Nothing found so far in this turn of the loop. */ 
    404     found_one = 0; 
    405  
    406     for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    407       if (board[pos] != other || countlib(pos) > 1) 
    408         continue; 
     411  for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
     412    if (board[pos] != other) 
     413      continue; 
    409414         
    410       /* Try to extend the string at (m, n). */ 
     415    /* Try to extend the string. */ 
     416    while (countlib(pos) == 1) { 
    411417      findlib(pos, 1, libs); 
    412       if (trymove(libs[0], other, "unconditional_life", pos)) { 
     418      if (trymove(libs[0], other, "unconditional_life", pos)) 
    413419        moves_played++; 
    414         found_one = 1; 
    415       } 
     420      else 
     421        break; 
    416422    } 
    417423  } 
    418424 
     
    422428        || board[pos] == EMPTY 
    423429        || find_origin(pos) != pos) 
    424430      continue; 
     431 
     432    /* Try different rotations. */ 
    425433    for (r = 0; r < 4; r++) { 
    426434      int up = delta[r]; 
    427435      int right = delta[(r + 1) % 4]; 
     
    432440        continue; 
    433441      for (k = 0; k < 2; k++) { 
    434442        if (k == 1) 
    435           right = -right; 
     443          right = -right; /* Try a mirror reflection. */ 
    436444        if (board[pos + right] != EMPTY || board[pos + up - right] != EMPTY) 
    437445          continue; 
    438         if (board[pos - right] == EMPTY 
    439             && trymove(pos - right, other, "unconditional_life", pos)) 
    440           locally_played_moves++; 
    441         if (board[pos + up + right] == EMPTY 
    442             && trymove(pos + up + right, other, "unconditional_life", pos)) 
    443           locally_played_moves++; 
     446        if (board[pos - right] == EMPTY) 
     447          locally_played_moves += trymove(pos - right, other, 
     448                                          "unconditional_life", pos); 
     449        if (board[pos + up + right] == EMPTY) 
     450          locally_played_moves += trymove(pos + up + right, other, 
     451                                          "unconditional_life", pos); 
    444452        if (board[pos - right] == other && board[pos + up + right] == other 
    445453            && same_string(pos - right, pos + up + right)) { 
    446454          /* This is a critical seki. Extend the string with one stone 
     
    450458            popgo(); 
    451459            locally_played_moves--; 
    452460          } 
    453           trymove(pos - up, color, "unconditional_life", pos); 
    454           moves_played++; 
     461          moves_played += trymove(pos - up, color, "unconditional_life", pos); 
    455462          break; 
    456463        } 
    457464        else { 
     
    472479      continue; 
    473480    /* Play as many liberties as we can. */ 
    474481    liberties = findlib(pos, MAXLIBS, libs); 
    475     for (k = 0; k < liberties; k++) { 
    476       if (trymove(libs[k], other, "unconditional_life", pos)) 
    477         moves_played++; 
    478     } 
     482    for (k = 0; k < liberties; k++) 
     483      moves_played += trymove(libs[k], other, "unconditional_life", pos); 
    479484  } 
    480485     
    481  
     486  /* All opponent strings liberties are now inside opponent territory 
     487     (due to step 4.). If any string has 3 or more liberties, it is alive 
     488     (2 eyes can be made). If a string has 1 liberty it must be in atari, so 
     489     is dead (because we tried to extend strings in atari in step 5.). We 
     490     only have to check strings, which have 2 liberties. This operations 
     491     are made instead 9. and 10. step of the algorithm. */ 
    482492  for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    483493    int apos; 
    484494    int bpos; 
     
    493503      continue; 
    494504     
    495505    /* Only two liberties and these are adjacent. Play one. We want 
    496      * to maximize the number of open liberties. In this particular 
    497      * situation we can count this with approxlib for the opposite 
    498      * color. If the number of open liberties is the same, we 
    499      * maximize the total number of obtained liberties. 
    500      * Two relevant positions: 
     506     * to maximize the number of neighboring liberties (to split an 
     507     * eyespace). In this particular situation we can count this with 
     508     * approxlib for the opposite color. If the number of neighboring 
     509     * liberties is the same, we maximize the total number of obtained 
     510     * liberties. Two relevant positions (we want to make 2 eyes for 
     511     * these O groups): 
    501512     * 
    502513     * |XXX.  
    503514     * |OOXX    |XXXXXXX 
     
    510521    alib  = approxlib(apos, other, 4, NULL); 
    511522    blib  = approxlib(bpos, other, 4, NULL); 
    512523     
    513     if (aopen > bopen || (aopen == bopen && alib >= blib)) { 
    514       trymove(apos, other, "unconditional_life", pos); 
    515       moves_played++; 
    516     } 
    517     else { 
    518       trymove(bpos, other, "unconditional_life", pos); 
    519       moves_played++; 
    520     } 
     524    if (aopen > bopen || (aopen == bopen && alib >= blib)) 
     525      moves_played += trymove(apos, other, "unconditional_life", pos); 
     526    else 
     527      moves_played += trymove(bpos, other, "unconditional_life", pos); 
    521528  } 
    522529   
    523530  /* Identify unconditionally alive stones and unconditional territory. */ 
     
    532539    } 
    533540    else if (board[pos] == other && countlib(pos) == 1) { 
    534541      unconditional_territory[pos] = 2; 
    535       findlib(pos, 1, libs); 
    536       unconditional_territory[libs[0]] = 2; 
     542      if (find_origin(pos) == pos) { 
     543        findlib(pos, 1, libs); 
     544        unconditional_territory[libs[0]] = 2; 
     545      } 
    537546    } 
    538547  } 
    539548   
  • engine/worm.c

    diff -r -u -X .ignore gnugo-copy/engine/worm.c gnugo/engine/worm.c
    old new  
    22 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see       * 
    33 * http://www.gnu.org/software/gnugo/ for more information.          * 
    44 *                                                                   * 
    5  * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006      * 
     5 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 * 
    66 * by the Free Software Foundation.                                  * 
    77 *                                                                   * 
    88 * This program is free software; you can redistribute it and/or     * 
     
    712712   
    713713  for (color = WHITE; color <= BLACK; color++) { 
    714714    unconditional_life(unconditional_territory, color); 
     715    gg_assert(stackp == 0); 
    715716 
    716717    for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    717718      if (!ON_BOARD(pos) || !unconditional_territory[pos]) 
     
    732733        worm[pos].unconditional_status = DEAD; 
    733734    } 
    734735  } 
    735   gg_assert(stackp == 0); 
    736736} 
    737737 
    738738/*