Ticket #163: draqo-semeai.diff

File draqo-semeai.diff, 9.0 kB (added by arend, 15 months ago)

This extracts the semeai parts of all-in-one.zip in #148 and probably supersedes all patches here.

  • 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     * 
     
    670670  struct eyevalue probable_eyes_a; 
    671671  struct eyevalue probable_eyes_b; 
    672672  struct eyevalue dummy_eyes; 
     673  int I_have_more_eyes; 
    673674   
    674675  SETUP_TRACE_INFO2("do_owl_analyze_semeai", apos, bpos); 
    675676 
     
    804805  if (!owl_phase) { 
    805806    set_eyevalue(&probable_eyes_a, 0, 0, 0, 0); 
    806807    set_eyevalue(&probable_eyes_b, 0, 0, 0, 0); 
     808    I_have_more_eyes = 0; 
    807809  } 
    808810  else { 
    809811    /* First the vital moves. These include moves to attack or 
     
    893895                                     shape_defensive_moves, 1, owla)) 
    894896          break; 
    895897    } 
     898    else 
     899      shape_defensive_moves[0].pos = 0; 
     900 
    896901    if (!you_look_alive) { 
    897902      owl_shapes(&shape_offensive_patterns, shape_offensive_moves, color, 
    898903                 owlb, &owl_attackpat_db); 
     
    901906                                     shape_offensive_moves, 1, owlb)) 
    902907          break; 
    903908    } 
     909    else 
     910      shape_offensive_moves[0].pos = 0; 
     911 
     912    /* Filter out moves, which fills our eye (and not split it). */ 
     913    if (eyemax_a) { 
     914      int n; 
     915      struct owl_move_data *checked_moves; 
     916 
     917      for (n = 1; n <= 5; n++) { 
     918        switch (n) { 
     919        case 1: 
     920          checked_moves = moves; 
     921          break; 
     922        case 2: 
     923          checked_moves = vital_defensive_moves; 
     924          break; 
     925        case 3: 
     926          checked_moves = vital_offensive_moves; 
     927          break; 
     928        case 4: 
     929          checked_moves = shape_defensive_moves; 
     930          break; 
     931        case 5: 
     932          checked_moves = shape_offensive_moves; 
     933          break; 
     934        default: 
     935          checked_moves = NULL; 
     936          gg_assert(0); 
     937        } 
     938 
     939        for (k = 0; k < MAX_MOVES; k++) { 
     940          if (checked_moves[k].pos <= 0) 
     941            break; 
     942          else { 
     943            struct eye_data *eye = &owla->my_eye[checked_moves[k].pos]; 
     944 
     945            /* If esize==1 this eye must not be a real eye (at least one 
     946             * worm is capturable, otherwise this move would not be 
     947             * proposed). 
     948             */ 
     949            if (eye->color == color && eye->msize == 0 && eye->neighbors <= 1 
     950                && eye->esize != 1 
     951                && owla->half_eye[checked_moves[k].pos].type != HALF_EYE 
     952                && !has_neighbor(checked_moves[k].pos, OTHER_COLOR(color))) 
     953              checked_moves[k].value = 0; 
     954          } 
     955        } 
     956      } 
     957    } 
    904958 
    905959    /* Now we review the moves already considered, while collecting 
    906960     * them into a single list.  
     
    9561010      include_semeai_worms_in_eyespace = 0; 
    9571011    } 
    9581012 
     1013    if (eyemin_a == eyemax_a) 
     1014      /* We have stable number of eyes, so we can try to reduce 
     1015       * opponent eyes. */ 
     1016      I_have_more_eyes = (eyemin_a > min_eyes(&probable_eyes_b)); 
     1017    else { 
     1018      if (min_eyes(&probable_eyes_a) == max_eyes(&probable_eyes_a)) 
     1019        /* If we can't increase our number of eyes, we try to reduce 
     1020         * opponent eyes. */ 
     1021        I_have_more_eyes = (max_eyes(&probable_eyes_a) > min_eyes(&probable_eyes_b)); 
     1022      else 
     1023        /* If we can increase our number of eyes, we do it and let 
     1024         * opponent to increase his. */ 
     1025        I_have_more_eyes = (max_eyes(&probable_eyes_a) > max_eyes(&probable_eyes_b)); 
     1026    } 
     1027 
    9591028    if (get_level() < 8) { 
    9601029      /* If no owl moves were found on two consecutive moves, 
    9611030       * turn off the owl phase. 
     
    9791048   
    9801049  /* Now we look for a move to fill a liberty. This is only 
    9811050   * interesting if the opponent doesn't already have two eyes. 
     1051   * If we have more eyes, always check for a backfilling move. 
    9821052   */ 
    9831053  if (!you_look_alive 
    984       && !safe_outside_liberty_found && moves[0].value < 110) { 
     1054      && !safe_outside_liberty_found 
     1055      && (moves[0].value < 110 || I_have_more_eyes)) { 
    9851056    int pos; 
    9861057    for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    9871058      if (!ON_BOARD(pos)) 
    988         continue; 
     1059        continue; 
    9891060       
    9901061      if (board[pos] == EMPTY && !mw[pos]) { 
    9911062        if (liberty_of_goal(pos, owlb)) { 
     
    9971068              break; 
    9981069            } 
    9991070            else if (backfill_outside_liberty.pos == NO_MOVE) 
    1000               backfill_outside_liberty.pos = find_semeai_backfilling_move(bpos, 
    1001                                                                           pos); 
     1071              backfill_outside_liberty.pos = 
     1072                find_semeai_backfilling_move(bpos, pos); 
    10021073          } 
    10031074          else { 
    10041075            /* common liberty */ 
     
    10071078              common_liberty.pos = pos; 
    10081079            } 
    10091080            else if (backfill_common_liberty.pos == NO_MOVE) 
    1010               backfill_common_liberty.pos = find_semeai_backfilling_move(bpos, 
    1011                                                                         pos); 
     1081              backfill_common_liberty.pos = 
     1082                find_semeai_backfilling_move(bpos, pos); 
    10121083          } 
    10131084        } 
    10141085      } 
     
    10951166    if (mpos == NO_MOVE) 
    10961167      break; 
    10971168 
     1169    if (moves[k].value == 0) 
     1170      continue; 
     1171 
    10981172    /* Do not try too many moves. */ 
    10991173    if (tested_moves > 2 
    11001174        || (stackp > semeai_branch_depth2 && tested_moves > 1) 
     
    12831357  gg_assert(this_resulta != NULL && this_resultb != NULL); 
    12841358  *this_resulta = 0; 
    12851359  *this_resultb = 0; 
    1286   if (!komaster_trymove(move, color, move_name, apos, &ko_move, ko_allowed)) 
     1360 
     1361  if (!komaster_trymove(move, color, move_name, apos, &ko_move, ko_allowed)) { 
     1362    int kpos; 
     1363    if (is_ko(move, color, &kpos)) { 
     1364      /* Move was not allowed because of komaster. We want to check, if this 
     1365       * situation is double ko and when it is, we won semeai. 
     1366       */ 
     1367      int libs[MAX_LIBERTIES]; 
     1368      int n; 
     1369      int nlib; 
     1370      int sworm; 
     1371      int worm_color; 
     1372      int other = OTHER_COLOR(color); 
     1373 
     1374      for (sworm = 0; sworm < s_worms; sworm++) { 
     1375        worm_color = board[semeai_worms[sworm]]; 
     1376        if (worm_color == color) { 
     1377          /* We only check up to MAX_LIBERTIES, due to performance reasons. When we 
     1378           * have more liberties we have some outside liberties to fill and these 
     1379           * moves will be tried later (and double ko situation will be found). 
     1380           */ 
     1381          nlib = findlib(semeai_worms[sworm], MAX_LIBERTIES, libs); 
     1382          if (nlib > MAX_LIBERTIES) 
     1383            return 0; 
     1384 
     1385          for (n = 0; n < nlib; n++) 
     1386            if (is_ko(libs[n], other, NULL)) { 
     1387              /* Check if situation is not a nested ko capture. */ 
     1388              if (DIAGONAL_NEIGHBORS(libs[n], kpos)) 
     1389                return 0; 
     1390 
     1391              /* Our dragon has double ko, but we have to check if opponent dragon 
     1392               * doesn't have outside liberties or double ko. 
     1393               */ 
     1394              *this_resulta = WIN; 
     1395              *this_resultb = WIN; 
     1396            } 
     1397        } 
     1398        else if (worm_color == other) { 
     1399          if (countlib(semeai_worms[sworm]) > 2) 
     1400            /* In double ko situation the opponent can have only 
     1401             * a single eye and a ko outside liberty to be sure that we 
     1402             * will always win double ko. */ 
     1403            return 0; 
     1404        } 
     1405      } 
     1406      if (*this_resulta == WIN) 
     1407        return 1; 
     1408    } 
     1409 
    12871410    return 0; 
     1411  } 
    12881412   
    12891413  semeai_add_sgf_comment(move_value, owl_phase); 
    12901414  TRACE("Trying %C %1m. Current stack: ", color, move); 
     
    14531577    if (move == NO_MOVE) 
    14541578      break; 
    14551579 
     1580    if (owl_moves[k].value == 0) 
     1581      continue; 
     1582 
    14561583    /* Does the move fill a liberty in the semeai? */ 
    14571584    if (liberty_of_goal(move, owlb) 
    14581585        && safe_move(move, color)) { 
     
    15781705    for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    15791706      if (IS_STONE(board[pos]) 
    15801707          && pos == find_origin(pos)) { 
    1581         if (owla->goal[pos]) 
    1582           net -= 75*countlib(pos); 
    1583         if (owlb->goal[pos]) 
    1584           net += 100*countlib(pos);        
     1708        int count_lib = -1; 
     1709        if (owla->goal[pos]) { 
     1710          count_lib = countlib(pos); 
     1711          net -= 75 * count_lib; 
     1712        } 
     1713        if (owlb->goal[pos]) { 
     1714          if (count_lib < 0) 
     1715            count_lib = countlib(pos); 
     1716          net += 100 * count_lib; 
     1717        } 
    15851718      } 
    15861719    } 
    15871720    if (!trymove(move, color, NULL, 0)) { 
     
    15911724    for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    15921725      if (IS_STONE(board[pos]) 
    15931726          && pos == find_origin(pos)) { 
     1727        int count_lib = -1; 
    15941728        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); 
     1729            || (pos == move && liberty_of_goal(move, owla))) { 
     1730          count_lib = countlib(pos); 
     1731          net += 75 * count_lib; 
     1732        } 
     1733        if (owlb->goal[pos]) { 
     1734          if (count_lib < 0) 
     1735            count_lib = countlib(pos); 
     1736          net -= 100 * count_lib; 
     1737        } 
    15991738      } 
    16001739    } 
    16011740