Ticket #163: draqo-semeai_b.diff

File draqo-semeai_b.diff, 8.9 kB (added by arend, 16 months ago)

This is draqo-semeai.diff, somewhat cleaned up

  • engine/owl.c

    RCS file: /home/arend/Go/gnugo-rsync/gnugo/engine/owl.c,v
    retrieving revision 1.253
    diff -u -p -r1.253 owl.c
     
    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     * 
     
    284284                             struct local_owl_data *owlb, int raw_value, 
    285285                             int *critical_semeai_worms); 
    286286static int semeai_is_riskless_move(int move, struct local_owl_data *owla); 
     287static void remove_eye_filling_moves(struct local_owl_data *our_owl, 
     288                                     struct owl_move_data *moves); 
    287289static int find_semeai_backfilling_move(int worm, int liberty); 
    288290static int liberty_of_goal(int pos, struct local_owl_data *owl); 
    289291static int second_liberty_of_goal(int pos, struct local_owl_data *owl); 
     
    670672  struct eyevalue probable_eyes_a; 
    671673  struct eyevalue probable_eyes_b; 
    672674  struct eyevalue dummy_eyes; 
     675  int I_have_more_eyes; 
    673676   
    674677  SETUP_TRACE_INFO2("do_owl_analyze_semeai", apos, bpos); 
    675678 
     
    804807  if (!owl_phase) { 
    805808    set_eyevalue(&probable_eyes_a, 0, 0, 0, 0); 
    806809    set_eyevalue(&probable_eyes_b, 0, 0, 0, 0); 
     810    I_have_more_eyes = 0; 
    807811  } 
    808812  else { 
    809813    /* First the vital moves. These include moves to attack or 
     
    893897                                     shape_defensive_moves, 1, owla)) 
    894898          break; 
    895899    } 
     900    else 
     901      shape_defensive_moves[0].pos = 0; 
     902 
    896903    if (!you_look_alive) { 
    897904      owl_shapes(&shape_offensive_patterns, shape_offensive_moves, color, 
    898905                 owlb, &owl_attackpat_db); 
     
    901908                                     shape_offensive_moves, 1, owlb)) 
    902909          break; 
    903910    } 
     911    else 
     912      shape_offensive_moves[0].pos = 0; 
     913 
     914    /* Filter out moves, which fills our eye (and not split it). */ 
     915    if (eyemax_a) { 
     916      remove_eye_filling_moves(owla, vital_defensive_moves); 
     917      remove_eye_filling_moves(owla, vital_offensive_moves); 
     918      remove_eye_filling_moves(owla, shape_defensive_moves); 
     919      remove_eye_filling_moves(owla, shape_offensive_moves); 
     920    } 
    904921 
    905922    /* Now we review the moves already considered, while collecting 
    906923     * them into a single list.  
     
    956973      include_semeai_worms_in_eyespace = 0; 
    957974    } 
    958975 
     976    if (eyemin_a == eyemax_a) 
     977      /* We have stable number of eyes, so we can try to reduce 
     978       * opponent eyes. */ 
     979      I_have_more_eyes = (eyemin_a > min_eyes(&probable_eyes_b)); 
     980    else { 
     981      if (min_eyes(&probable_eyes_a) == max_eyes(&probable_eyes_a)) 
     982        /* If we can't increase our number of eyes, we try to reduce 
     983         * opponent eyes. */ 
     984        I_have_more_eyes = (max_eyes(&probable_eyes_a) > min_eyes(&probable_eyes_b)); 
     985      else 
     986        /* If we can increase our number of eyes, we do it and let 
     987         * opponent to increase his. */ 
     988        I_have_more_eyes = (max_eyes(&probable_eyes_a) > max_eyes(&probable_eyes_b)); 
     989    } 
     990 
    959991    if (get_level() < 8) { 
    960992      /* If no owl moves were found on two consecutive moves, 
    961993       * turn off the owl phase. 
     
    9791011   
    9801012  /* Now we look for a move to fill a liberty. This is only 
    9811013   * interesting if the opponent doesn't already have two eyes. 
     1014   * If we have more eyes, always check for a backfilling move. 
    9821015   */ 
    9831016  if (!you_look_alive 
    984       && !safe_outside_liberty_found && moves[0].value < 110) { 
     1017      && !safe_outside_liberty_found 
     1018      && (moves[0].value < 110 || I_have_more_eyes)) { 
    9851019    int pos; 
    9861020    for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    9871021      if (!ON_BOARD(pos)) 
    988         continue; 
     1022        continue; 
    9891023       
    9901024      if (board[pos] == EMPTY && !mw[pos]) { 
    9911025        if (liberty_of_goal(pos, owlb)) { 
     
    10951129    if (mpos == NO_MOVE) 
    10961130      break; 
    10971131 
     1132    if (moves[k].value == 0) 
     1133      continue; 
     1134 
    10981135    /* Do not try too many moves. */ 
    10991136    if (tested_moves > 2 
    11001137        || (stackp > semeai_branch_depth2 && tested_moves > 1) 
     
    12831320  gg_assert(this_resulta != NULL && this_resultb != NULL); 
    12841321  *this_resulta = 0; 
    12851322  *this_resultb = 0; 
    1286   if (!komaster_trymove(move, color, move_name, apos, &ko_move, ko_allowed)) 
     1323 
     1324  if (!komaster_trymove(move, color, move_name, apos, &ko_move, ko_allowed)) { 
     1325    int kpos; 
     1326    if (is_ko(move, color, &kpos)) { 
     1327      /* Move was not allowed because of komaster. We want to check, if this 
     1328       * situation is double ko and when it is, we won semeai. 
     1329       */ 
     1330      int libs[MAX_LIBERTIES]; 
     1331      int n; 
     1332      int nlib; 
     1333      int sworm; 
     1334      int worm_color; 
     1335      int other = OTHER_COLOR(color); 
     1336 
     1337      for (sworm = 0; sworm < s_worms; sworm++) { 
     1338        worm_color = board[semeai_worms[sworm]]; 
     1339        if (worm_color == color) { 
     1340          /* We only check up to MAX_LIBERTIES, due to performance reasons. When we 
     1341           * have more liberties we have some outside liberties to fill and these 
     1342           * moves will be tried later (and double ko situation will be found). 
     1343           */ 
     1344          nlib = findlib(semeai_worms[sworm], MAX_LIBERTIES, libs); 
     1345          if (nlib > MAX_LIBERTIES) 
     1346            return 0; 
     1347 
     1348          for (n = 0; n < nlib; n++) 
     1349            if (is_ko(libs[n], other, NULL)) { 
     1350              /* Check if situation is not a nested ko capture. */ 
     1351              if (DIAGONAL_NEIGHBORS(libs[n], kpos)) 
     1352                return 0; 
     1353 
     1354              /* Our dragon has double ko, but we have to check if opponent dragon 
     1355               * doesn't have outside liberties or double ko. 
     1356               */ 
     1357              *this_resulta = WIN; 
     1358              *this_resultb = WIN; 
     1359            } 
     1360        } 
     1361        else if (worm_color == other) { 
     1362          if (countlib(semeai_worms[sworm]) > 2) 
     1363            /* In double ko situation the opponent can have only 
     1364             * a single eye and a ko outside liberty to be sure that we 
     1365             * will always win double ko. */ 
     1366            return 0; 
     1367        } 
     1368      } 
     1369      if (*this_resulta == WIN) 
     1370        return 1; 
     1371    } 
     1372 
    12871373    return 0; 
     1374  } 
    12881375   
    12891376  semeai_add_sgf_comment(move_value, owl_phase); 
    12901377  TRACE("Trying %C %1m. Current stack: ", color, move); 
     
    14531540    if (move == NO_MOVE) 
    14541541      break; 
    14551542 
     1543    if (owl_moves[k].value == 0) 
     1544      continue; 
     1545 
    14561546    /* Does the move fill a liberty in the semeai? */ 
    14571547    if (liberty_of_goal(move, owlb) 
    14581548        && safe_move(move, color)) { 
     
    15781668    for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    15791669      if (IS_STONE(board[pos]) 
    15801670          && pos == find_origin(pos)) { 
    1581         if (owla->goal[pos]) 
    1582           net -= 75*countlib(pos); 
    1583         if (owlb->goal[pos]) 
    1584           net += 100*countlib(pos);        
     1671        int count_lib = -1; 
     1672        if (owla->goal[pos]) { 
     1673          count_lib = countlib(pos); 
     1674          net -= 75 * count_lib; 
     1675        } 
     1676        if (owlb->goal[pos]) { 
     1677          if (count_lib < 0) 
     1678            count_lib = countlib(pos); 
     1679          net += 100 * count_lib; 
     1680        } 
    15851681      } 
    15861682    } 
    15871683    if (!trymove(move, color, NULL, 0)) { 
     
    15911687    for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    15921688      if (IS_STONE(board[pos]) 
    15931689          && pos == find_origin(pos)) { 
     1690        int count_lib = -1; 
    15941691        if (owla->goal[pos] 
    1595             || (pos == move && liberty_of_goal(move, owla))) 
    1596           net += 75*countlib(pos); 
    1597         if (owlb->goal[pos]) 
    1598           net -= 100*countlib(pos); 
     1692            || (pos == move && liberty_of_goal(move, owla))) { 
     1693          count_lib = countlib(pos); 
     1694          net += 75 * count_lib; 
     1695        } 
     1696        if (owlb->goal[pos]) { 
     1697          if (count_lib < 0) 
     1698            count_lib = countlib(pos); 
     1699          net -= 100 * count_lib; 
     1700        } 
    15991701      } 
    16001702    } 
    16011703 
     
    16271729} 
    16281730 
    16291731 
     1732/* Remove all moves from the list that would fill our own eye. */ 
     1733static void 
     1734remove_eye_filling_moves(struct local_owl_data *our_owl, 
     1735                         struct owl_move_data *moves) 
     1736{ 
     1737  int k; 
     1738  int color = our_owl->color; 
     1739 
     1740  for (k = 0; k < MAX_MOVES; k++) { 
     1741    if (moves[k].pos <= 0) 
     1742      break; 
     1743    else { 
     1744      struct eye_data *eye = &our_owl->my_eye[moves[k].pos]; 
     1745 
     1746      /* If esize==1 this eye must not be a real eye (at least one 
     1747       * worm is capturable, otherwise this move would not be 
     1748       * proposed). 
     1749       */ 
     1750      if (eye->color == color && eye->msize == 0 && eye->neighbors <= 1 
     1751          && eye->esize != 1 
     1752          && our_owl->half_eye[moves[k].pos].type != HALF_EYE 
     1753          && !has_neighbor(moves[k].pos, OTHER_COLOR(color))) 
     1754        moves[k].value = 0; 
     1755    } 
     1756  } 
     1757} 
    16301758 
    16311759/* Is the vertex at pos adjacent to an element of the owl goal? */ 
    16321760static int