gnugo-devel
[Top][All Lists]
Advanced

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

[gnugo-devel] read_eye() patch


From: Paul Pogonyshev
Subject: [gnugo-devel] read_eye() patch
Date: 23 Oct 2003 01:24:35 +0000

This patch solves owl:232 in an algorithmic way.  No other breakage.
I'm not sure if the patch worth it, but the cost must be negligible.

Node counters (3.5.2-pre-1 + the patch):
                1512174446 2466795 8795625

Paul



--- optics.c.~1.82.~    2003-08-25 00:39:17.000000000 +0000
+++ optics.c    2003-10-22 21:29:23.000000000 +0000
@@ -989,7 +989,7 @@ guess_eye_space(int pos, int effective_e
 
 
 /* This function does some minor reading to improve the results of
- * recognize_eye(). Currently, it has to duties. One is to read
+ * recognize_eye().  Currently, it has three duties.  One is to read
  * positions like this:
  *
  *     .XXXX|        with half eye         with proper eye
@@ -1000,14 +1000,14 @@ guess_eye_space(int pos, int effective_e
  *
  * recognize_eye() sees the eyespace of the white dragon as shown
  * (there's a half eye at a and it is considered the same as '!.' by
- * the optics code). Normally, that eye shape gives only one secure
+ * the optics code).  Normally, that eye shape gives only one secure
  * eye, and owl thinks that the white dragon is dead unconditionally.
  * This function tries to turn such ko-dependent half eyes into proper
- * eyes and chooses the best alternative. Note that we don't have any
+ * eyes and chooses the best alternative.  Note that we don't have any
  * attack/defense codes here, since owl will determine them itself.
  *
- * Another one is related to some cases when replacing half eyes with
- * '!.' doesn't work. E.g. consider this eye (optics:328):
+ * The second is related to some cases when replacing half eyes with
+ * '!.' doesn't work.  E.g. consider this eye (optics:328):
  *
  *     XXXOO         eye graph is 310:
  *     X..X.
@@ -1017,15 +1017,22 @@ guess_eye_space(int pos, int effective_e
  *
  * When this function detects such a half eye that can be attacked
  * and/or defended inside its eyespace, it tries to turn it into a
- * proper eye and see what happens. In case it gives an improvement
+ * proper eye and see what happens.  In case it gives an improvement
  * for attacker and/or defender, the function keeps new result but
  * only if new vital points are also vital points for the half eye.
  * The heuristics used here might need improvements since they are
- * based on a single game position.
+ * based on very few game positions.
+ *
+ * Finally, when the best defense of an eye is capturable and is not
+ * in the eye itself (is not a sacrifice that prevents a dead shape)
+ * and the attack on the eye is in ko, this function finds a
+ * backfilling move.  Note that if the attack is unconditional, there
+ * is no sense in backfilling, since opponent will simply kill the eye
+ * in response.
  *
  * If add_moves != 0, this function may add move reasons for (color)
- * at the vital points which are found by recognize_eye(). If add_moves 
- * == 0, set color to be EMPTY.
+ * at the vital points which are found by recognize_eye().  If
+ * add_moves == 0, set color to be EMPTY.
  */
 static int
 read_eye(int pos, int *attack_point, int *defense_point,
@@ -1176,6 +1183,57 @@ read_eye(int pos, int *attack_point, int
     }
   }
 
+  /* If the best defense move is not safe and is outside the eye under
+   * consideration and the attack on the eye is a ko, then we might
+   * have time to backfill.
+   */
+  if (*defense_point
+      && !safe_move(*defense_point, eye_color)
+      && eye[*defense_point].origin != pos
+      && is_ko(*attack_point, OTHER_COLOR(eye_color), NULL)) {
+    int num_moves = 0;
+    int moves[MAX_BOARD * MAX_BOARD];
+
+    for (k = 0; k < 4; k++) {
+      if (board[*defense_point + delta[k]] == eye_color) {
+       int i;
+       int num_chainlinks;
+       int chainlinks[MAXCHAIN];
+
+       num_chainlinks = chainlinks2(*defense_point + delta[k], chainlinks, 1);
+
+       for (i = 0; i < num_chainlinks; i++)
+         findlib(chainlinks[i], 1, &moves[num_moves++]);
+      }
+    }
+
+    if (is_self_atari(*defense_point, eye_color)) {
+      if (approxlib(*defense_point, eye_color, 1, &moves[num_moves]))
+       num_moves++;
+    }
+
+    for (k = 0; k < num_moves; k++) {
+      int i;
+
+      for (i = 0; i < k; i++) {
+       if (moves[i] == moves[k])
+         break;
+      }
+
+      if (i ==k
+         && trymove(moves[k], eye_color, "read_eye",
+                    NO_MOVE, EMPTY, NO_MOVE)) {
+       if (safe_move(*defense_point, eye_color) == WIN) {
+         *defense_point = moves[k];
+         popgo();
+         break;
+       }
+
+       popgo();
+      }
+    }
+  }
+
   if (add_moves) {
     if (eye_color == color) {
       for (k = 0; k < best_vp->num_defenses; k++)
@@ -2393,6 +2451,7 @@ test_eyeshape(int eyesize, int *eye_vert
   verbose = save_verbose;
 }
 
+
 /********************************************************************
  * The following static functions are helpers for analyze_eyegraph()
  * further down. The purpose is to evaluate eye graphs according to





reply via email to

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