gnugo-devel
[Top][All Lists]
Advanced

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

[gnugo-devel] PATCH: enhanced atari_atari


From: Inge Wallin
Subject: [gnugo-devel] PATCH: enhanced atari_atari
Date: Fri, 23 Nov 2001 19:56:09 +0100 (CET)

Here is the patch that I described in my last mail.  Note that it
kind of works, but that it finds bogus sequences.  I have not run the
regressions on it yet either.

            -Inge

================================================================

Index: engine/combination.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/combination.c,v
retrieving revision 1.5
diff -u -r1.5 combination.c
--- engine/combination.c        2001/11/15 23:54:48     1.5
+++ engine/combination.c        2001/11/23 18:54:11
@@ -37,6 +37,8 @@
 
 /* Generate move reasons for combination attacks and defenses against
  * them.
+ *
+ * This is one of the move generators called from genmove().
  */
 
 void
@@ -175,8 +177,11 @@
 static void compute_aa_status(int color);
 static int get_aa_status(int pos);
 static int do_atari_atari(int color, int *attack_point,
-                         int *defense_point, int cpos,
+                         int *defense_point, int last_friendly,
                          int save_verbose, int minsize);
+static int atari_atari_succeeded(int color, int *attack_point, 
+                                int *defense_point, int last_friendly,
+                                int save_verbose, int minsize);
 
 /* Set to 1 if you want verbose traces from this function. */
 
@@ -231,8 +236,121 @@
   return 0;
 }
 
+
+/* Ask the atari_atari code whether there appears any combination
+ * attack which would capture at least minsize stones after playing at
+ * (tpos). If this happens, (*move) points to a move which prevents
+ * this blunder.
+ */
+int
+atari_atari_confirm_safety(int color, int tpos, int *move, int minsize)
+{
+  int fpos;
+  int defense_point = NO_MOVE, after_defense_point = NO_MOVE;
+  int aa_val, after_aa_val;
+  int other = OTHER_COLOR(color);
+
+  /* If aa_depth is too small, we can't see any combination attacks,
+   * so in this respect the move is safe enough.
+   */
+  if (aa_depth < 2)
+    return 1;
+
+  memset(forbidden, 0, sizeof(forbidden));
+
+  compute_aa_status(other);
+  
+  /* Accept illegal ko capture here. */
+  if (!tryko(tpos, color, NULL, EMPTY, NO_MOVE))
+    /* Really shouldn't happen. */
+    abortgo(__FILE__, __LINE__, "trymove", I(tpos), J(tpos)); 
+  increase_depth_values();
+
+  aa_val = do_atari_atari(other, &fpos, &defense_point,
+                         NO_MOVE, 0, minsize);
+  after_aa_val = aa_val;
+
+  if (aa_val == 0 || defense_point == NO_MOVE) {
+
+  /* No sufficiently large combination attack, so the move is safe from
+   * this danger.
+   *
+   * On rare occasions do_atari_atari might find a combination
+   * but no defense. In this case we assume that the combination
+   * is illusory.
+   */
+
+    popgo();
+    decrease_depth_values();
+    return 1;
+  }
+
+  while (aa_val >= after_aa_val) {
+    /* Try dropping moves from the combination and see if it still
+     * works. What we really want is to get the proper defense move
+     * into (*move).
+     */
+    after_defense_point = defense_point;
+    forbidden[fpos] = 1;
+    aa_val = do_atari_atari(other, &fpos, &defense_point, 
+                           NO_MOVE, 0, aa_val);
+  }
+
+  popgo();
+  decrease_depth_values();
+  /* We know that a combination exists, but we don't know if
+   * the original move at (aa) was really relevant. So we
+   * try omitting it and see if a combination is still found.
+   */
+  if (do_atari_atari(other, NULL, NULL, NO_MOVE, 0, minsize) >= after_aa_val)
+    return 1;
+  else {
+    if (move) *move = after_defense_point;
+    return 0;
+  }
+}
+
 
-/* Helper function for computing the aa_status for a string. */
+/* Ask the atari_atari code if after color plays at (apos)
+ * and other plays at (bpos) there appears any combination
+ * attack. Returns the size of the combination.
+ */
+
+int
+atari_atari_try_combination(int color, int apos, int bpos)
+{
+  int other = OTHER_COLOR(color);
+  int aa_val = 0;
+  int save_verbose = verbose;
+
+  if (aa_depth < 2)
+    return 0;
+  if (verbose > 0)
+    verbose--;
+  memset(forbidden, 0, sizeof(forbidden));
+
+  compute_aa_status(color);
+
+  if (trymove(apos, color, NULL, NO_MOVE, EMPTY, NO_MOVE)) {
+    if (trymove(bpos, other, NULL, NO_MOVE, EMPTY, NO_MOVE)) {
+      aa_val = do_atari_atari(color, NULL, NULL, apos, 0, 0);
+      popgo();
+    }
+    popgo();
+  }
+  verbose = save_verbose;
+  return aa_val;
+}
+
+
+/* ---------------------------------------------------------------- */
+/*                Helper functions for atari_atari.                 */
+/* ---------------------------------------------------------------- */
+
+
+/* Helper function for computing the aa_status for a string.
+ */
+
 static void
 compute_aa_status(int color)
 {
@@ -298,6 +416,7 @@
   }
 }
 
+
 /* Helper function for retrieving the aa_status for a string. We can't
  * reliably do this simply by looking up aa_status[pos] since this is
  * only valid at vertices which were non-empty at the start of the
@@ -305,6 +424,7 @@
  * locating a part of the string which was a worm at the beginning of
  * the reading.
  */
+
 static int
 get_aa_status(int pos)
 {
@@ -338,6 +458,7 @@
  * equivalent to a return value of 0.
  */
 
+#define MAX_THREAT_MOVES  10
 static int
 do_atari_atari(int color, int *attack_point, int *defense_point,
               int last_friendly, int save_verbose, int minsize)
@@ -361,65 +482,15 @@
 
   /* First look for strings adjacent to the last friendly move played
    * (or to another stone in the same string) which can be
-   * unexpectedly attacked.
+   * unexpectedly attacked.  If so, the combination attack
+   * has succeeded.
    */
-  if (last_friendly != NO_MOVE)
-    for (m = 0; m < board_size; m++)
-      for (n = 0; n < board_size; n++) {
-       int pos = POS(m, n);
-       int apos;
-
-       if (board[pos] != other)
-         continue;
-
-       if (pos != find_origin(pos))
-         continue;
-
-       if (minsize > 0 && countstones(pos) < minsize)
-         continue;
-
-       if (get_aa_status(pos) != ALIVE)
-         continue;
-
-       if (board[last_friendly] != EMPTY
-           && !adjacent_strings(last_friendly, pos))
-         continue;
-
-       if (board[last_friendly] == EMPTY
-           && !liberty_of_string(last_friendly, pos))
-         continue;
-       
-       if (debug & DEBUG_ATARI_ATARI)
-         gprintf("Considering attack of %1m. depth = %d.\n", pos, depth);
-       if (attack(pos, &apos)) {
-         if (save_verbose || (debug & DEBUG_ATARI_ATARI)) {
-           gprintf("%oThe worm %1m can be attacked at %1m after ", pos, apos);
-           dump_stack();
-         }       
-         if (attack_point) *attack_point = apos;
-         
-         /* We look for a move defending the combination.
-          * Normally this is found by find_defense but failing
-          * that, if the attacking move is a safe move for color, 
-          * it probably defends.
-          */
-         if (defense_point) {
-           if (!find_defense(pos, defense_point)) {
-             if (safe_move(apos, other)) {
-               *defense_point = apos;
-             }
-             /* No defense is found */
-             else {
-               *defense_point = NO_MOVE;
-             }
-           }
-         }
-
-         DEBUG(DEBUG_ATARI_ATARI, "%oreturn value:%d (%1m)\n",
-               countstones(pos), pos);
-         return countstones(pos);
-       }
-      }
+  if (last_friendly != NO_MOVE) {
+    int retval = atari_atari_succeeded(color, attack_point, defense_point,
+                                      last_friendly, save_verbose, minsize);
+    if (retval != 0)
+      return retval;
+  }
 
   if (stackp > aa_depth)
     return 0;
@@ -431,8 +502,11 @@
   for (m = 0; m < board_size; m++)
     for (n = 0; n < board_size; n++) {
       int pos = POS(m, n);
-      int libs[2];
+      int num_moves;
+      int moves[MAX_THREAT_MOVES];
+      int codes[MAX_THREAT_MOVES];
       int status;
+      int aa_val;
 
       if (board[pos] != other) 
        continue;
@@ -447,218 +521,198 @@
       if (status != ALIVE)
        continue;
 
-      if (findlib(pos, 2, libs) != 2)
-       continue;
+      if (stackp < aa_threat_depth) {
+       int i;
+       num_moves = attack_threats(pos, MAX_THREAT_MOVES, moves, codes);
+       if (num_moves > 0) {
+         gprintf("Threats on %1m: ", pos);
+         for (i = 0; i < num_moves; i++)
+           gprintf("%1m ", moves[i]);
+         gprintf("\n");
+       }
+      }
+      else {
+       num_moves = findlib(pos, 2, moves);
+       if (num_moves != 2)
+         continue;
+      }
 
-      for (k = 0; k < 2; k++) {
-       int apos = libs[k];
+      for (k = 0; k < num_moves; k++) {
+       int apos = moves[k];
        int bpos;
+
+       if (forbidden[apos])
+         continue;
 
-       if (!forbidden[apos]
-           && (accurate_approxlib(apos, color, 2, NULL) > 1
-               || safe_move(apos, color))) {
-         if (trymove(apos, color, "do_atari_atari-A", pos,
+       if (accurate_approxlib(apos, color, 2, NULL) < 2
+           && !safe_move(apos, color))
+         continue;
+
+
+       if (!trymove(apos, color, "do_atari_atari-A", pos,
+                    EMPTY, NO_MOVE))
+         continue;
+
+       /* try to defend the stone (m,n) which is in atari */
+       aa_val = 0;
+
+       /* Because we know (pos) is threatened there is a trivial
+        * attack and we can be sure find_defense() will give a
+        * useful defense point if it returns non-zero. Usually we
+        * would need to call attack_and_defend() to be certain of
+        * this.
+        *
+        * On the other hand, if there is no defense we have
+        * already been successful.
+        */
+       if (find_defense(pos, &bpos)
+           && trymove(bpos, other, "do_atari_atari-B", pos,
                       EMPTY, NO_MOVE)) {
-           /* try to defend the stone (m,n) which is in atari */
-           int aa_val = 0;
+         /* These moves may have been irrelevant for later
+          * reading, so in order to avoid horizon problems, we
+          * need to temporarily increase the depth values.
+          */
+         modify_depth_values(2);
+         aa_val = do_atari_atari(color, NULL, defense_point,
+                                 apos, save_verbose, minsize);
+         modify_depth_values(-2);
+         popgo();
+       }
+       else {
+         /* No way to save the ataried stone. We have been successful. */
+         popgo();
+         if (save_verbose || (debug & DEBUG_ATARI_ATARI)) {
+           gprintf("%oThe worm %m can be attacked at %1m after ", m, n,
+                   apos);
+           dump_stack();
+         }       
+         if (attack_point) *attack_point = apos;
+         if (defense_point && !find_defense(pos, defense_point))
+           *defense_point = NO_MOVE;
+             
+         DEBUG(DEBUG_ATARI_ATARI, "%oreturn value:%d (%m)\n",
+               countstones(pos), m, n);
+         return countstones(pos);
+       }
 
-           /* Because we know (m, n) is in atari there is a trivial
-            * attack and we can be sure find_defense() will give a
-            * useful defense point if it returns non-zero. Usually we
-            * would need to call attack_and_defend() to be certain of
-            * this.
-            *
-            * On the other hand, if there is no defense we have
-            * already been successful.
-            */
-           if (find_defense(pos, &bpos)
-               && trymove(bpos, other, "do_atari_atari-B", pos,
-                           EMPTY, NO_MOVE)) {
-             /* These moves may have been irrelevant for later
-               * reading, so in order to avoid horizon problems, we
-               * need to temporarily increase the depth values.
-              */
-             increase_depth_values();
-             increase_depth_values();
-             aa_val = do_atari_atari(color, NULL, defense_point,
-                                     apos, save_verbose, minsize);
-             decrease_depth_values();
-             decrease_depth_values();
-             popgo();
-           }
-           else {
-             /* No way to save the ataried stone. We have been successful. */
+       if (aa_val) {
+         /* The atari at (apos) seems to work but we still
+          * must check if there is not a better defense.
+          */
+         int cpos;
+         int res;
+
+         if (countlib(pos) == 1)
+           res = restricted_defend1(pos, &cpos, EMPTY, 0, 1, &bpos);
+         else
+           res = 0;  /* FIXME: Find other defense points. */
+      
+         if (res) {
+           if (trymove(cpos, other, "do_atari_atari-C", 
+                       pos, EMPTY, NO_MOVE)) {
+             modify_depth_values(2);
+             if (!do_atari_atari(color, NULL, defense_point,
+                                 apos, save_verbose, minsize)) 
+               aa_val = 0;
+             modify_depth_values(-2);
              popgo();
-             if (save_verbose || (debug & DEBUG_ATARI_ATARI)) {
-               gprintf("%oThe worm %m can be attacked at %1m after ", m, n,
-                       apos);
-               dump_stack();
-             }   
-             if (attack_point) *attack_point = apos;
-             if (defense_point && !find_defense(pos, defense_point))
-               *defense_point = NO_MOVE;
-             
-             DEBUG(DEBUG_ATARI_ATARI, "%oreturn value:%d (%m)\n",
-                   countstones(pos), m, n);
-             return countstones(pos);
            }
+         }
 
-           if (aa_val) {
-             /* The atari at (ai,aj) seems to work but we still
-              * must check there is not a better defense.
-              */
-             int cpos;
-             int res = restricted_defend1(pos, &cpos, EMPTY, 0, 
-                                          1, &bpos);
-             if (res) {
-               if (trymove(cpos, other, "do_atari_atari-C", 
-                            pos, EMPTY, NO_MOVE)) {
-                 increase_depth_values();
-                 increase_depth_values();
-                 if (!do_atari_atari(color, NULL, defense_point,
-                                     apos, save_verbose, minsize)) 
-                   aa_val = 0;
-                 decrease_depth_values();
-                 decrease_depth_values();
-                 popgo();
-               }
-             }
-             if (aa_val) {
-               if (attack_point) *attack_point = apos;
-               popgo();
-               DEBUG(DEBUG_ATARI_ATARI, 
-                     "%oreturn value:%d (min %d, %d (%m))\n",
-                     gg_min(aa_val, countstones(pos)), aa_val,
-                     countstones(pos), m, n);
-               /* If no defense point is known and (ai,aj) is a safe
-                * move for other, it probably defends the combination.
-                */
-               if (defense_point 
-                   && (*defense_point == NO_MOVE
-                       || !safe_move(*defense_point, other))
-                   && safe_move(apos, other)) {
-                 *defense_point = apos;
-               }
-               return gg_min(aa_val, countstones(pos));
-             }
-           }
+         if (aa_val) {
+           if (attack_point) *attack_point = apos;
            popgo();
+           DEBUG(DEBUG_ATARI_ATARI, 
+                 "%oreturn value:%d (min %d, %d (%m))\n",
+                 gg_min(aa_val, countstones(pos)), aa_val,
+                 countstones(pos), m, n);
+           /* If no defense point is known and (ai,aj) is a safe
+            * move for other, it probably defends the combination.
+            */
+           if (defense_point 
+               && (*defense_point == NO_MOVE
+                   || !safe_move(*defense_point, other))
+               && safe_move(apos, other)) {
+             *defense_point = apos;
+           }
+           return gg_min(aa_val, countstones(pos));
          }
        }
+
+       popgo();
       }
     }
+
   return 0;
 }
 
-/* Ask the atari_atari code whether there appears any combination
- * attack which would capture at least minsize stones after playing at
- * (tpos). If this happens, (*move) points to a move which prevents
- * this blunder.
- *
- * FIXME: Most of the code below is common with atari_atari() and
- *        should be broken out of both functions.
- */
-int
-atari_atari_confirm_safety(int color, int tpos, int *move, int minsize)
+
+static int
+atari_atari_succeeded(int color, int *attack_point, int *defense_point,
+                     int last_friendly, int save_verbose, int minsize)
 {
-  int fpos;
-  int defense_point = NO_MOVE, after_defense_point = NO_MOVE;
-  int aa_val, after_aa_val;
+  int m, n;
   int other = OTHER_COLOR(color);
-
-  /* If aa_depth is too small, we can't see any combination attacks,
-   * so in this respect the move is safe enough.
-   */
-  if (aa_depth < 2)
-    return 1;
-
-  memset(forbidden, 0, sizeof(forbidden));
-
-  compute_aa_status(other);
-  
-  /* Accept illegal ko capture here. */
-  if (!tryko(tpos, color, NULL, EMPTY, NO_MOVE))
-    /* Really shouldn't happen. */
-    abortgo(__FILE__, __LINE__, "trymove", I(tpos), J(tpos)); 
-  increase_depth_values();
-
-  aa_val = do_atari_atari(other, &fpos, &defense_point,
-                         NO_MOVE, 0, minsize);
-  after_aa_val = aa_val;
-
-  if (aa_val == 0 || defense_point == NO_MOVE) {
-
-  /* No sufficiently large combination attack, so the move is safe from
-   * this danger.
-   *
-   * On rare occasions do_atari_atari might find a combination
-   * but no defense. In this case we assume that the combination
-   * is illusory.
-   */
 
-    popgo();
-    decrease_depth_values();
-    return 1;
-  }
+  for (m = 0; m < board_size; m++)
+    for (n = 0; n < board_size; n++) {
+      int ii = POS(m, n);
+      int aa;
 
-  while (aa_val >= after_aa_val) {
-    /* Try dropping moves from the combination and see if it still
-     * works. What we really want is to get the proper defense move
-     * into (*move).
-     */
-    after_defense_point = defense_point;
-    forbidden[fpos] = 1;
-    aa_val = do_atari_atari(other, &fpos, &defense_point, 
-                           NO_MOVE, 0, aa_val);
-  }
+      if (board[ii] != other)
+       continue;
 
-  popgo();
-  decrease_depth_values();
-  /* We know that a combination exists, but we don't know if
-   * the original move at (aa) was really relevant. So we
-   * try omitting it and see if a combination is still found.
-   */
-  if (do_atari_atari(other, NULL, NULL, NO_MOVE, 0, minsize) >= after_aa_val)
-    return 1;
-  else {
-    if (move) *move = after_defense_point;
-    return 0;
-  }
-}
+      if (ii != find_origin(ii))
+       continue;
 
+      if (minsize > 0 && countstones(ii) < minsize)
+       continue;
 
-/* Ask the atari_atari code if after color plays at (apos)
- * and other plays at (bpos) there appears any combination
- * attack. Returns the size of the combination.
- *
- * FIXME: Most of the code below is common with atari_atari() and
- *        should be broken out of both functions.
- */
+      if (get_aa_status(ii) != ALIVE)
+       continue;
 
-int
-atari_atari_try_combination(int color, int apos, int bpos)
-{
-  int other = OTHER_COLOR(color);
-  int aa_val = 0;
-  int save_verbose = verbose;
+      if (board[last_friendly] != EMPTY
+         && !adjacent_strings(last_friendly, ii))
+       continue;
 
-  if (aa_depth < 2)
-    return 0;
-  if (verbose > 0)
-    verbose--;
-  memset(forbidden, 0, sizeof(forbidden));
+      if (board[last_friendly] == EMPTY
+         && !liberty_of_string(last_friendly, ii))
+       continue;
+       
+      if (debug & DEBUG_ATARI_ATARI)
+       gprintf("Considering attack of %1m. depth = %d.\n", ii, depth);
 
-  compute_aa_status(color);
+      if (attack(ii, &aa)) {
+       if (save_verbose || (debug & DEBUG_ATARI_ATARI)) {
+         gprintf("%oThe worm %1m can be attacked at %1m after ", ii, aa);
+         dump_stack();
+       }         
+       if (attack_point) *attack_point = aa;
+         
+       /* We look for a move defending the combination.
+        * Normally this is found by find_defense but failing
+        * that, if the attacking move is a safe move for color, 
+        * it probably defends.
+        */
+       if (defense_point) {
+         if (!find_defense(ii, defense_point)) {
+           if (safe_move(aa, other)) {
+             *defense_point = aa;
+           }
+           /* No defense is found */
+           else {
+             *defense_point = NO_MOVE;
+           }
+         }
+       }
 
-  if (trymove(apos, color, NULL, NO_MOVE, EMPTY, NO_MOVE)) {
-    if (trymove(bpos, other, NULL, NO_MOVE, EMPTY, NO_MOVE)) {
-      aa_val = do_atari_atari(color, NULL, NULL, apos, 0, 0);
-      popgo();
+       DEBUG(DEBUG_ATARI_ATARI, "%oreturn value:%d (%1m)\n",
+             countstones(ii), ii);
+       return countstones(ii);
+      }
     }
-    popgo();
-  }
-  verbose = save_verbose;
-  return aa_val;
+
+  return 0;
 }
 
 
Index: engine/dragon.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/dragon.c,v
retrieving revision 1.29
diff -u -r1.29 dragon.c
--- engine/dragon.c     2001/11/23 14:08:42     1.29
+++ engine/dragon.c     2001/11/23 18:54:11
@@ -78,12 +78,19 @@
       dragon[ii].effective_size     = worm[ii].effective_size;
       dragon[ii].color              = worm[ii].color;
       dragon[ii].origin             = worm[ii].origin;
+#if 0
+      for (i = 0; i < MAX_TACTICAL_POINTS; ++i) {
+       dragon[ii].owl_attack_points[i]   = NO_MOVE;
+       dragon[ii].owl_attack_codes[i]    = 0;
+      }
+#else
       dragon[ii].owl_attack_point   = NO_MOVE;
       dragon[ii].owl_attack_code    = 0;
-      dragon[ii].owl_attack_certain =  1;
+#endif
+      dragon[ii].owl_attack_certain = 1;
       dragon[ii].owl_defense_point  = NO_MOVE;
       dragon[ii].owl_defense_code   = 0;
-      dragon[ii].owl_defend_certain =  1;
+      dragon[ii].owl_defend_certain = 1;
       dragon[ii].owl_status         = UNCHECKED;
       dragon[ii].status             = UNKNOWN;
       dragon[ii].matcher_status     = UNKNOWN;
@@ -395,8 +402,9 @@
   if (stop_before_owl)
     return;
   
-  /* Determine owl status of each dragon. */
-
+  /* Determine life and death status of each dragon using the owl code
+   * if necessary.
+   */
   purge_persistent_owl_cache();
 
   for (m = 0; m < board_size; m++)
@@ -1452,7 +1460,7 @@
 }
 
 /* Wrapper to call the function above and compute the escape potential
- * for the dragon at (m, n).
+ * for the dragon at (pos).
  */
 static int
 compute_escape(int pos, int dragon_status_known)
@@ -1471,9 +1479,13 @@
       goal[ii] = is_same_dragon(ii, pos);
     }
 
+  /* Compute escape_value array.  Points are awarded for moyo (4),
+   * area (2) or EMPTY (1).  Values may change without notice.
+   */
   compute_escape_influence(goal, board[pos], escape_value,
                           dragon_status_known);
 
+  /* If we can reach a live group, award 6 points. */
   for (i = 0; i < board_size; i++)
     for (j = 0; j < board_size; j++) {
       ii = POS(i, j);
Index: engine/globals.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/globals.c,v
retrieving revision 1.11
diff -u -r1.11 globals.c
--- engine/globals.c    2001/10/16 19:53:01     1.11
+++ engine/globals.c    2001/11/23 18:54:11
@@ -61,6 +61,7 @@
 int ko_depth;           /* deep reading cut off */
 int branch_depth;       /* deep reading cut off */
 int aa_depth;
+int aa_threat_depth;
 int owl_distrust_depth;   /* below this owl trusts the optics code */
 int owl_branch_depth;     /* below this owl tries only one variation */
 int owl_reading_depth;    /* owl does not read below this depth */
@@ -73,6 +74,7 @@
 int mandated_ko_depth;        /* deep reading cut off, mandated value */
 int mandated_branch_depth;    /* deep reading cut off, mandated value */
 int mandated_aa_depth;
+int mandated_aa_threat_depth = -1;
 int mandated_owl_distrust_depth;  
 int mandated_owl_branch_depth;  
 int mandated_owl_reading_depth; 
Index: engine/gnugo.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/gnugo.h,v
retrieving revision 1.23
diff -u -r1.23 gnugo.h
--- engine/gnugo.h      2001/11/23 03:06:22     1.23
+++ engine/gnugo.h      2001/11/23 18:54:11
@@ -284,6 +284,7 @@
 extern int mandated_ko_depth;
 extern int mandated_branch_depth;
 extern int mandated_aa_depth;
+extern int mandated_aa_threat_depth;
 extern int mandated_owl_distrust_depth;
 extern int mandated_owl_branch_depth;
 extern int mandated_owl_reading_depth;
Index: engine/influence.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/influence.c,v
retrieving revision 1.20
diff -u -r1.20 influence.c
--- engine/influence.c  2001/11/14 19:16:28     1.20
+++ engine/influence.c  2001/11/23 18:54:11
@@ -1171,18 +1171,22 @@
                         int dragons_known)
 {
   int i, j;
+  int ii;
+
   compute_influence(&escape_influence, OTHER_COLOR(color), -1, -1,
                    dragons_known, goal, NULL);
   for (i = 0; i < board_size; i++)
     for (j = 0; j < board_size; j++) {
+      ii = POS(i, j);
+
       if (whose_moyo(&escape_influence, i, j) == color)
-       escape_value[POS(i, j)] = 4;
+       escape_value[ii] = 4;
       else if (whose_area(&escape_influence, i, j) == color)
-       escape_value[POS(i, j)] = 2;
+       escape_value[ii] = 2;
       else if (whose_area(&escape_influence, i, j) == EMPTY)
-       escape_value[POS(i, j)] = 1;
+       escape_value[ii] = 1;
       else
-       escape_value[POS(i, j)] = 0;
+       escape_value[ii] = 0;
     }
 
   if (0 && (debug & DEBUG_ESCAPE) && verbose > 0) {
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.47
diff -u -r1.47 liberty.h
--- engine/liberty.h    2001/11/23 03:06:22     1.47
+++ engine/liberty.h    2001/11/23 18:54:11
@@ -229,6 +229,7 @@
 int attack_either(int astr, int bstr);
 int defend_both(int astr, int bstr);
 int break_through(int apos, int bpos, int cpos);
+int attack_threats(int pos, int max_threats, int moves[], int codes[]);
 
 int restricted_defend1(int str, int *move, int komaster, int kom_pos,
                       int num_forbidden_moves, int *forbidden_moves);
@@ -516,6 +517,7 @@
 extern int fourlib_depth;       /* deep reading cutoff */
 extern int ko_depth;            /* deep ko reading cutoff */
 extern int aa_depth;            /* deep global reading cutoff */
+extern int aa_threat_depth;
 extern int owl_distrust_depth;  /* below this owl trusts the optics code */
 extern int owl_branch_depth;    /* below this owl tries only one variation */
 extern int owl_reading_depth;   /* owl does not read below this depth */
@@ -586,8 +588,8 @@
    * respect to the codes so that the first element contains the best
    * result.
    */
-  int attack_codes[MAX_TACTICAL_POINTS];
   int attack_points[MAX_TACTICAL_POINTS];
+  int attack_codes[MAX_TACTICAL_POINTS];
   int defend_codes[MAX_TACTICAL_POINTS];
   int defense_points[MAX_TACTICAL_POINTS];
   int attack_threat_codes[MAX_TACTICAL_POINTS];
@@ -615,7 +617,12 @@
   int owl_status;          /* (ALIVE, DEAD, UNKNOWN, CRITICAL, UNCHECKED)    */
   int owl_attack_point;    /* vital point for attack                         */
   int owl_attack_code;     /* ko result code                                 */
+#if 0
+  int owl_attack_points[MAX_TACTICAL_POINTS];
+  int owl_attack_codes[MAX_TACTICAL_POINTS];
+#endif
   int owl_attack_certain;  /* 0 if owl reading node limit is reached         */
+
   int owl_second_attack_point;/* if attacker gets both attack points, wins   */
   int owl_defense_point;   /* vital point for defense                        */
   int owl_defense_code;    /* ko result code                                 */
Index: engine/move_reasons.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.c,v
retrieving revision 1.40
diff -u -r1.40 move_reasons.c
--- engine/move_reasons.c       2001/11/22 15:58:03     1.40
+++ engine/move_reasons.c       2001/11/23 18:54:12
@@ -3186,10 +3186,10 @@
        }
 
 #if 0
-       if (dragon[POS(bi, bj)].status == CRITICAL) {
+       if (dragon[bb].matcher_status == CRITICAL) {
          this_value = ???
-         TRACE("  %m: %f - vital for %m\n",
-               m, n, this_value, bi, bj);
+         TRACE("  %1m: %f - vital for %1m\n",
+               pos, this_value, bb);
          tot_value += this_value;
        }
 #endif
@@ -3333,7 +3333,7 @@
       
       continue;
     }
-    
+
     TRACE("  %1m: %f - strategic effect on %1m\n",
          pos, dragon_value[k], dragons[k]);
     tot_value += dragon_value[k];
Index: engine/reading.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/reading.c,v
retrieving revision 1.31
diff -u -r1.31 reading.c
--- engine/reading.c    2001/11/15 16:18:40     1.31
+++ engine/reading.c    2001/11/23 18:54:13
@@ -134,6 +134,8 @@
 
 
 /* ================================================================ */
+/*                     Persistent reading cache                     */
+/* ================================================================ */
 
 
 /* Persistent reading cache to reuse read results between moves and
@@ -758,6 +760,94 @@
 }
 
 
+/* ---------------------------------------------------------------- */
+/*                              Threats                             */
+/* ---------------------------------------------------------------- */
+
+
+/* Return up to max_threats threats to capture the string at pos.
+ * If the string is directly attackable the number of threats
+ * is reported to be 0.
+ *
+ * FIXME: Shall we report upgrades, like we can capture in ko but
+ *        have a threat to capture unconditionally.
+ */
+
+int
+attack_threats(int pos, int max_threats, int moves[], int codes[])
+{
+  int  other;
+  int  num_threats;
+  int  liberties;
+  int  libs[MAXLIBS];
+  int  k;
+  int  l;
+
+  ASSERT1(IS_STONE(board[pos]), pos);
+  other = OTHER_COLOR(board[pos]);
+
+  /* Only handle strings with no way to capture immediately. 
+   * For now, we treat ko the same as unconditionally. */
+  if (attack(pos, NULL) != 0)
+    return 0;
+
+  num_threats = 0;
+
+  /* This test would seem to be unnecessary since we only attack
+   * strings with attack_code == 0, but it turns out that single
+   * stones with one liberty that can be captured, but come to
+   * live again in a snap-back get attack_code == 0. 
+   *
+   * The test against 6 liberties is just an optimization.
+   */
+  liberties = findlib(pos, MAXLIBS, libs);
+  if (liberties > 1 && liberties < 6) {
+    for (k = 0; k < liberties && num_threats < max_threats; k++) {
+      int aa = libs[k];
+
+      /* Try to threaten on the liberty. */
+      if (trymove(aa, other, "threaten attack", pos, EMPTY, NO_MOVE)) {
+       int acode = attack(pos, NULL);
+       if (acode != 0) {
+         moves[num_threats] = aa;
+         codes[num_threats] = acode;
+         num_threats++;
+       }
+       popgo();
+      }
+      if (num_threats == max_threats)
+       break;
+
+      /* Try to threaten on second order liberties. */
+      for (l = 0; l < 4; l++) {
+       int bb = libs[k] + delta[l];
+
+       if (!ON_BOARD(bb)
+           || IS_STONE(board[bb])
+           || liberty_of_string(bb, pos))
+         continue;
+
+       if (trymove(bb, other, "threaten attack", pos, EMPTY, NO_MOVE)) {
+         int acode = attack(pos, NULL);
+         if (acode != 0) {
+           moves[num_threats] = bb;
+           codes[num_threats] = acode;
+           num_threats++;
+         }
+         popgo();
+       }
+      }
+    }
+  }
+
+
+  /* FIXME: Threaten to attack by saving weak neighbors. 
+   *        Get it from worm.c. */
+
+  return num_threats;
+}
+
+
 /* ================================================================ */  
 /*                       Defensive functions                        */
 /* ================================================================ */
@@ -917,7 +1007,6 @@
   num_moves = 1;
   
   break_chain_moves(str, moves, scores, &num_moves);
-
   order_moves(str, num_moves, moves, scores, color, read_function_name);
 
   for (k = 0; k < num_moves; k++) {
@@ -4498,6 +4587,7 @@
   
   break_chain_moves(str, moves, scores, &num_moves);
   order_moves(str, num_moves, moves, scores, color, read_function_name);
+
   for (k = 0; k < num_moves; k++) {
     int ko_capture;
 
Index: engine/utils.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/utils.c,v
retrieving revision 1.24
diff -u -r1.24 utils.c
--- engine/utils.c      2001/10/26 07:21:11     1.24
+++ engine/utils.c      2001/11/23 18:54:14
@@ -465,6 +465,7 @@
 #define KO_DEPTH              8
 
 #define AA_DEPTH              6
+#define AA_THREAT_DEPTH       1
 
 /* Pattern based reading */
 #define OWL_DISTRUST_DEPTH    6
@@ -493,6 +494,7 @@
     branch_depth        = gg_max(3, BRANCH_DEPTH - 10 + level);
     fourlib_depth       = gg_max(1, FOURLIB_DEPTH - 10 + level);
     aa_depth            = gg_max(0, AA_DEPTH - 10 + level);
+    aa_threat_depth     = gg_max(0, AA_THREAT_DEPTH - 10 + level);
     owl_distrust_depth  = gg_max(1, OWL_DISTRUST_DEPTH - 5 + level/2);
     owl_branch_depth    = gg_max(2, OWL_BRANCH_DEPTH - 5 + level/2);
     owl_reading_depth   = gg_max(5, OWL_READING_DEPTH - 5 + level/2);
@@ -514,6 +516,7 @@
     else
       fourlib_depth     = gg_max(1, FOURLIB_DEPTH - 9 + level);
     aa_depth            = gg_max(0, AA_DEPTH - 10 + level);
+    aa_threat_depth     = gg_max(0, AA_THREAT_DEPTH - 10 + level);
     owl_distrust_depth  = gg_max(1, OWL_DISTRUST_DEPTH - 5 
                              + (level+1)/2);
     owl_branch_depth    = gg_max(2, OWL_BRANCH_DEPTH - 5 + (level+1)/2);
@@ -535,6 +538,7 @@
     else
       fourlib_depth     = gg_max(1, FOURLIB_DEPTH - 1);
     aa_depth            = gg_max(0, AA_DEPTH - 2);
+    aa_threat_depth     = gg_max(0, AA_THREAT_DEPTH - 2);
     owl_distrust_depth  = gg_max(1, OWL_DISTRUST_DEPTH - 1);
     owl_branch_depth    = gg_max(2, OWL_BRANCH_DEPTH - 5 + (level+1)/2);
     owl_reading_depth   = gg_max(5, OWL_READING_DEPTH - 5 + (level+1)/2);
@@ -555,6 +559,7 @@
     else
       fourlib_depth     = gg_max(1, FOURLIB_DEPTH - 8 + level);
     aa_depth            = gg_max(0, AA_DEPTH - 9 + level);
+    aa_threat_depth     = gg_max(0, AA_THREAT_DEPTH - 9 + level);
     owl_distrust_depth  = gg_max(1, OWL_DISTRUST_DEPTH - 5
                              + (level+1)/2);
     owl_branch_depth    = gg_max(2, OWL_BRANCH_DEPTH - 4 + level/2);
@@ -582,6 +587,8 @@
     branch_depth = mandated_branch_depth;
   if (mandated_aa_depth != -1)
     aa_depth = mandated_aa_depth;
+  if (mandated_aa_threat_depth != -1)
+    aa_threat_depth = mandated_aa_threat_depth;
   if (mandated_owl_distrust_depth != -1)
     owl_distrust_depth = mandated_owl_distrust_depth;
   if (mandated_owl_branch_depth != -1)
Index: regression/niki.tst
===================================================================
RCS file: /cvsroot/gnugo/gnugo/regression/niki.tst,v
retrieving revision 1.10
diff -u -r1.10 niki.tst
--- regression/niki.tst 2001/11/18 05:33:02     1.10
+++ regression/niki.tst 2001/11/23 18:54:14
@@ -66,10 +66,9 @@
 #DESCRIPTION=Very tough position
 #SEVERITY=3
 #Note: G16 is still very very big.  See niki.tst#8 & nikit.tst#9
-# FIXME: Same move listed twice.
 loadsgf games/niki.sgf 158
 11 gg_genmove white
-#? [M6|M6|P7]*
+#? [M6|P6|P7]*
 
 
 #CATEGORY=OWL_TUNING



reply via email to

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