Ticket #116: gunnar_7_10.1.diff

File gunnar_7_10.1.diff, 21.4 kB (added by gunnar, 3 years ago)

Implementation of a classification.

  • engine/owl.c

    RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v
    retrieving revision 1.247
    diff -u -r1.247 owl.c
     
    118118 
    119119#define MAX_CUTS 5 
    120120 
     121enum same_dragon_value { 
     122  SAME_DRAGON_NOT_CONNECTED, 
     123  SAME_DRAGON_MAYBE_CONNECTED, 
     124  SAME_DRAGON_CONNECTED, 
     125  SAME_DRAGON_ALL_CONNECTED 
     126}; 
     127 
     128struct matched_pattern_data; 
     129 
    121130struct owl_move_data { 
    122131  int pos;          /* move coordinate */ 
    123132  int value;        /* value */ 
    124133  const char *name; /* name of the pattern suggesting the move */ 
    125   int same_dragon;  /* whether the move extends the dragon or not */ 
     134  /* whether the move extends the dragon or not */ 
     135  enum same_dragon_value same_dragon; 
    126136  int lunch;        /* Position of a lunch, if applicable.*/ 
    127137  int escape;       /* true if an escape pattern is matched */ 
    128138  int defense_pos;  /* defense coordinate for vital owl attack patterns. */ 
    129139  int cuts[MAX_CUTS]; /* strings of the goal that might get cut off */ 
     140  /* pointer to pattern data, used for SAME_DRAGON_ALL_CONNECTED */ 
     141  struct matched_pattern_data *pattern_data; 
    130142}; 
    131143 
    132144#define USE_BDIST 1 
     
    187199                                struct pattern *pattern_db, 
    188200                                int ll, void *data); 
    189201static void owl_add_move(struct owl_move_data *moves, int move, int value, 
    190                          const char *reason, int same_dragon, int lunch, 
    191                          int escape, int defense_pos, int max_moves); 
     202                         const char *reason, 
     203                         enum same_dragon_value same_dragon, int lunch, 
     204                         int escape, int defense_pos, int max_moves, 
     205                         struct matched_pattern_data *pattern_data); 
    192206static void owl_determine_life(struct local_owl_data *owl, 
    193207                               struct local_owl_data *second_owl, 
    194208                               int does_attack, 
     
    216230static void owl_mark_worm(int apos, int bpos, 
    217231                          struct local_owl_data *owl); 
    218232static void owl_mark_boundary(struct local_owl_data *owl); 
    219 static void owl_update_goal(int pos, int same_dragon, int lunch, 
    220                             struct local_owl_data *owl, int semeai_call); 
     233static void owl_update_goal(int pos, enum same_dragon_value same_dragon, 
     234                            int lunch, struct local_owl_data *owl, 
     235                            int semeai_call, 
     236                            struct matched_pattern_data *pattern_data); 
    221237static void owl_test_cuts(signed char goal[BOARDMAX], int color, 
    222238                          int cuts[MAX_CUTS]); 
    223239static void componentdump(const signed char component[BOARDMAX]); 
     
    246262                                      int owl_phase, 
    247263                                      int move, int color, int ko_allowed, 
    248264                                      int move_value, const char *move_name, 
    249                                       int same_dragon, int lunch, 
    250                                       int *semeai_move, 
     265                                      enum same_dragon_value same_dragon, 
     266                                      struct matched_pattern_data *pattern_data, 
     267                                      int lunch, int *semeai_move, 
    251268                                      int *this_resulta, int *this_resultb); 
    252269static void semeai_add_sgf_comment(int value, int owl_phase); 
    253270static int semeai_trust_tactical_attack(int str); 
     
    556573                          resulta, resultb, semeai_move, 0, owl); 
    557574  else { 
    558575    semeai_trymove_and_recurse(bpos, apos, owlb, owla, owl, 
    559                                move, color, 1, 0, "mandatory move", 1, NO_MOVE, 
     576                               move, color, 1, 0, "mandatory move", 
     577                               SAME_DRAGON_MAYBE_CONNECTED, NULL, NO_MOVE, 
    560578                               semeai_move, resultb, resulta); 
    561579    *resulta = REVERSE_RESULT(*resulta); 
    562580    *resultb = REVERSE_RESULT(*resultb); 
     
    703721    moves[k].pos = 0; 
    704722    moves[k].value = -1; 
    705723    moves[k].name = NULL; 
    706     moves[k].same_dragon = 2; 
     724    moves[k].same_dragon = SAME_DRAGON_CONNECTED; 
    707725    moves[k].lunch = NO_MOVE; 
    708726    clear_cut_list(moves[k].cuts); 
    709727  } 
     
    742760        else if (acode != 0 
    743761                 && find_defense(semeai_worms[sworm], NULL)) { 
    744762          critical_semeai_worms[sworm] = 1; 
    745           owl_add_move(moves, upos, 105, "attack semeai worm", 1, 
    746                        NO_MOVE, 0, NO_MOVE, MAX_SEMEAI_MOVES); 
     763          owl_add_move(moves, upos, 105, "attack semeai worm", 
     764                       SAME_DRAGON_MAYBE_CONNECTED, 
     765                       NO_MOVE, 0, NO_MOVE, MAX_SEMEAI_MOVES, NULL); 
    747766          TRACE("Added %1m %d (-1)\n", upos, 105); 
    748767        } 
    749768        else if (acode == WIN 
    750769                 && important_semeai_worms[sworm]) { 
    751           owl_add_move(moves, upos, 100, "attack semeai worm", 1, 
    752                        NO_MOVE, 0, NO_MOVE, MAX_SEMEAI_MOVES); 
     770          owl_add_move(moves, upos, 100, "attack semeai worm", 
     771                       SAME_DRAGON_MAYBE_CONNECTED, 
     772                       NO_MOVE, 0, NO_MOVE, MAX_SEMEAI_MOVES, NULL); 
    753773          TRACE("Added %1m %d (-1)\n", upos, 100); 
    754774        } 
    755775      } 
     
    767787        if (attack(semeai_worms[sworm], NULL) 
    768788            && find_defense(semeai_worms[sworm], &upos)) { 
    769789          critical_semeai_worms[sworm] = 1; 
    770           owl_add_move(moves, upos, 85, "defend semeai worm", 1, NO_MOVE, 
    771                        0, NO_MOVE, MAX_SEMEAI_MOVES); 
     790          owl_add_move(moves, upos, 85, "defend semeai worm", 
     791                       SAME_DRAGON_MAYBE_CONNECTED, NO_MOVE, 
     792                       0, NO_MOVE, MAX_SEMEAI_MOVES, NULL); 
    772793          TRACE("Added %1m %d (0)\n", upos, 85); 
    773794        } 
    774795      } 
     
    10061027                                     owla, owlb, 50, 
    10071028                                     critical_semeai_worms); 
    10081029      owl_add_move(moves, outside_liberty.pos, move_value, 
    1009                    "safe outside liberty", 0, NO_MOVE, 0, NO_MOVE, 
    1010                    MAX_SEMEAI_MOVES); 
     1030                   "safe outside liberty", SAME_DRAGON_NOT_CONNECTED, 
     1031                   NO_MOVE, 0, NO_MOVE, MAX_SEMEAI_MOVES, NULL); 
    10111032      riskless_move_found = 1; 
    10121033      TRACE("Added %1m %d (5)\n", outside_liberty.pos, move_value); 
    10131034    } 
     
    10161037                                     owla, owlb, 50, 
    10171038                                     critical_semeai_worms); 
    10181039      owl_add_move(moves, backfill_outside_liberty.pos, move_value, 
    1019                    "backfilling move", 0, NO_MOVE, 0, 
    1020                    NO_MOVE, MAX_SEMEAI_MOVES); 
     1040                   "backfilling move", SAME_DRAGON_NOT_CONNECTED, NO_MOVE, 0, 
     1041                   NO_MOVE, MAX_SEMEAI_MOVES, NULL); 
    10211042      riskless_move_found = 1; 
    10221043      TRACE("Added %1m %d (6)\n", backfill_outside_liberty.pos, move_value); 
    10231044    } 
     
    10271048                                     owla, owlb, 10, 
    10281049                                     critical_semeai_worms); 
    10291050      owl_add_move(moves, common_liberty.pos, move_value, 
    1030                    "safe common liberty", 1, NO_MOVE, 0, 
    1031                    NO_MOVE, MAX_SEMEAI_MOVES); 
     1051                   "safe common liberty", SAME_DRAGON_MAYBE_CONNECTED, 
     1052                   NO_MOVE, 0, NO_MOVE, MAX_SEMEAI_MOVES, NULL); 
    10321053      if (semeai_is_riskless_move(common_liberty.pos, owla)) 
    10331054        riskless_move_found = 1; 
    10341055      TRACE("Added %1m %d (7)\n", common_liberty.pos, move_value); 
     
    10381059                                     owla, owlb, 10, 
    10391060                                     critical_semeai_worms); 
    10401061      owl_add_move(moves, backfill_common_liberty.pos, move_value, 
    1041                    "backfilling move", 0, NO_MOVE, 0, 
    1042                    NO_MOVE, MAX_SEMEAI_MOVES); 
     1062                   "backfilling move", SAME_DRAGON_NOT_CONNECTED, NO_MOVE, 0, 
     1063                   NO_MOVE, MAX_SEMEAI_MOVES, NULL); 
    10431064      if (semeai_is_riskless_move(backfill_common_liberty.pos, owla)) 
    10441065        riskless_move_found = 1; 
    10451066      TRACE("Added %1m %d (6)\n", backfill_common_liberty.pos, move_value); 
     
    10541075      int move = semeai_propose_eyespace_filling_move(owla, owlb); 
    10551076 
    10561077      if (move) { 
    1057         owl_add_move(moves, move, 70, "eyespace filling", 0, NO_MOVE, 
    1058                      0, NO_MOVE, MAX_SEMEAI_MOVES); 
     1078        owl_add_move(moves, move, 70, "eyespace filling", 
     1079                     SAME_DRAGON_NOT_CONNECTED, NO_MOVE, 
     1080                     0, NO_MOVE, MAX_SEMEAI_MOVES, NULL); 
    10591081      } 
    10601082    } 
    10611083 
     
    10971119                                   owl_phase, mpos, color, 
    10981120                                   best_resulta == 0 || best_resultb == 0, 
    10991121                                   moves[k].value, moves[k].name, 
    1100                                    moves[k].same_dragon, moves[k].lunch, 
    1101                                    NULL, &this_resulta, &this_resultb)) { 
     1122                                   moves[k].same_dragon, moves[k].pattern_data, 
     1123                                   moves[k].lunch, NULL, 
     1124                                   &this_resulta, &this_resultb)) { 
    11021125      tested_moves++; 
    11031126      if (this_resultb == WIN && this_resulta == WIN) { 
    11041127        /* Ideal result, no need to try any more moves. */ 
     
    12491272                           int owl_phase, 
    12501273                           int move, int color, int ko_allowed, 
    12511274                           int move_value, const char *move_name, 
    1252                            int same_dragon, int lunch, int *semeai_move, 
     1275                           enum same_dragon_value same_dragon, 
     1276                           struct matched_pattern_data *pattern_data, 
     1277                           int lunch, int *semeai_move, 
    12531278                           int *this_resulta, int *this_resultb) 
    12541279{ 
    12551280  int ko_move = 0; 
     
    12751300  push_owl(&owlb); 
    12761301 
    12771302  if (owla->color == color) { 
    1278     owl_update_goal(move, same_dragon, lunch, owla, 1); 
     1303    owl_update_goal(move, same_dragon, lunch, owla, 1, pattern_data); 
    12791304    owl_update_boundary_marks(move, owlb); 
    12801305  } 
    12811306  else { 
    1282     owl_update_goal(move, same_dragon, lunch, owlb, 1); 
     1307    owl_update_goal(move, same_dragon, lunch, owlb, 1, pattern_data); 
    12831308    owl_update_boundary_marks(move, owla); 
    12841309  } 
    12851310  mark_goal_in_sgf(owla->goal); 
     
    14181443{ 
    14191444  int move; 
    14201445  int move_value; 
    1421   int same_dragon; 
     1446  enum same_dragon_value same_dragon; 
     1447  struct matched_pattern_data *pattern_data = NULL; 
    14221448  int k; 
    14231449   
    14241450  for (k = 0; k < MAX_MOVES-1; k++) { 
     
    14441470    if (guess_same_dragon) { 
    14451471      if (liberty_of_goal(move, owla) 
    14461472          || second_liberty_of_goal(move, owla)) 
    1447         same_dragon = 1; 
     1473        same_dragon = SAME_DRAGON_MAYBE_CONNECTED; 
    14481474      else 
    1449         same_dragon = 0; 
     1475        same_dragon = SAME_DRAGON_NOT_CONNECTED; 
    14501476    } 
    1451     else 
     1477    else { 
    14521478      same_dragon = owl_moves[k].same_dragon; 
     1479      pattern_data = owl_moves[k].pattern_data; 
     1480    } 
    14531481 
    14541482    mw[move] = 1; 
    14551483    move_value = (semeai_move_value(move, owla, owlb, owl_moves[k].value, 
     
    14571485                  + value_bonus); 
    14581486    owl_add_move(semeai_moves, move, move_value, owl_moves[k].name,  
    14591487                 same_dragon, NO_MOVE, owl_moves[k].escape, 
    1460                  NO_MOVE, MAX_SEMEAI_MOVES); 
     1488                 NO_MOVE, MAX_SEMEAI_MOVES, pattern_data); 
    14611489    TRACE("Added %1m %d\n", move, move_value); 
    14621490  } 
    14631491} 
     
    17031731    moves[k].pos = NO_MOVE; 
    17041732    moves[k].value = -1; 
    17051733    moves[k].name = NULL; 
    1706     moves[k].same_dragon = 2; 
     1734    moves[k].same_dragon = SAME_DRAGON_CONNECTED; 
    17071735    moves[k].escape = 0; 
    17081736    moves[k].lunch = NO_MOVE; 
     1737    moves[k].pattern_data = NULL; 
    17091738    clear_cut_list(moves[k].cuts); 
    17101739  } 
    17111740} 
     
    17141743set_single_owl_move(struct owl_move_data moves[MAX_MOVES], 
    17151744                    int pos, const char *name) 
    17161745{ 
    1717   moves[0].pos         = pos; 
    1718   moves[0].value       = 25; 
    1719   moves[0].name        = name; 
    1720   moves[0].same_dragon = 1; 
    1721   moves[0].escape      = 0; 
    1722   moves[0].lunch       = NO_MOVE; 
     1746  moves[0].pos          = pos; 
     1747  moves[0].value        = 25; 
     1748  moves[0].name         = name; 
     1749  moves[0].same_dragon  = SAME_DRAGON_MAYBE_CONNECTED; 
     1750  moves[0].escape       = 0; 
     1751  moves[0].lunch        = NO_MOVE; 
     1752  moves[0].pattern_data = NULL; 
    17231753  clear_cut_list(moves[0].cuts); 
    1724   moves[1].value       = 0; 
     1754  moves[1].value        = 0; 
    17251755} 
    17261756 
    17271757 
     
    27162746      /* Add the stone just played to the goal dragon, unless the 
    27172747       * pattern explicitly asked for not doing this. 
    27182748       */ 
    2719       owl_update_goal(mpos, moves[k].same_dragon, moves[k].lunch, owl, 0); 
     2749      owl_update_goal(mpos, moves[k].same_dragon, moves[k].lunch, owl, 0, 
     2750                      moves[k].pattern_data); 
    27202751      mark_goal_in_sgf(owl->goal); 
    27212752 
    27222753      if (!ko_move) { 
     
    28322863        if (trymove(moves[k].pos, color, moves[k].name, target)) { 
    28332864          owl->lunches_are_current = 0; 
    28342865          owl_update_goal(moves[k].pos, moves[k].same_dragon, 
    2835                           moves[k].lunch, owl, 0); 
     2866                          moves[k].lunch, owl, 0, moves[k].pattern_data); 
    28362867          if (do_owl_defend(target, &move2, NULL, owl, 0) == WIN) { 
    28372868            move = moves[k].pos; 
    28382869            popgo(); 
     
    29472978     * Let's try to defend against it. 
    29482979     */ 
    29492980    owl_add_move(vital_moves, dummy_moves[0].defense_pos, 
    2950                  dummy_moves[0].value, dummy_moves[0].name, 2, NO_MOVE, 
    2951                  0, NO_MOVE, MAX_MOVES); 
     2981                 dummy_moves[0].value, dummy_moves[0].name, 
     2982                 SAME_DRAGON_CONNECTED, NO_MOVE, 0, NO_MOVE, MAX_MOVES, NULL); 
    29522983  } 
    29532984 
    29542985  return 0; 
     
    31613192                  attack_point); 
    31623193 
    31633194          if (attack_point != NO_MOVE) { 
    3164             owl_add_move(moves, attack_point, value, reason, 1, NO_MOVE, 
    3165                          0, NO_MOVE, MAX_MOVES); 
     3195            owl_add_move(moves, attack_point, value, reason, 
     3196                         SAME_DRAGON_MAYBE_CONNECTED, NO_MOVE, 
     3197                         0, NO_MOVE, MAX_MOVES, NULL); 
    31663198            vital_values[attack_point] = value; 
    31673199            eyes_attack_points[num_eyes] = attack_point; 
    31683200          } 
     
    32163248                  defense_point); 
    32173249 
    32183250          if (defense_point != NO_MOVE) { 
    3219             owl_add_move(moves, defense_point, value, reason, 1, NO_MOVE, 
    3220                          0, NO_MOVE, MAX_MOVES); 
     3251            owl_add_move(moves, defense_point, value, reason, 
     3252                         SAME_DRAGON_MAYBE_CONNECTED, NO_MOVE, 
     3253                         0, NO_MOVE, MAX_MOVES, NULL); 
    32213254            vital_values[defense_point] = value; 
    32223255          } 
    32233256        } 
     
    32913324                owl->lunch[lunch], defense_point, value, 
    32923325                lunch_probable, lunch_max); 
    32933326          owl_add_move(moves, defense_point, value, 
    3294                        "save lunch", 1, NO_MOVE, 0, NO_MOVE, MAX_MOVES); 
     3327                       "save lunch", SAME_DRAGON_MAYBE_CONNECTED, 
     3328                       NO_MOVE, 0, NO_MOVE, MAX_MOVES, NULL); 
    32953329        } 
    32963330        else { 
    32973331          attack_point = improve_lunch_attack(owl->lunch[lunch], 
     
    33073341          if (owl->lunch_attack_code[lunch] ==  WIN 
    33083342              || is_illegal_ko_capture(attack_point, owl->color)) 
    33093343            owl_add_move(moves, attack_point, value, "eat lunch", 
    3310                          1, owl->lunch[lunch], 0, NO_MOVE, MAX_MOVES); 
     3344                         SAME_DRAGON_MAYBE_CONNECTED, owl->lunch[lunch], 
     3345                         0, NO_MOVE, MAX_MOVES, NULL); 
    33113346          else 
    33123347            owl_add_move(moves, attack_point, value, "eat lunch", 
    3313                          1, NO_MOVE, 0, NO_MOVE, MAX_MOVES); 
     3348                         SAME_DRAGON_MAYBE_CONNECTED, NO_MOVE, 0, NO_MOVE, 
     3349                         MAX_MOVES, NULL); 
    33143350          num_lunches++; 
    33153351          eyevalue_list[num_eyes++] = e; 
    33163352        } 
     
    42404276        } 
    42414277 
    42424278        if (pattern->class & CLASS_B) 
    4243           moves[k].same_dragon = 0; 
    4244         else if (pattern->class & CLASS_b) { 
     4279          moves[k].same_dragon = SAME_DRAGON_NOT_CONNECTED; 
     4280        else if (pattern->class & CLASS_a) { 
     4281          moves[k].same_dragon = SAME_DRAGON_ALL_CONNECTED; 
     4282          moves[k].pattern_data = list->pattern_heap[0]; 
     4283        } 
     4284        else if (!(pattern->class & CLASS_b)) 
     4285          moves[k].same_dragon = SAME_DRAGON_CONNECTED; 
     4286        else { 
    42454287          int i; 
    4246           int same_dragon = 1; 
     4288          enum same_dragon_value same_dragon = SAME_DRAGON_MAYBE_CONNECTED; 
    42474289 
    42484290          /* If we do not yet know whether the move belongs to the 
    42494291           * same dragon, we see whether another pattern can clarify. 
     
    42604302                TRACE("Additionally pattern %s found at %1m\n", 
    42614303                      pattern_data->pattern->name, move); 
    42624304                if (pattern_data->pattern->class & CLASS_B) 
    4263                   same_dragon = 0; 
     4305                  same_dragon = SAME_DRAGON_NOT_CONNECTED; 
     4306                else if (pattern_data->pattern->class & CLASS_a) { 
     4307                  same_dragon = SAME_DRAGON_ALL_CONNECTED; 
     4308                  moves[k].pattern_data = pattern_data; 
     4309                } 
    42644310                else 
    4265                   same_dragon = 2; 
     4311                  same_dragon = SAME_DRAGON_CONNECTED; 
    42664312 
    42674313                break; 
    42684314              } 
     
    42714317 
    42724318          moves[k].same_dragon = same_dragon; 
    42734319        } 
    4274         else 
    4275           moves[k].same_dragon = 2; 
    42764320      } 
    42774321      else { 
    42784322        moves[k].name = "Pattern combination"; 
     
    42874331         *        chain didn't match, this will not work at all. 
    42884332         */ 
    42894333        if (pattern && pattern->class & CLASS_B) 
    4290           moves[k].same_dragon = 0; 
     4334          moves[k].same_dragon = SAME_DRAGON_NOT_CONNECTED; 
     4335        else if (pattern && pattern->class & CLASS_a) { 
     4336          moves[k].same_dragon = SAME_DRAGON_ALL_CONNECTED; 
     4337          moves[k].pattern_data = list->pattern_heap[0]; 
     4338        } 
    42914339        else 
    4292           moves[k].same_dragon = 2; 
     4340          moves[k].same_dragon = SAME_DRAGON_CONNECTED; 
    42934341      } 
    42944342 
    42954343      if (pattern && pattern->class & CLASS_E) 
     
    43384386  int tval;  /* trial move and its value */ 
    43394387  int move; 
    43404388  struct owl_move_data *moves = data; /* considered moves passed as data */ 
    4341   int same_dragon = 1; 
     4389  enum same_dragon_value same_dragon = SAME_DRAGON_MAYBE_CONNECTED; 
    43424390  int escape = 0; 
    43434391  int defense_pos; 
    43444392 
     
    43954443  TRACE("Pattern %s found at %1m with value %d\n", pattern->name, move, tval); 
    43964444 
    43974445  if (pattern->class & CLASS_B) 
    4398     same_dragon = 0; 
     4446    same_dragon = SAME_DRAGON_NOT_CONNECTED; 
    43994447  else if (pattern->class & CLASS_b) 
    4400     same_dragon = 1; 
     4448    same_dragon = SAME_DRAGON_MAYBE_CONNECTED; 
     4449  else if (pattern->class & CLASS_a) { 
     4450    same_dragon = SAME_DRAGON_ALL_CONNECTED; 
     4451    /* FIXME: Currently this code is only used with vital attack 
     4452     * moves, so there is no use for the "a" classification. If it 
     4453     * would be needed in the future it's necessary to set up a struct 
     4454     * matched_pattern_data here to be passed to owl_add_move(). This 
     4455     * is not all that simple with respect to memory management 
     4456     * however. Notice that a local variable in this function would go 
     4457     * out of scope too early. 
     4458     */ 
     4459    gg_assert(0); 
     4460  } 
    44014461  else 
    4402     same_dragon = 2; 
     4462    same_dragon = SAME_DRAGON_CONNECTED; 
    44034463 
    44044464  if (pattern->class & CLASS_E) 
    44054465    escape = 1; 
     
    44164476  } 
    44174477   
    44184478  owl_add_move(moves, move, tval, pattern->name, same_dragon, NO_MOVE, 
    4419                escape, defense_pos, MAX_MOVES); 
     4479               escape, defense_pos, MAX_MOVES, NULL); 
    44204480} 
    44214481 
    44224482 
     
    44244484 
    44254485static void 
    44264486owl_add_move(struct owl_move_data *moves, int move, int value, 
    4427              const char *reason, int same_dragon, int lunch, 
    4428              int escape, int defense_pos, int max_moves) 
     4487             const char *reason, enum same_dragon_value same_dragon, int lunch, 
     4488             int escape, int defense_pos, int max_moves, 
     4489             struct matched_pattern_data *pattern_data) 
    44294490{ 
    44304491  int k; 
    44314492 
     
    44434504    if (moves[k].value == -1) 
    44444505      break; 
    44454506    if (moves[k].pos == move) { 
    4446       if (same_dragon > moves[k].same_dragon) 
     4507      if (same_dragon > moves[k].same_dragon) { 
    44474508        moves[k].same_dragon = same_dragon; 
     4509        moves[k].pattern_data = pattern_data; 
     4510      } 
    44484511      if (!moves[k].escape) 
    44494512        escape = 0; 
    44504513      break; 
     
    44714534         * dragon under consideration. 
    44724535         */ 
    44734536        moves[k].same_dragon = same_dragon; 
     4537        moves[k].pattern_data = pattern_data; 
    44744538        moves[k].lunch = lunch; 
    44754539        moves[k].escape = escape; 
    44764540        moves[k].defense_pos = defense_pos; 
     
    46614725} 
    46624726 
    46634727/* Add the stone just played to the goal dragon if same_dragon is 
    4664  * 2. We also add all stones belonging to the same generalized string 
    4665  * to the goal. If same_dragon is 1, we only add the stones if at 
    4666  * least one stone of the generalized string already was part of the 
    4667  * goal. If same_dragon is 0, we don't add any stones at all. 
     4728 * SAME_DRAGON_CONNECTED. We also add all stones belonging to the same 
     4729 * generalized string to the goal. If same_dragon is 
     4730 * SAME_DRAGON_MAYBE_CONNECTED, we only add the stones if at least one 
     4731 * stone of the generalized string already was part of the goal. If 
     4732 * same_dragon is SAME_DRAGON_NOT_CONNECTED, we don't add any stones 
     4733 * at all. 
     4734 * 
     4735 * The SAME_DRAGON_ALL_CONNECTED case is like SAME_DRAGON_CONNECTED 
     4736 * but additionally all other own stones in the pattern suggesting the 
     4737 * move are also added to the goal. 
    46684738 */ 
    46694739static void 
    4670 owl_update_goal(int pos, int same_dragon, int lunch, 
    4671                 struct local_owl_data *owl, int semeai_call) 
     4740owl_update_goal(int pos, enum same_dragon_value same_dragon, int lunch, 
     4741                struct local_owl_data *owl, int semeai_call, 
     4742                struct matched_pattern_data *pattern_data) 
    46724743{ 
    46734744  int stones[MAX_BOARD * MAX_BOARD]; 
    46744745  int num_stones; 
     
    46824753  sgf_dumptree = NULL; 
    46834754  count_variations = 0; 
    46844755   
    4685   if (same_dragon == 0) 
     4756  if (same_dragon == SAME_DRAGON_NOT_CONNECTED) 
    46864757    num_stones = findstones(pos, MAX_BOARD*MAX_BOARD, stones); 
    46874758  else if (semeai_call) 
    46884759    find_superstring_conservative(pos, &num_stones, stones); 
     
    46964767  /* If same_dragon field is 1, only add if the played stone 
    46974768   * clearly is in contact with the goal dragon. 
    46984769   */ 
    4699   if (same_dragon <= 1) { 
     4770  if (same_dragon <= SAME_DRAGON_MAYBE_CONNECTED) { 
    47004771    do_add = 0; 
    47014772    for (k = 0; k < num_stones; k++) 
    47024773      if (owl->goal[stones[k]] != 0) { 
     
    47294800      } 
    47304801  } 
    47314802 
     4803  /* Now we handle the SAME_DRAGON_ALL_CONNECTED case. The move has 
     4804   * already been added to the goal above, so it remains to find all 
     4805   * other friendly stones in the pattern and add them too. We do that 
     4806   * by a recursive call to this function in SAME_DRAGON_CONNECTED mode. 
     4807   * This is maybe not the most elegant technique, however. 
     4808   */ 
     4809  if (same_dragon == SAME_DRAGON_ALL_CONNECTED) { 
     4810    gg_assert(pattern_data != NULL); 
     4811    for (k = 0; k < pattern_data->pattern->patlen; k++) { 
     4812      int pos2; 
     4813       
     4814      /* all the following stuff (currently) applies only at occupied cells */ 
     4815      if (pattern_data->pattern->patn[k].att != ATT_O) 
     4816        continue; 
     4817       
     4818      /* transform pattern real coordinate */ 
     4819      pos2 = AFFINE_TRANSFORM(pattern_data->pattern->patn[k].offset, 
     4820                              pattern_data->ll, pattern_data->anchor); 
     4821 
     4822      if (!owl->goal[pos2]) 
     4823        owl_update_goal(pos2, SAME_DRAGON_CONNECTED, NO_MOVE, owl, semeai_call, 
     4824                        pattern_data); 
     4825    } 
     4826  } 
     4827 
    47324828  if (1 && verbose) 
    47334829    goaldump(owl->goal); 
    47344830} 
     
    55015597  init_owl(&owl, target1, target2, NO_MOVE, 1, NULL); 
    55025598 
    55035599  if (trymove(move, color, "owl_connection_defends", target1)) { 
    5504     owl_update_goal(move, 1, NO_MOVE, owl, 0); 
     5600    owl_update_goal(move, SAME_DRAGON_MAYBE_CONNECTED, NO_MOVE, owl, 0, NULL); 
    55055601    if (!do_owl_attack(move, NULL, NULL, owl, 0)) 
    55065602      result = WIN; 
    55075603    owl->lunches_are_current = 0; 
     
    66696765  (*owl)->lunches_are_current = 0; 
    66706766  owl_mark_dragon(target1, target2, *owl, new_dragons); 
    66716767  if (move != NO_MOVE) 
    6672     owl_update_goal(move, 1, NO_MOVE, *owl, 0); 
     6768    owl_update_goal(move, SAME_DRAGON_MAYBE_CONNECTED, NO_MOVE, *owl, 0, NULL); 
    66736769  compute_owl_escape_values(*owl); 
    66746770} 
    66756771 
  • patterns/owl_defendpats.db

    RCS file: /cvsroot/gnugo/gnugo/patterns/owl_defendpats.db,v
    retrieving revision 1.137
    diff -u -r1.137 owl_defendpats.db
     
    6262# b  :  This move is maybe not connected to the goal dragon and should 
    6363#       therefore be included only after closer examination. 
    6464# 
     65# a  :  This move connects all O stones in the pattern to the goal.