gnugo-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnugo-devel] a lunch towards freedom


From: Arend Bayer
Subject: [gnugo-devel] a lunch towards freedom
Date: Sat, 10 Apr 2004 21:14:46 +0200 (CEST)


- enlarge owl goal if eaten lunch is cutting stone

If the capture of a lunch does not depend on ko, it makes sense to add
all direct neighbours of this string to the owl goal dragon, as we are
now connected to these. This is done by adding a "lunch" field to the
owl_move_data that gets set by owl_determine_life() if applicable.

I didn't try using this for semeai reading, as owl_update_goal() must
always be very careful in this case.

Arend


owl1:298        pass
Paying debts from previous patch.
nngs4:470       FAIL N10 [R8]
Owl reading improved: owl_does_attack R8 O8 now depends on ko. (Which is
correct as the string at N9 is captured unless black can win the ko.)

Total nodes: 1558968911 2849540 11009081
19 PASS
15 FAIL



diff -urp -x config.h -x config.log -x config.status -x '.#*' -x .cvsignore -x 
'*.Po' -x '*.o' -x '*.a' -x x -x Makefile -x Entries ./engine/board.c 
../gnugo-eat-lunch/engine/board.c
--- ./engine/board.c    2004-03-31 18:48:33.000000000 +0200
+++ ../gnugo-eat-lunch/engine/board.c   2004-04-09 06:20:47.000000000 +0200
@@ -2511,7 +2511,7 @@ extended_chainlinks(int str, int adj[MAX


 /*
- * Find the origin of a worm or a cavity, i.e. the point with the
+ * Find the origin of a worm, i.e. the point with the
  * smallest 1D board coordinate. The idea is to have a canonical
  * reference point for a string.
  */
diff -urp -x config.h -x config.log -x config.status -x '.#*' -x .cvsignore -x 
'*.Po' -x '*.o' -x '*.a' -x x -x Makefile -x Entries ./engine/owl.c 
../gnugo-eat-lunch/engine/owl.c
--- ./engine/owl.c      2004-04-10 19:17:05.909683448 +0200
+++ ../gnugo-eat-lunch/engine/owl.c     2004-04-10 19:19:11.810543608 +0200
@@ -118,6 +118,7 @@ struct owl_move_data {
   int value;        /* value */
   const char *name; /* name of the pattern suggesting the move */
   int same_dragon;  /* whether the move extends the dragon or not */
+  int lunch;       /* Position of a lunch, if applicable.*/
   int escape;       /* true if an escape pattern is matched */
   int defense_pos;  /* defense coordinate for vital owl attack patterns. */
 };
@@ -179,8 +180,8 @@ static void owl_shapes_callback(int anch
                                struct pattern *pattern_db,
                                int ll, void *data);
 static void owl_add_move(struct owl_move_data *moves, int move, int value,
-                        const char *reason, int same_dragon, int escape,
-                        int defense_pos, int max_moves);
+                        const char *reason, int same_dragon, int lunch,
+                        int escape, int defense_pos, int max_moves);
 static void owl_determine_life(struct local_owl_data *owl,
                               struct local_owl_data *second_owl,
                                int does_attack,
@@ -204,7 +205,7 @@ static void owl_mark_dragon(int apos, in
 static void owl_mark_worm(int apos, int bpos,
                          struct local_owl_data *owl);
 static void owl_mark_boundary(struct local_owl_data *owl);
-static void owl_update_goal(int pos, int same_dragon,
+static void owl_update_goal(int pos, int same_dragon, int lunch,
                            struct local_owl_data *owl, int semeai_call);
 static void owl_update_boundary_marks(int pos, struct local_owl_data *owl);
 static void owl_find_lunches(struct local_owl_data *owl);
@@ -228,10 +229,11 @@ static void do_owl_analyze_semeai(int ap
 static int semeai_trymove_and_recurse(int apos, int bpos,
                                      struct local_owl_data *owla,
                                      struct local_owl_data *owlb,
-                                       int owl_phase,
+                                     int owl_phase,
                                      int move, int color, int ko_allowed,
                                      int move_value, const char *move_name,
-                                     int same_dragon, int *semeai_move,
+                                     int same_dragon, int lunch,
+                                     int *semeai_move,
                                      int *this_resulta, int *this_resultb);
 static void semeai_add_sgf_comment(int value, int owl_phase);
 static int semeai_trust_tactical_attack(int str);
@@ -477,7 +479,7 @@ owl_analyze_semeai_after_move(int move,
                          resulta, resultb, semeai_move, 0, owl);
   else {
     semeai_trymove_and_recurse(bpos, apos, owlb, owla, owl,
-                              move, color, 1, 0, "mandatory move", 1,
+                              move, color, 1, 0, "mandatory move", 1, NO_MOVE,
                               semeai_move, resultb, resulta);
     *resulta = REVERSE_RESULT(*resulta);
     *resultb = REVERSE_RESULT(*resultb);
@@ -689,8 +691,8 @@ do_owl_analyze_semeai(int apos, int bpos
        else if (acode != 0
                 && find_defense(semeai_worms[sworm], NULL)) {
          critical_semeai_worms[sworm] = 1;
-         owl_add_move(moves, upos, 95, "attack semeai worm", 1, 0, NO_MOVE,
-                      MAX_SEMEAI_MOVES);
+         owl_add_move(moves, upos, 95, "attack semeai worm", 1, NO_MOVE,
+                      0, NO_MOVE, MAX_SEMEAI_MOVES);
          TRACE("Added %1m %d (-1)\n", upos, 95);
        }
       }
@@ -708,8 +710,8 @@ do_owl_analyze_semeai(int apos, int bpos
        if (attack(semeai_worms[sworm], NULL)
            && find_defense(semeai_worms[sworm], &upos)) {
          critical_semeai_worms[sworm] = 1;
-         owl_add_move(moves, upos, 85, "defend semeai worm", 1, 0, NO_MOVE,
-                      MAX_SEMEAI_MOVES);
+         owl_add_move(moves, upos, 85, "defend semeai worm", 1, NO_MOVE,
+                      0, NO_MOVE, MAX_SEMEAI_MOVES);
          TRACE("Added %1m %d (0)\n", upos, 85);
        }
       }
@@ -947,7 +949,8 @@ do_owl_analyze_semeai(int apos, int bpos
                                     owla, owlb, 50,
                                     critical_semeai_worms);
       owl_add_move(moves, outside_liberty.pos, move_value,
-                  "safe outside liberty", 0, 0, NO_MOVE, MAX_SEMEAI_MOVES);
+                  "safe outside liberty", 0, NO_MOVE, 0, NO_MOVE,
+                  MAX_SEMEAI_MOVES);
       TRACE("Added %1m %d (5)\n", outside_liberty.pos, move_value);
     }
     else if (backfill_outside_liberty.pos != NO_MOVE) {
@@ -955,7 +958,8 @@ do_owl_analyze_semeai(int apos, int bpos
                                     owla, owlb, 50,
                                     critical_semeai_worms);
       owl_add_move(moves, backfill_outside_liberty.pos, move_value,
-                  "backfilling move", 0, 0, NO_MOVE, MAX_SEMEAI_MOVES);
+                  "backfilling move", 0, NO_MOVE, 0,
+                  NO_MOVE, MAX_SEMEAI_MOVES);
       TRACE("Added %1m %d (6)\n", backfill_outside_liberty.pos, move_value);
     }
     else if (safe_common_liberty_found
@@ -964,7 +968,8 @@ do_owl_analyze_semeai(int apos, int bpos
                                     owla, owlb, 10,
                                     critical_semeai_worms);
       owl_add_move(moves, common_liberty.pos, move_value,
-                  "safe common liberty", 1, 0, NO_MOVE, MAX_SEMEAI_MOVES);
+                  "safe common liberty", 1, NO_MOVE, 0,
+                  NO_MOVE, MAX_SEMEAI_MOVES);
       TRACE("Added %1m %d (7)\n", common_liberty.pos, move_value);
     }
     else if (backfill_common_liberty.pos != NO_MOVE) {
@@ -972,7 +977,8 @@ do_owl_analyze_semeai(int apos, int bpos
                                     owla, owlb, 10,
                                     critical_semeai_worms);
       owl_add_move(moves, backfill_common_liberty.pos, move_value,
-                  "backfilling move", 0, 0, NO_MOVE, MAX_SEMEAI_MOVES);
+                  "backfilling move", 0, NO_MOVE, 0,
+                  NO_MOVE, MAX_SEMEAI_MOVES);
       TRACE("Added %1m %d (6)\n", backfill_common_liberty.pos, move_value);
     }
   }
@@ -985,8 +991,8 @@ do_owl_analyze_semeai(int apos, int bpos
       int move = semeai_propose_eyespace_filling_move(owla, owlb);

       if (move) {
-       owl_add_move(moves, move, 70,
-                    "eyespace filling", 0, 0, NO_MOVE, MAX_SEMEAI_MOVES);
+       owl_add_move(moves, move, 70, "eyespace filling", 0, NO_MOVE,
+                    0, NO_MOVE, MAX_SEMEAI_MOVES);
       }
     }

@@ -1028,8 +1034,8 @@ do_owl_analyze_semeai(int apos, int bpos
                                   owl_phase, mpos, color,
                                   best_resulta == 0 || best_resultb == 0,
                                   moves[k].value, moves[k].name,
-                                  moves[k].same_dragon, NULL,
-                                  &this_resulta, &this_resultb)) {
+                                  moves[k].same_dragon, moves[k].lunch,
+                                  NULL, &this_resulta, &this_resultb)) {
       tested_moves++;
       if (this_resultb == WIN && this_resulta == WIN) {
        /* Ideal result, no need to try any more moves. */
@@ -1207,7 +1213,7 @@ semeai_trymove_and_recurse(int apos, int
                           struct local_owl_data *owlb, int owl_phase,
                           int move, int color, int ko_allowed,
                           int move_value, const char *move_name,
-                          int same_dragon, int *semeai_move,
+                          int same_dragon, int lunch, int *semeai_move,
                           int *this_resulta, int *this_resultb)
 {
   int ko_move = 0;
@@ -1233,11 +1239,11 @@ semeai_trymove_and_recurse(int apos, int
   push_owl(&owlb);

   if (owla->color == color) {
-    owl_update_goal(move, same_dragon, owla, 1);
+    owl_update_goal(move, same_dragon, lunch, owla, 1);
     owl_update_boundary_marks(move, owlb);
   }
   else {
-    owl_update_goal(move, same_dragon, owlb, 1);
+    owl_update_goal(move, same_dragon, lunch, owlb, 1);
     owl_update_boundary_marks(move, owla);
   }

@@ -1386,7 +1392,7 @@ semeai_review_owl_moves(struct owl_move_
                                    critical_semeai_worms)
                  + value_bonus);
     owl_add_move(semeai_moves, move, move_value, owl_moves[k].name,
-                same_dragon, owl_moves[k].escape,
+                same_dragon, NO_MOVE, owl_moves[k].escape,
                 NO_MOVE, MAX_SEMEAI_MOVES);
     TRACE("Added %1m %d\n", move, move_value);
   }
@@ -1635,6 +1641,7 @@ clear_owl_move_data(struct owl_move_data
     moves[k].name = NULL;
     moves[k].same_dragon = 2;
     moves[k].escape = 0;
+    moves[k].lunch = NO_MOVE;
   }
 }

@@ -2782,7 +2789,7 @@ do_owl_defend(int str, int *move, int *w
       /* Add the stone just played to the goal dragon, unless the
        * pattern explicitly asked for not doing this.
        */
-      owl_update_goal(mpos, moves[k].same_dragon, owl, 0);
+      owl_update_goal(mpos, moves[k].same_dragon, moves[k].lunch, owl, 0);

       if (!ko_move) {
        int acode = do_owl_attack(str, NULL, &wid, owl, new_escape);
@@ -2919,7 +2926,8 @@ owl_threaten_defense(int target, int *de
       if (moves[k].pos != NO_MOVE && moves[k].value > 0)
        if (trymove(moves[k].pos, color, moves[k].name, target)) {
          owl->lunches_are_current = 0;
-         owl_update_goal(moves[k].pos, moves[k].same_dragon, owl, 0);
+         owl_update_goal(moves[k].pos, moves[k].same_dragon,
+                         moves[k].lunch, owl, 0);
          if (do_owl_defend(target, &move2, NULL, owl, 0) == WIN) {
            move = moves[k].pos;
            popgo();
@@ -3034,8 +3042,8 @@ owl_estimate_life(struct local_owl_data
      * Let's try to defend against it.
      */
     owl_add_move(vital_moves, dummy_moves[0].defense_pos,
-                dummy_moves[0].value, dummy_moves[0].name, 2, 0, NO_MOVE,
-                MAX_MOVES);
+                dummy_moves[0].value, dummy_moves[0].name, 2, NO_MOVE,
+                0, NO_MOVE, MAX_MOVES);
   }

   return 0;
@@ -3248,8 +3256,8 @@ owl_determine_life(struct local_owl_data
                  attack_point);

          if (attack_point != NO_MOVE) {
-           owl_add_move(moves, attack_point, value, reason, 1, 0, NO_MOVE,
-                        MAX_MOVES);
+           owl_add_move(moves, attack_point, value, reason, 1, NO_MOVE,
+                        0, NO_MOVE, MAX_MOVES);
            vital_values[attack_point] = value;
            eyes_attack_points[num_eyes] = attack_point;
          }
@@ -3303,8 +3311,8 @@ owl_determine_life(struct local_owl_data
                  defense_point);

          if (defense_point != NO_MOVE) {
-           owl_add_move(moves, defense_point, value, reason, 1, 0, NO_MOVE,
-                        MAX_MOVES);
+           owl_add_move(moves, defense_point, value, reason, 1, NO_MOVE,
+                        0, NO_MOVE, MAX_MOVES);
            vital_values[defense_point] = value;
          }
        }
@@ -3378,7 +3386,7 @@ owl_determine_life(struct local_owl_data
                owl->lunch[lunch], defense_point, value,
                lunch_probable, lunch_max);
          owl_add_move(moves, defense_point, value,
-                      "save lunch", 1, 0, NO_MOVE, MAX_MOVES);
+                      "save lunch", 1, NO_MOVE, 0, NO_MOVE, MAX_MOVES);
        }
        else {
          attack_point = improve_lunch_attack(owl->lunch[lunch],
@@ -3386,8 +3394,18 @@ owl_determine_life(struct local_owl_data
          TRACE("eat lunch at %1m with %1m, score %d, probable eye %d, max eye 
%d\n",
                owl->lunch[lunch], attack_point, value,
                lunch_probable, lunch_max);
-         owl_add_move(moves, attack_point, value, "eat lunch",
-                      1, 0, NO_MOVE, MAX_MOVES);
+         /* We only remember the lunch for owl_update_goal() if the lunch
+          * cannot be defended with ko after the move.
+          * If we capture the lunch by an illegal ko capture, we become
+          * ko master with this move, and hence the above is true.
+          */
+         if  (owl->lunch_attack_code[lunch] ==  WIN
+              || is_illegal_ko_capture(attack_point, owl->color))
+           owl_add_move(moves, attack_point, value, "eat lunch",
+                        1, owl->lunch[lunch], 0, NO_MOVE, MAX_MOVES);
+         else
+           owl_add_move(moves, attack_point, value, "eat lunch",
+                        1, NO_MOVE, 0, NO_MOVE, MAX_MOVES);
          num_lunches++;
          eyevalue_list[num_eyes++] = e;
        }
@@ -4376,8 +4394,8 @@ owl_shapes_callback(int anchor, int colo
        defense_pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor);
   }

-  owl_add_move(moves, move, tval, pattern->name, same_dragon, escape,
-              defense_pos, MAX_MOVES);
+  owl_add_move(moves, move, tval, pattern->name, same_dragon, NO_MOVE,
+              escape, defense_pos, MAX_MOVES);
 }


@@ -4385,8 +4403,8 @@ owl_shapes_callback(int anchor, int colo

 static void
 owl_add_move(struct owl_move_data *moves, int move, int value,
-            const char *reason, int same_dragon, int escape, int defense_pos,
-            int max_moves)
+            const char *reason, int same_dragon, int lunch,
+            int escape, int defense_pos, int max_moves)
 {
   int k;

@@ -4432,6 +4450,7 @@ owl_add_move(struct owl_move_data *moves
          * dragon under consideration.
         */
        moves[k].same_dragon = same_dragon;
+       moves[k].lunch = lunch;
        moves[k].escape = escape;
        moves[k].defense_pos = defense_pos;
       }
@@ -4612,8 +4631,8 @@ owl_mark_boundary(struct local_owl_data
  * goal. If same_dragon is 0, we don't add any stones at all.
  */
 static void
-owl_update_goal(int pos, int same_dragon, struct local_owl_data *owl,
-               int semeai_call)
+owl_update_goal(int pos, int same_dragon, int lunch,
+               struct local_owl_data *owl, int semeai_call)
 {
   int stones[MAX_BOARD * MAX_BOARD];
   int num_stones;
@@ -4659,6 +4678,18 @@ owl_update_goal(int pos, int same_dragon
       }
     }

+  /* If this move captures a lunch, we add all it's direct neighbours to the
+   * goal.
+   */
+  if (!semeai_call && lunch != NO_MOVE && board[lunch] != EMPTY) {
+    int adj, adjs[MAXCHAIN];
+    int k;
+    adj = chainlinks(lunch, adjs);
+    for (k = 0; k < adj; k++)
+      if (!owl->goal[adjs[k]])
+       mark_string(adjs[k], owl->goal, 2);
+  }
+
   if (0)
     goaldump(owl->goal);
 }
@@ -5229,7 +5260,7 @@ owl_connection_defends(int move, int tar
   init_owl(&owl, target1, target2, NO_MOVE, 1);

   if (trymove(move, color, "owl_connection_defends", target1)) {
-    owl_update_goal(move, 1, owl, 0);
+    owl_update_goal(move, 1, NO_MOVE, owl, 0);
     if (!do_owl_attack(move, NULL, NULL, owl, 0))
       result = WIN;
     owl->lunches_are_current = 0;
@@ -6333,7 +6364,7 @@ init_owl(struct local_owl_data **owl, in
   (*owl)->lunches_are_current = 0;
   owl_mark_dragon(target1, target2, *owl);
   if (move != NO_MOVE)
-    owl_update_goal(move, 1, *owl, 0);
+    owl_update_goal(move, 1, NO_MOVE, *owl, 0);
   compute_owl_escape_values(*owl);
 }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]