gnugo-devel
[Top][All Lists]
Advanced

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

[gnugo-devel] False eye territory


From: Gunnar Farneback
Subject: [gnugo-devel] False eye territory
Date: Mon, 30 Sep 2002 21:17:29 +0200
User-agent: EMH/1.14.1 SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.3 Emacs/20.7 (sparc-sun-solaris2.7) (with unibyte mode)

This patch mostly deals with endgame tuning. One important problem has
been to distinguish between two positions like

|.OOOOO     |.OOOOO
|.O.XXO     |.O.OXO
|OOX.XO     |OOX.XO
|O*XXXO and |O*XXXO
|OX.XOO     |OX.XOO
|X.XOO.     |X.XOO.
|.XXO..     |.XXO..
+------     +------

In the left diagram * is a pure dame point, in the right diagram it is
worth one point of territory for either player to play there. The
issue at question is of course whether a topologically false eye
vertex counts as territory or not and the answer depends on whether
each string adjoining the eye is externally connected to at least one
proper eye.

This kind of analysis has been partially implemented through a set of
functions analyze_false_eye_territory(), connected_to_eye(), and
connected_to_eye_recurse() in dragon.c.

The connected_to_eye() function finds the connected set of strings of
a dragon, starting from a string next to the analyzed halfeye. Strings
are for this purpose considered connected if and only if they have a
common liberty, which is not allowed to be the half eye itself or one
of its diagonal neighbors. For these strings it examines whether their
liberties are parts of eyespaces worth at least two halfeyes (again
not counting the eyespace vertex under consideration). The function is
implemented with recursion and connected_to_eye_recurse() does the
real work.

The function analyze_false_eye_territory() loops over the
topologically false and half eye vertices and calls connected_to_eye()
for each adjoining string. The result is stored in the new global
array false_eye_territory[]. Notice that this is static information
for the initial position and is not recomputed for different moves.

The false eye territory information is incorporated into the
computation of territorial value through non_territory patterns in
barriers.db and the autohelper function false_eye_territory().

However, this is NOT a complete solution to the problem. It does,
e.g., not suffice to understand that in

|.OOOOO
|.O.*XO
|OOX.XO
|OOXXXO
|OX.XOO
|X.XOO.
|.XXO..
+------

the move at * is worth two points of territory. There are also some
weaknesses in the details of the analysis. Still this does improve the
territorial valuation of false eye points significantly.

Additionally this patch includes some more pattern tuning and a new
step to identify inessential dragons. Close to the end of
make_dragons(), critical worms are revised to be inessential if all
adjacent opponent dragons are dead. The new step is to then reclassify
critical dragons as inessential if all worms of the dragon are
inessential. This properly solves test case 13x13:53 which previously
passed by accident and would be accidentally broken by the rest of
this patch.

The regression delta is 11 PASSes and 5 FAILs. Closer analysis:

trevora:480     FAIL  accidental, valuation is way off
nngs1:26        PASS  accidental, not very good valuation
endgame:218     PASS  properly solved
trevorb:270     PASS  properly solved
trevorb:700     PASS  properly solved
trevorb:740     FAIL  accidental
nicklas2:601    PASS  improved
nngs:1010       PASS  properly solved
trevorc:170     FAIL  accidental, dragon safety underestimated
trevorc:280     PASS  solved, but chosen move overvalued instead
trevorc:560     FAIL  mostly accidental, not fully sure what's going on
trevorc:650     PASS  properly solved
13x13:41        FAIL  accidental, bad patterns
13x13:53        pass  properly solved (passed accidentally before)
trevord:970     PASS  properly solved
century2002:220 PASS  accidental
century2002:260 PASS  accidental

- new static functions analyze_false_eye_territory(),
  connected_to_eye(), and connected_to_eye_recurse() in dragon.c.
- new global array false_eye_territory[]
- critical dragons only consisting of inessential worms are revised
  to be inessential
- new function is_false_eye() in optics.c
- new autohelper functions o_captures_something(),
  x_captures_something(), false_eye_territory(), and false_eye()
- influence tuning
- tuning

/Gunnar

Index: engine/dragon.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/dragon.c,v
retrieving revision 1.82
diff -u -r1.82 dragon.c
--- engine/dragon.c     26 Sep 2002 20:28:09 -0000      1.82
+++ engine/dragon.c     30 Sep 2002 13:12:08 -0000
@@ -55,6 +55,12 @@
 static void add_adjacent_dragon(int a, int b);
 static int dragon_invincible(int pos);
 static int dragon_looks_inessential(int origin);
+static void analyze_false_eye_territory(void);
+static int connected_to_eye(int pos, int str, int color, int eye_color,
+                           struct eye_data *eye);
+static void connected_to_eye_recurse(int pos, int str, int color,
+                                    int eye_color, struct eye_data *eye,
+                                    char *mx, char *me, int *halfeyes);
 static int compute_crude_status(int pos);
 static void dragon_eye(int pos, struct eye_data[BOARDMAX]);
 static int compute_escape(int pos, int dragon_status_known);
@@ -231,6 +237,12 @@
   }
   time_report(2, "  time to find eyes", NO_MOVE, 1.0);
 
+  /* Try to determine whether topologically false and half eye points
+   * contribute to territory even if the eye doesn't solidify.
+   */
+  analyze_false_eye_territory();
+  time_report(2, "  time to analyze false eye territory", NO_MOVE, 1.0);
+
   /* Now we compute the genus. */
   for (str = BOARDMIN; str < BOARDMAX; str++) {
     if (!ON_BOARD(str))
@@ -612,7 +624,30 @@
        }
       }
     }
-  time_report(2, "  revise inessentiality", NO_MOVE, 1.0);
+  time_report(2, "  revise worm inessentiality", NO_MOVE, 1.0);
+
+  /* Revise essentiality of critical dragons. Specifically, a critical
+   * dragon consisting entirely of inessential worms is considered
+   * INESSENTIAL.
+   */
+  for (str = BOARDMIN; str < BOARDMAX; str++) {
+    if (ON_BOARD(str)
+       && dragon[str].origin == str
+       && DRAGON2(str).safety == CRITICAL) {
+      int w;
+      for (w = first_worm_in_dragon(str); w != NO_MOVE;
+          w = next_worm_in_dragon(w)) {
+       if (!worm[w].inessential)
+         break;
+      }
+
+      if (w == NO_MOVE) {
+       DEBUG(DEBUG_DRAGONS, "Dragon %1m revised to be inessential.\n", str);
+       DRAGON2(str).safety = INESSENTIAL;
+      }
+    }
+  }
+  time_report(2, "  revise dragon inessentiality", NO_MOVE, 1.0);
 
   /* Count the non-dead dragons. */
   lively_white_dragons = 0;
@@ -1030,6 +1065,191 @@
   return 1;
 }
 
+
+/* Try to determine whether topologically false and half eye points
+ * contribute to territory even if the eye doesn't solidify. The purpose
+ * is to be able to distinguish between, e.g., these positions:
+ *
+ * |.OOOOO       |.OOOOO
+ * |.O.XXO       |.O.OXO
+ * |OOX.XO       |OOX.XO
+ * |O*XXXO  and  |O*XXXO
+ * |OX.XOO       |OX.XOO
+ * |X.XOO.       |X.XOO.
+ * |.XXO..       |.XXO..
+ * +------       +------
+ * 
+ * In the left one the move at * is a pure dame point while in the
+ * right one it is worth one point of territory for either player.
+ *
+ * In general the question is whether a topologically false eye vertex
+ * counts as territory or not and the answer depends on whether each
+ * string adjoining the eye is externally connected to at least one
+ * proper eye.
+ *
+ * This function loops over the topologically false and half eye
+ * vertices and calls connected_to_eye() for each adjoining string to
+ * determine whether they all have external connection to an eye. The
+ * result is stored in the array false_eye_territory[] array.
+ */
+static void
+analyze_false_eye_territory(void)
+{
+  int pos;
+  int color;
+  int eye_color;
+  struct eye_data *eye;
+  int k;
+
+  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+    if (!ON_BOARD(pos))
+      continue;
+    
+    false_eye_territory[pos] = 0;
+
+    /* The analysis only applies to false and half eyes. */
+    if (half_eye[pos].type == 0)
+      continue;
+
+    /* Determine the color of the eye. */
+    if (white_eye[pos].color == WHITE_BORDER) {
+      color = WHITE;
+      eye_color = WHITE_BORDER;
+      eye = white_eye;
+    }
+    else if (black_eye[pos].color == BLACK_BORDER) {
+      color = BLACK;
+      eye_color = BLACK_BORDER;
+      eye = black_eye;
+    }
+    else
+      continue;
+
+    /* Make sure we have a "closed" position. Positions like
+     *
+     * |XXXXXX.
+     * |OOOOOXX
+     * |.O.O*..
+     * +-------
+     *
+     * disqualify without further analysis. (* is a false eye vertex)
+     */
+    for (k = 0; k < 4; k++)
+      if (ON_BOARD(pos + delta[k])
+         && board[pos + delta[k]] != color
+         && eye[pos + delta[k]].color != eye_color)
+       break;
+     
+    if (k < 4)
+      continue;
+
+    /* Check that all adjoining strings have external connection to an
+     * eye.
+     */
+    for (k = 0; k < 4; k++)
+      if (ON_BOARD(pos + delta[k])
+         && board[pos + delta[k]] == color
+         && !connected_to_eye(pos, pos + delta[k], color, eye_color, eye))
+       break;
+
+    if (k == 4) {
+      false_eye_territory[pos] = 1;
+      if (0)
+       gprintf("False eye territory at %1m\n", pos);
+    }
+  }
+}
+
+/* 
+ * This function (implicitly) finds the connected set of strings of a
+ * dragon, starting from (str) which is next to the analyzed halfeye
+ * at (pos). Strings are for this purpose considered connected if and
+ * only if they have a common liberty, which is not allowed to be the
+ * half eye itself or one of its diagonal neighbors. For these strings
+ * it is examined whether their liberties are parts of eyespaces worth
+ * at least two halfeyes (again not counting the eyespace at (pos)).
+ *
+ * The real work is done by the recursive function
+ * connected_to_eye_recurse() below.
+ */
+static int
+connected_to_eye(int pos, int str, int color, int eye_color,
+                struct eye_data *eye)
+{
+  char mx[BOARDMAX];
+  char me[BOARDMAX];
+  int k;
+  int halfeyes;
+
+  /* mx marks strings and liberties which have already been investigated.
+   * me marks the origins of eyespaces which have already been counted.
+   * Start by marking (pos) and the surrounding vertices in mx.
+   */
+  memset(mx, 0, sizeof(mx));
+  memset(me, 0, sizeof(me));
+  mx[pos] = 1;
+  for (k = 0; k < 8; k++)
+    if (ON_BOARD(pos + delta[k]))
+      mx[pos + delta[k]] = 1;
+
+  halfeyes = 0;
+  connected_to_eye_recurse(pos, str, color, eye_color, eye, mx, me, &halfeyes);
+
+  if (halfeyes >= 2)
+    return 1;
+  
+  return 0;
+}
+
+/* Recursive helper for connected_to_eye(). Stop searching when we
+ * have found at least two halfeyes.
+ */
+static void
+connected_to_eye_recurse(int pos, int str, int color, int eye_color,
+                        struct eye_data *eye, char *mx, char *me,
+                        int *halfeyes)
+{
+  int liberties;
+  int libs[MAXLIBS];
+  int r;
+  int k;
+
+  mark_string(str, mx, 1);
+  liberties = findlib(str, MAXLIBS, libs);
+
+  /* Search the liberties of (str) for eyespaces. */
+  for (r = 0; r < liberties; r++) {
+    if (eye[libs[r]].color == eye_color
+       && libs[r] != pos
+       && !me[eye[libs[r]].origin]) {
+      me[eye[libs[r]].origin] = 1;
+      *halfeyes += (min_eyes(&eye[libs[r]].value)
+                   + max_eyes(&eye[libs[r]].value));
+    }
+  }
+
+  if (*halfeyes >= 2)
+    return;
+
+  /* Search for new strings in the same dragon with a liberty in
+   * common with (str), and recurse.
+   */
+  for (r = 0; r < liberties; r++) {
+    if (mx[libs[r]])
+      continue;
+    mx[libs[r]] = 1;
+    for (k = 0; k < 4; k++) {
+      if (ON_BOARD(libs[r] + delta[k])
+         && board[libs[r] + delta[k]] == color
+         && is_same_dragon(str, libs[r] + delta[k])
+         && !mx[libs[r] + delta[k]])
+       connected_to_eye_recurse(pos, libs[r] + delta[k], color, eye_color,
+                                eye, mx, me, halfeyes);
+      if (*halfeyes >= 2)
+       return;
+    }
+  }
+}
 
 /* print status info on all dragons. (Can be invoked from gdb) 
  */
Index: engine/globals.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/globals.c,v
retrieving revision 1.30
diff -u -r1.30 globals.c
--- engine/globals.c    29 Sep 2002 02:45:46 -0000      1.30
+++ engine/globals.c    30 Sep 2002 13:12:09 -0000
@@ -152,6 +152,8 @@
 int close_white_worms[BOARDMAX][4];
 int number_close_white_worms[BOARDMAX];
 
+int false_eye_territory[BOARDMAX];
+
 /* Various statistics are collected here. */
 struct stats_data stats;
 
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.120
diff -u -r1.120 liberty.h
--- engine/liberty.h    28 Sep 2002 00:05:08 -0000      1.120
+++ engine/liberty.h    30 Sep 2002 13:12:13 -0000
@@ -704,6 +704,7 @@
 extern int close_white_worms[BOARDMAX][MAX_CLOSE_WORMS];
 extern int number_close_white_worms[BOARDMAX];
 
+extern int false_eye_territory[BOARDMAX];
 
 struct stats_data {
   int nodes;                     /* Number of visited nodes while reading */
@@ -934,6 +935,7 @@
 char *eyevalue_to_string(struct eyevalue *e);
 
 int is_halfeye(struct half_eye_data heye[BOARDMAX], int pos);
+int is_false_eye(struct half_eye_data heye[BOARDMAX], int pos);
 
 /* Our own abort() which prints board state on the way out.
  * (i, j) is a "relevant" board position for info. */
Index: engine/optics.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/optics.c,v
retrieving revision 1.53
diff -u -r1.53 optics.c
--- engine/optics.c     26 Sep 2002 20:28:09 -0000      1.53
+++ engine/optics.c     30 Sep 2002 13:12:15 -0000
@@ -1402,6 +1402,12 @@
   return heye[pos].type == HALF_EYE;
 }
 
+int
+is_false_eye(struct half_eye_data heye[BOARDMAX], int pos)
+{
+  return heye[pos].type == FALSE_EYE;
+}
+
 /* See Texinfo documentation (Eyes:Eye Topology). Returns:
  * - 2 or less if (pos) is a proper eye for (color);
  * - between 2 and 3 if the eye can be made false only by ko
Index: patterns/barriers.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/barriers.db,v
retrieving revision 1.38
diff -u -r1.38 barriers.db
--- patterns/barriers.db        29 Aug 2002 10:43:35 -0000      1.38
+++ patterns/barriers.db        30 Sep 2002 13:12:21 -0000
@@ -1621,6 +1621,7 @@
 
 
 Pattern Intrusion40
+# gf Revised constraint. (3.3.10)
 
 X!
 Q?
@@ -1630,7 +1631,7 @@
 A!
 Q?
 
-;lib(A)==1
+;lib(A)==1 && attack(A)
 
 
 Pattern Intrusion41
@@ -1896,6 +1897,7 @@
 
 
 Pattern Nonterritory1
+# gf Revised constraint. (3.3.10)
 
 OxO
 XoX
@@ -1905,11 +1907,42 @@
 OaO
 XbX
 
->non_oterritory(a);
->non_xterritory(b);
+>if (!false_eye_territory(a)) non_oterritory(a);
+>if (!false_eye_territory(b)) non_xterritory(b);
+
+
+Pattern Nonterritory1b
+# gf Revised constraint. (3.3.10)
+
+Ox.
+XoX
+
+:8,t
+
+Ox.
+XaX
+
+>if ((halfeye(a) || false_eye(a))
+>    && !false_eye_territory(a)) non_xterritory(a);
+
+
+Pattern Nonterritory1c
+# gf Revised constraint. (3.3.10)
+
+Xo.
+OxO
+
+:8,t
+
+Ox.
+XaX
+
+>if (false_eye(a)
+>    && !false_eye_territory(a)) non_oterritory(a);
 
 
 Pattern Nonterritory2
+# gf Revised constraint. (3.3.10)
 
 ?xO
 x.X
@@ -1921,10 +1954,11 @@
 xaX
 Ox?
 
->non_xterritory(a);
+>if (!false_eye_territory(a)) non_xterritory(a);
 
 
 Pattern Nonterritory3
+# gf Revised constraint. (3.3.10)
 
 ?oX
 o.O
@@ -1936,10 +1970,11 @@
 oaO
 Xo?
 
->non_oterritory(a);
+>if (!false_eye_territory(a)) non_oterritory(a);
 
 
 Pattern Nonterritory4
+# gf Revised constraint. (3.3.10)
 
 |xO
 |oX
@@ -1949,8 +1984,8 @@
 |aO
 |bX
 
->non_oterritory(a);
->non_xterritory(b);
+>if (!false_eye_territory(a)) non_oterritory(a);
+>if (!false_eye_territory(b)) non_xterritory(b);
 
 
 Pattern Nonterritory5
@@ -2603,22 +2638,82 @@
 
 Pattern Nonterritory36
 # gf New pattern. (3.3.7)
+# gf Revised constraint. (3.3.10)
 
 OX?
 .OX
-.ox
+.o?
 ---
 
 :8,t
 
 OX?
 baX
-.ox
+.o?
 ---
 
-;attack(a)
+;lib(a)==2 && attack(a)
 
 >non_oterritory(b);
+
+
+Pattern Nonterritory37
+# gf New pattern. (3.3.10)
+# See trevorb:270.
+
+X.?
+.XO
+.x?
+---
+
+:8,t
+
+Xa?
+cBO
+.x?
+---
+
+;lib(B)==3 && safe_omove(a) && oplay_attack(a,B)
+
+>non_xterritory(c);
+
+
+Pattern Nonterritory38
+# gf New pattern. (3.3.10)
+# See trevorc:930.
+
+OX?
+.OX
+..O
+
+:8,t
+
+OX?
+.cX
+.ab
+
+;!xplay_defend_both(a,b,c)
+
+>non_oterritory(a);
+
+
+Pattern Nonterritory39
+# gf New pattern. (3.3.10)
+# See trevorc:930.
+
+X.O
+.XO
+..X
+
+:8,t
+
+XaO
+.DO
+.bC
+
+;!oplay_defend_both(a,?,b,C,D)
+
+>non_xterritory(b);
 
 
 # END OF FILE
Index: patterns/endgame.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/endgame.db,v
retrieving revision 1.37
diff -u -r1.37 endgame.db
--- patterns/endgame.db 29 Aug 2002 10:43:35 -0000      1.37
+++ patterns/endgame.db 30 Sep 2002 13:12:22 -0000
@@ -502,6 +502,7 @@
 
 
 Pattern EE302
+# gf Revised constraint. (3.3.10)
 
 O.        endgame move
 X*        2 points reverse sente
@@ -513,7 +514,7 @@
 X*
 --
 
-;eye(*) && eye(a) && oplay_defend_both(*,a,*,b)
+;eye(*) && proper_eye(a) && oplay_defend_both(*,a,*,b)
 
 
 Pattern EE303
@@ -565,6 +566,7 @@
 
 
 Pattern EE404
+# gf Revised constraint. (3.3.10)
 
 |OX?       endgame move
 |.*.       half point gote as sacrifice
@@ -573,10 +575,10 @@
 :8,sOXe,terri(0.5)
 
 |OX?
-|.*.
+|.*a
 +---
 
-;marginal_eye(*)
+;marginal_eye(*) && proper_eye(a)
 
 
 Pattern EE404b
@@ -599,6 +601,7 @@
 
 Pattern EE405
 # gf Made main diagram consistent with constraint diagram. (3.1.18)
+# gf Revised constraint. (3.3.10)
 
 |XO?      endgame move
 |.*.      one point gote
@@ -607,10 +610,10 @@
 :8,OXe,terri(1)
 
 |XO?
-|.*.
+|.*a
 +---
 
-;marginal_eye(*)
+;marginal_eye(*) && proper_eye(a)
 
 
 Pattern EE406
@@ -1078,13 +1081,14 @@
 :8,OXe,terri(1)
 
 
-Pattern CE4
+Pattern CE4a
+# gf Split and revised pattern. (3.3.10)
 
 ??X     endgame move
 O*.     about 1 point reverse sente
 ?.O
 
-:8,OXe,terri(1),reverse_followup(2)
+:8,OXe,terri(1),reverse_followup(1)
 
 ??X
 O*.
@@ -1093,6 +1097,22 @@
 ;marginal_eye(*) && proper_eye(a)
 
 
+Pattern CE4b
+# gf Split and revised pattern. (3.3.10)
+
+??X     endgame move
+O*.     about 1 point reverse sente
+x.O
+
+:8,OXe,terri(1),reverse_followup(2)
+
+??X
+O*.
+baO
+
+;marginal_eye(*) && proper_eye(a) && proper_eye(b)
+
+
 Pattern CE6
 
 X?        push in
@@ -1258,13 +1278,14 @@
 ;marginal_eye(*) && proper_eye(b) && oplay_attack(*,a,a)
 
 
-Pattern CE20
+Pattern CE20a
+# gf Split and revised pattern. (3.3.10)
 
 ?.?         Smallish endgame
-O*O         one point reverse sente
+O*O         one point, possibly reverse sente
 ?X?
 
-:|,nOXe,terri(1),reverse_followup(2)
+:|,nOXe,terri(1),reverse_followup(1)
 
 ?a?
 O*O
@@ -1273,6 +1294,38 @@
 ;marginal_eye(*) && proper_eye(a)
 
 
+Pattern CE20b
+# gf Split and revised pattern. (3.3.10)
+
+?.x         Smallish endgame
+O*O         one point reverse sente
+?X?
+
+:8,nOXe,terri(1),reverse_followup(2)
+
+?ab
+O*O
+?X?
+
+;marginal_eye(*) && proper_eye(a) && proper_eye(b)
+
+
+Pattern CE20c
+# gf Split and revised pattern. (3.3.10)
+
+x.x         Smallish endgame
+O*O         one point reverse sente
+?X?
+
+:|,nOXe,terri(1),reverse_followup(3)
+
+cab
+O*O
+?X?
+
+;marginal_eye(*) && proper_eye(a) && proper_eye(b) && proper_eye(c)
+
+
 Pattern CE21
 # gf Constraint revised. (3.1.8)
 
@@ -1371,6 +1424,7 @@
 
 Pattern CE28
 # tm New Pattern (3.1.20)
+# gf Revised constraint. (3.3.10)
 
 OX
 .*
@@ -1382,7 +1436,17 @@
 A*
 OB
 
-; eye(A) && oplay_attack(*,B,B)
+;proper_eye(A) && oplay_attack(*,B,B)
+
+
+Pattern CE28b
+# gf New pattern. (3.3.10)
+
+OX
+.*
+O.
+
+:8,nOXe
 
 
 Pattern CE29
@@ -1458,6 +1522,7 @@
 
 
 Pattern EY1
+# gf Revised constraint. (3.3.10)
 
 X*O
 .X?
@@ -1467,10 +1532,11 @@
 X*b
 aX?
 
-;halfeye(a) && !weak(b)
+;halfeye(a) && max_eye_value(a)>0 && !false_eye_territory(a) && !weak(b)
 
 
 Pattern EY2
+# gf Revised constraint. (3.3.10)
 
 ?.O
 X*.
@@ -1482,10 +1548,11 @@
 X*.
 aX?
 
-;halfeye(a) && !weak(b)
+;halfeye(a) && max_eye_value(a)>0 && !false_eye_territory(a) && !weak(b)
 
 
 Pattern EY3
+# gf Revised constraint. (3.3.10)
 
 O*X
 .O?
@@ -1495,10 +1562,11 @@
 O*X
 aO?
 
-;halfeye(a)
+;halfeye(a) && max_eye_value(a)>0 && !false_eye_territory(a)
 
 
 Pattern EY4
+# gf Revised constraint. (3.3.10)
 
 ?.X
 O*.
@@ -1510,10 +1578,11 @@
 O*.
 aO?
 
-;halfeye(a)
+;halfeye(a) && max_eye_value(a)>0 && !false_eye_territory(a)
 
 
 Pattern EY5
+# gf Revised constraint. (3.3.10)
 
 ?.X
 O.*
@@ -1525,7 +1594,8 @@
 Ob*
 aO?
 
-;halfeye(a) && oplay_attack(*,b,b) == WIN
+;halfeye(a) && max_eye_value(a)>0 && !false_eye_territory(a)
+;&& oplay_attack(*,b,b) == WIN
 
 
 # END OF FILE
Index: patterns/mkpat.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/mkpat.c,v
retrieving revision 1.80
diff -u -r1.80 mkpat.c
--- patterns/mkpat.c    27 Aug 2002 18:06:16 -0000      1.80
+++ patterns/mkpat.c    30 Sep 2002 13:12:24 -0000
@@ -303,7 +303,12 @@
   {"non_xterritory",           1, 0.0,
                "influence_mark_non_territory(%s, OTHER_COLOR(color))"},
   {"remaining_handicap_stones",        0, 0.0, 
"free_handicap_remaining_stones()"},
-  {"total_handicap_stones",    0, 0.0, "free_handicap_total_stones()"}
+  {"total_handicap_stones",    0, 0.0, "free_handicap_total_stones()"},
+  {"o_captures_something",     1, 0.02, "does_capture_something(%s, color)"},
+  {"x_captures_something",     1, 0.02, "does_capture_something(%s,
+                                          OTHER_COLOR(color))"},
+  {"false_eye_territory",      1, 0.0, "false_eye_territory[%s]"},
+  {"false_eye",                        1, 0.01, "is_false_eye(half_eye,%s)"}
 };
 
 
Index: patterns/patterns2.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/patterns2.db,v
retrieving revision 1.45
diff -u -r1.45 patterns2.db
--- patterns/patterns2.db       29 Sep 2002 13:48:22 -0000      1.45
+++ patterns/patterns2.db       30 Sep 2002 13:12:26 -0000
@@ -1292,6 +1292,7 @@
 
 Pattern Shape1
 # gf Revised constraint. (3.1.9)
+# gf Revised constraint. (3.3.10)
 
 OO      empty triangle. Ok if the empty point of the triangle is an eye.
 .*
@@ -1301,10 +1302,11 @@
 OO
 a*
 
-;!proper_eye(a)
+;!proper_eye(a) && !o_captures_something(*) && !x_captures_something(*)
 
 
 Pattern Shape2
+# gf Revised constraint. (3.3.10)
 
 O*      empty triangle. Ok if the empty point of the triangle is an eye.
 .O
@@ -1314,7 +1316,7 @@
 O*
 aO
 
-;!eye(a)
+;!eye(a) && !o_captures_something(*)
 
 
 Pattern Shape3
@@ -2611,6 +2613,26 @@
 ;lib(a)>1 && xlib(b)>1 && oplay_attack(*,b,*)
 
 
+Pattern Shape85
+# gf New pattern. (3.3.10)
+# Usually less aji when attacking at c rather than *.
+
+OOX        attack correctly
+*XO
+...
+xxx
+
+:8,sX,shape(-1)
+
+aaX
+*BO
+.c.
+xxx
+
+;(xlib(*)==2 || (lib(a)>2 && xlib(*) < xlib(c)))
+;&& !oplay_defend(c,B)
+
+
 ###########################
 #
 # Followup moves. 
@@ -2663,6 +2685,22 @@
 bX?
 COX
 *ao
+
+;lib(C)==1 && xplay_attack(a,b) && oplay_attack(*,a,a)
+
+
+Pattern Sente1d
+# gf New pattern. (3.3.10)
+
+?OX?     Capture to avoid cutting points
+*XOX
+?O.o
+
+:8,-,reverse_followup(5)
+
+?OX?
+*COX
+?bao
 
 ;lib(C)==1 && xplay_attack(a,b) && oplay_attack(*,a,a)
 




reply via email to

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