gnugo-devel
[Top][All Lists]
Advanced

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

[gnugo-devel] tuning patch


From: Gunnar Farneback
Subject: [gnugo-devel] tuning patch
Date: Sun, 11 May 2003 23:26:44 +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 includes various tuning, mostly of the owl and endgame
varieties.

- new static function endgame_find_backfilling_dame() in endgame.c
- new static function endgame_find_liberties() broken out of
  endgame_analyze_worm_liberties()
- new functions owl_mineye() and owl_maxeye() and corresponding
  autohelper functions
- move_connects_strings revised not to care about connecting
  invincible strings
- ALL_MOVE move reasons no longer considered to guarantee a safe move
- never give cutstone bonus for an inessential string
- tuning
- owl tuning

In endgame.c some comments have been revised but more importantly the
code has been reorganized so that the analysis of liberties can be
reused in a new function which finds backfilling dame. These are
described in a code comment like this:

/* A backfilling dame is a defense move, usually within potential own
 * territory, which does not have to be played immediately but after
 * outer liberties of some string have been filled. If those outer
 * liberties are dame points (here inessential liberties), it is
 * usually better to play the backfilling moves before filling the
 * dame points. If nothing else it reduces the risk for making stupid
 * blunders while filling dame.
 */

An example of the latter is blunder:25 where R5 is found as a
backfilling dame.

Regression changes are:

filllib:41      PASS M8 [M8]
blunder:25      PASS R5 [!P9|M6|T9]
trevorc:1420    FAIL A11 [J4]
nngs3:1180      PASS A6 [A6]
nngs4:340       PASS D2 [D2]
gunnar:24       PASS K3 [K3]
gunnar:26       PASS F9 [F9]
nando:25        PASS A14 [!P16]

The trevorc:1420 failure is mostly accidental. The correct move was
not valued correctly before either but was chosen thanks to the
connect strings bonus. Now a backfilling dame gets valued higher from
this heuristic. The passes all look real except for nando:25, which is
most likely accidental.

/Gunnar

Index: engine/endgame.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/endgame.c,v
retrieving revision 1.4
diff -u -r1.4 endgame.c
--- engine/endgame.c    26 Feb 2003 19:43:50 -0000      1.4
+++ engine/endgame.c    11 May 2003 21:18:26 -0000
@@ -26,7 +26,14 @@
 
 
 static void endgame_analyze_worm_liberties(int pos, int color);
-
+static void endgame_find_backfilling_dame(int str, int color);
+static int endgame_find_liberties(int str, int *essential_liberties,
+                                 int essential_libs[MAXLIBS],
+                                 int *inessential_liberties,
+                                 int inessential_libs[MAXLIBS],
+                                 int *false_eye_liberties,
+                                 int false_eye_libs[MAXLIBS]);
+  
 
 /* Generate endgame moves. These are typically moves in settled positions,
  * they aren't worth many points. Currently, we generate such moves using
@@ -52,8 +59,11 @@
        && dragon[pos].status == ALIVE
        && !worm[pos].invincible
        && !worm[pos].inessential
-       && worm[pos].attack_codes[0] == 0)
+       && worm[pos].attack_codes[0] == 0) {
       endgame_analyze_worm_liberties(pos, color);
+      if (board[pos] == color)
+       endgame_find_backfilling_dame(pos, color);
+    }
   }
 }
 
@@ -68,17 +78,18 @@
  *   .OXX..X           X..XOOO|
  *   .OOOXX.           XXXXXXX|
  *
- * The two marked with `*' moves are worth one point in gote each (for both
- * colors). The first one is obvious - once black runs short on liberties,
- * he'll have to defend in his own eyespace, wasting one point. In the second
- * position, although black sacrifice one point by playing in white's 
territory,
- * he forces white to eventually capture the black string, losing three points.
- * However, white has to play at `*' sooner or later if black doesn't take
- * that vertex, so the move is worth 3 - 1 - 1 = 1 point only, not two.
+ * The two marked with `*' moves are worth one point in gote each (for
+ * both colors). The first one is obvious - once black runs short on
+ * liberties, he'll have to defend in his own eyespace, wasting one
+ * point. In the second position, although black sacrifices one point
+ * by playing in white's territory, he forces white to eventually
+ * capture the black string, losing three points. However, white has
+ * to play at `*' sooner or later if black doesn't take that vertex, so
+ * the move is worth 3 - 1 - 1 = 1 point only, not two.
  *
- * This function is able to find such moves. Algorithm is based on finding
- * such called "inessential liberties". These are defined as liberties, which
- * satisfy five conditions:
+ * This function is able to find such moves. The algorithm is based on
+ * finding so called "inessential liberties". These are defined as
+ * liberties, which satisfy five conditions:
  *
  *     1) they are not within an eye (not in someone's territory),
  *     2) all their adjacent worms and dragons are alive,
@@ -90,7 +101,7 @@
  * Such liberties are supposed to never become territory (they can't become
  * an additional eye for the worm under consideration), the worm cannot
  * connect to something via such a liberty and they will (or at least can)
- * be eventually filled by either of the players.
+ * eventually be filled by either of the players.
  *
  * FIXME: This function can probably be improved to handle more cases.
  */
@@ -100,13 +111,11 @@
   int k;
   int worm_color = board[pos];
   int other = OTHER_COLOR(worm_color);
-  int liberties;
-  int libs[MAXLIBS];
-  int essential_liberties = 0;
+  int essential_liberties;
   int essential_libs[MAXLIBS];
-  int inessential_liberties = 0;
+  int inessential_liberties;
   int inessential_libs[MAXLIBS];
-  int false_eye_liberties = 0;
+  int false_eye_liberties;
   int false_eye_libs[MAXLIBS];
   int num_attacks;
   int num_attacks2;
@@ -115,54 +124,11 @@
   int apos;
   int value;
 
-  /* Find all worm liberties. */
-  liberties = findlib(pos, MAXLIBS, libs);
-
-  /* Loop over the liberties and find inessential and essential ones. The
-   * latter are defined as those, which are not inside an eye space, but
-   * don't otherwise qualify as inessential. If we find a non-alive (dead
-   * or critical) worm or dragon around, we stop looking for liberties and
-   * skip the current worm (position is unstable).
-   */
-  for (k = 0; k < liberties; k++) {
-    int lib = libs[k];
-
-    if (!is_proper_eye_space(lib)) {
-      int i;
-      int essential = 0;
-      int found_other = 0;
-
-      for (i = 0; i < 4; i++) {
-       int pos2 = lib + delta[i];
-
-       if (!IS_STONE(board[pos2]))
-         continue;
-
-       if (worm[pos2].attack_codes[0] != 0 || dragon[pos2].status != ALIVE)
-         return;
-
-       if (board[pos2] == worm_color) {
-         if (worm[pos2].origin != pos)
-           essential = 1;
-       }
-       else
-         found_other = 1;
-      }
-
-      if (i < 4)
-       break;
-
-      if (found_other) {
-       if (essential)
-         essential_libs[essential_liberties++] = lib;
-       else
-         inessential_libs[inessential_liberties++] = lib;
-      }
-      else if (is_false_eye(half_eye, lib) && !false_eye_territory[lib])
-       false_eye_libs[false_eye_liberties++] = lib;
-    }
-  }
-
+  if (!endgame_find_liberties(pos, &essential_liberties, essential_libs,
+                             &inessential_liberties, inessential_libs,
+                             &false_eye_liberties, false_eye_libs))
+    return;
+  
   apos = NO_MOVE;
   num_attacks = 0;
 
@@ -180,9 +146,9 @@
    * worm have appeared.
    */
   if (k == inessential_liberties && board[pos] != EMPTY) {
-    /* Try to look for moves as in position 1. If the worm still has more than
-     * one liberty, try to play on every essential liberty and see if an attack
-     * appears.
+    /* Try to look for moves as in position 1. If the worm still has
+     * more than one liberty, try to play on every essential liberty
+     * and see if an attack appears.
      */
     if (countlib(pos) > 1) {
       for (k = 0; k < essential_liberties; k++) {
@@ -269,8 +235,9 @@
     }
   }
   else {
-    /* We were unable to fill all the liberties. Modify `inessential_liberties'
-     * in order to undo the right number of moves.
+    /* We were unable to fill all the liberties. Modify
+     * `inessential_liberties' in order to undo the right number of
+     * moves.
      */
     inessential_liberties = k;
   }
@@ -338,9 +305,10 @@
 
   value = 0;
   if (apos != NO_MOVE) {
-    /* We use the number of string's liberties minus 2 as the value of the
-     * move. Minus 2 is explained in the comment before the function. In
-     * some rare cases the value may differ, but this must be a good guess.
+    /* We use the number of string's liberties minus 2 as the value of
+     * the move. Minus 2 is explained in the comment before the
+     * function. In some rare cases the value may differ, but this
+     * should be a good guess.
      */
     value = accuratelib(apos, other, MAXLIBS, NULL) - 2;
   }
@@ -409,3 +377,137 @@
     popgo();
   ASSERT1(stackp == 0, pos);
 }
+
+/* A backfilling dame is a defense move, usually within potential own
+ * territory, which does not have to be played immediately but after
+ * outer liberties of some string have been filled. If those outer
+ * liberties are dame points (here inessential liberties), it is
+ * usually better to play the backfilling moves before filling the
+ * dame points. If nothing else it reduces the risk for making stupid
+ * blunders while filling dame.
+ */
+static void
+endgame_find_backfilling_dame(int str, int color)
+{
+  int k;
+  int other = OTHER_COLOR(color);
+  int essential_liberties;
+  int essential_libs[MAXLIBS];
+  int inessential_liberties;
+  int inessential_libs[MAXLIBS];
+  int false_eye_liberties;
+  int false_eye_libs[MAXLIBS];
+  int dpos;
+  int loop_again = 1;
+  int move = NO_MOVE;
+
+  while (loop_again) {
+    loop_again = 0;
+    if (!endgame_find_liberties(str, &essential_liberties, essential_libs,
+                               &inessential_liberties, inessential_libs,
+                               &false_eye_liberties, false_eye_libs))
+      break;
+    for (k = 0; k < inessential_liberties; k++) {
+      if (!safe_move(inessential_libs[k], other)
+         || !trymove(inessential_libs[k], other,
+                     "endgame", str, EMPTY, NO_MOVE))
+       continue;
+      if (board[str] == EMPTY)
+       break;
+      if (attack_and_defend(str, NULL, NULL, NULL, &dpos)) {
+       if (worm[dpos].color == EMPTY)
+         move = dpos;
+       trymove(move, color, "endgame", str, EMPTY, NO_MOVE);
+       loop_again = 1;
+       break;
+      }
+    }
+  }
+  
+  while (stackp > 0)
+    popgo();
+
+  if (move != NO_MOVE && safe_move(move, color)) {
+    TRACE("  backfilling dame found at %1m for string %1m\n", move, str);
+    add_expand_territory_move(move);
+    set_minimum_territorial_value(move, 0.1);
+  }    
+}
+
+/* Find liberties of the string str with various characteristics. See
+ * the comments above endgame_analyze_worm_liberties() for more
+ * information.
+ */
+static int
+endgame_find_liberties(int str,
+                      int *essential_liberties, int essential_libs[MAXLIBS],
+                      int *inessential_liberties,
+                      int inessential_libs[MAXLIBS],
+                      int *false_eye_liberties, int false_eye_libs[MAXLIBS])
+{
+  int liberties;
+  int libs[MAXLIBS];
+  int k;
+
+  ASSERT1(IS_STONE(board[str]), str);
+
+  *essential_liberties = 0;
+  *inessential_liberties = 0;
+  *false_eye_liberties = 0;
+  
+  /* Find all string liberties. */
+  liberties = findlib(str, MAXLIBS, libs);
+
+  /* Loop over the liberties and find inessential and essential ones. The
+   * latter are defined as those, which are not inside an eye space, but
+   * don't otherwise qualify as inessential. If we find a non-alive (dead
+   * or critical) worm or dragon around, we stop looking for liberties and
+   * skip the current worm (position is unstable).
+   */
+  for (k = 0; k < liberties; k++) {
+    int lib = libs[k];
+
+    if (!is_proper_eye_space(lib)) {
+      int i;
+      int essential = 0;
+      int found_other = 0;
+
+      for (i = 0; i < 4; i++) {
+       int pos = lib + delta[i];
+
+       if (!IS_STONE(board[pos]) || !IS_STONE(worm[pos].color))
+         continue;
+
+       if (worm[pos].attack_codes[0] != 0 || dragon[pos].status != ALIVE)
+         return 0;
+
+       if (board[pos] == board[str]) {
+         if (find_origin(pos) != find_origin(str))
+           essential = 1;
+       }
+       else
+         found_other = 1;
+      }
+
+      if (i < 4)
+       break;
+
+      if (found_other) {
+       if (essential)
+         essential_libs[(*essential_liberties)++] = lib;
+       else
+         inessential_libs[(*inessential_liberties)++] = lib;
+      }
+      else if (is_false_eye(half_eye, lib) && !false_eye_territory[lib])
+       false_eye_libs[(*false_eye_liberties)++] = lib;
+    }
+  }
+  return 1;
+}
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * c-basic-offset: 2
+ * End:
+ */
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.169
diff -u -r1.169 liberty.h
--- engine/liberty.h    9 May 2003 22:44:38 -0000       1.169
+++ engine/liberty.h    11 May 2003 21:18:26 -0000
@@ -505,6 +505,8 @@
 int owl_goal_dragon(int pos);
 int owl_eyespace(int pos);
 int owl_big_eyespace(int pos);
+int owl_mineye(int pos);
+int owl_maxeye(int pos);
 int owl_proper_eye(int pos);
 int owl_eye_size(int pos);
 int owl_strong_dragon(int pos);
Index: engine/owl.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v
retrieving revision 1.161
diff -u -r1.161 owl.c
--- engine/owl.c        11 May 2003 12:44:57 -0000      1.161
+++ engine/owl.c        11 May 2003 21:18:29 -0000
@@ -5137,6 +5137,46 @@
 
 
 /* Used by autohelpers.
+ * Returns 1 if (pos) is an eyespace for the color of the dragon currently
+ * under owl investigation.
+ */
+int
+owl_mineye(int pos)
+{
+  int origin;
+  ASSERT_ON_BOARD1(pos);
+  
+  origin = current_owl_data->my_eye[pos].origin;
+  if (!ON_BOARD(origin)
+      || (current_owl_data->my_eye[origin].color
+         != BORDER_COLOR(current_owl_data->color)))
+    return 0;
+      
+  return min_eyes(&current_owl_data->my_eye[origin].value);
+}
+
+
+/* Used by autohelpers.
+ * Returns 1 if (pos) is an eyespace for the color of the dragon currently
+ * under owl investigation.
+ */
+int
+owl_maxeye(int pos)
+{
+  int origin;
+  ASSERT_ON_BOARD1(pos);
+  
+  origin = current_owl_data->my_eye[pos].origin;
+  if (!ON_BOARD(origin)
+      || (current_owl_data->my_eye[origin].color
+         != BORDER_COLOR(current_owl_data->color)))
+    return 0;
+      
+  return max_eyes(&current_owl_data->my_eye[origin].value);
+}
+
+
+/* Used by autohelpers.
  * Returns 1 if (pos) is a non-marginal eyespace for the color of the
  * dragon currently under owl investigation.
  */
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.91
diff -u -r1.91 value_moves.c
--- engine/value_moves.c        8 May 2003 18:34:11 -0000       1.91
+++ engine/value_moves.c        11 May 2003 21:18:31 -0000
@@ -65,6 +65,8 @@
   }
 
   for (k = 0; k < strings; k++) {
+    if (worm[ss[k]].invincible)
+      continue;
     if (board[ss[k]] == color) {
       int newlibs = approxlib(pos, color, MAXLIBS, NULL);
       own_strings++;
@@ -691,10 +693,14 @@
       case MY_ATARI_ATARI_MOVE:
       case YOUR_ATARI_ATARI_MOVE:
       case EITHER_MOVE:         /* FIXME: More advanced handling? */
-      case ALL_MOVE:            /* FIXME: More advanced handling? */
        tactical_safety = 1;
        safety = 1;
        break;
+      case ALL_MOVE:
+       /* We don't trust these, unless some other move reason
+        * indicates safety.
+        */
+       break;
       case EXPAND_TERRITORY_MOVE:
       case EXPAND_MOYO_MOVE:
       case INVASION_MOVE:   /* A real invasion should be safe.
@@ -873,7 +879,7 @@
 
          if (aa == bb)
            continue;
-         
+
          if (DRAGON2(aa).owl_status == ALIVE
              || DRAGON2(bb).owl_status == ALIVE) {
            tactical_safety = 1;
@@ -2042,7 +2048,7 @@
         * FIXME: When worm[aa].cutstone2 == 1 we should probably add
         *        a followup value.
         */
-       if (worm[aa].cutstone2 > 1) {
+       if (worm[aa].cutstone2 > 1 && !worm[aa].inessential) {
          double ko_factor = 1;
          if (move_reasons[r].type == ATTACK_MOVE_GOOD_KO
              || move_reasons[r].type == DEFEND_MOVE_GOOD_KO) {
Index: patterns/mkpat.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/mkpat.c,v
retrieving revision 1.119
diff -u -r1.119 mkpat.c
--- patterns/mkpat.c    8 May 2003 18:34:11 -0000       1.119
+++ patterns/mkpat.c    11 May 2003 21:18:32 -0000
@@ -330,6 +330,8 @@
   {"owl_goal_dragon",          1, 0, 0.01, "owl_goal_dragon(%s)"},
   {"owl_eyespace",             1, 0, 0.01, "owl_eyespace(%s)"},
   {"owl_big_eyespace",         1, 0, 0.01, "owl_big_eyespace(%s)"},
+  {"owl_mineye",               1, 0, 0.01, "owl_mineye(%s)"},
+  {"owl_maxeye",               1, 0, 0.01, "owl_maxeye(%s)"},
   {"owl_proper_eye",           1, 0, 0.01, "owl_proper_eye(%s)"},
   {"owl_eye_size",             1, 0, 0.01, "owl_eye_size(%s)"},
   {"owl_strong_dragon",                1, 0, 0.01, "owl_strong_dragon(%s)"},
Index: patterns/owl_attackpats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_attackpats.db,v
retrieving revision 1.81
diff -u -r1.81 owl_attackpats.db
--- patterns/owl_attackpats.db  11 May 2003 06:41:38 -0000      1.81
+++ patterns/owl_attackpats.db  11 May 2003 21:18:34 -0000
@@ -2614,6 +2614,22 @@
 ; 1 || oplay_attack(*,A)
 
 
+Pattern A719
+# gf New pattern. (3.3.20)
+
+?XXO   reduce eye space 
+X.*X
+?XX.
+
+:8,s,value(50)
+
+?XXc
+Xa*X
+?XXb
+
+;owl_mineye(*)==1 && xlib(b)==2 && !attack(c) && !oplay_attack(*,a,b,b)
+
+
 #########################################################
 #                                                       #
 #            Invade the eye space                       #
@@ -5040,6 +5056,56 @@
 +---
 
 ;lib(a)==1 && lib(B)<=3 && defend(a)!=WIN
+
+
+Pattern A1349a
+# gf New pattern. (3.3.20)
+
+|.O?    only chance to kill, sometimes tesuji
+|.XO
+|X.Y
+|..X     
+|*.X
+|.X?
++---
+
+:8,s,value(75)
+
+|.O?
+|.XO
+|X.Y
+|..X     
+|*.X
+|.A?
++---
+
+;!attack(A)
+
+
+Pattern A1349b
+# gf New pattern. (3.3.20)
+
+|oO?    only chance to kill, sometimes tesuji
+|OXO
+|.XO
+|X.Y
+|..X     
+|*.X
+|.X?
++---
+
+:8,s,value(75)
+
+|oO?
+|OXO
+|.XO
+|X.Y
+|..X     
+|*.X
+|.A?
++---
+
+;!attack(A)
 
 
 #########################################################
Index: patterns/owl_defendpats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_defendpats.db,v
retrieving revision 1.95
diff -u -r1.95 owl_defendpats.db
--- patterns/owl_defendpats.db  11 May 2003 06:41:38 -0000      1.95
+++ patterns/owl_defendpats.db  11 May 2003 21:18:35 -0000
@@ -999,11 +999,12 @@
 
 Pattern D230
 # tm New Pattern (3.1.16)
+# gf Not down to edge. (3.3.20)
 
-?OO... expand along edge.
-o....*
-?.....
-------
+?OO...?   expand along edge.
+o....*?
+?.....?
+-------
 
 :8,-,value(80)
 
@@ -1804,6 +1805,24 @@
 ;lib(A)>1 && lib(B)>1 && lib(c)==2
 
 
+Pattern D515
+# gf New pattern. (3.3.20)
+
+?OOX?        hanging connection to defend and make eye
+O..OX
+.*...
+-----
+
+:8,-,value(61)
+
+?OOX?
+O.aOX
+.*.b.
+-----
+
+;!oplay_defend(*,a,b,a)
+
+
 #########################################################
 #                                                       #
 #            Make eyeshape on the edge                  #
@@ -2516,6 +2535,23 @@
 ;!obvious_false_oeye(a) && !oplay_attack(b,*,*)
 
 
+Pattern D640
+# gf New pattern. (3.3.20)
+# Compare D720.
+
+?O*.o       try to make eye on edge
+O....
+-----
+
+:8,-,value(56)
+
+?O*bo
+Oa...
+-----
+
+;!obvious_false_oeye(a) && !oplay_attack(b,*,*)
+
+
 #########################################################
 #                                                       #
 #            Make eyeshape in the center                #
@@ -2792,6 +2828,22 @@
 ;xlib(a)>1 && owl_big_eyespace(a) && oplay_attack(*,a,a)
 
 
+Pattern D715c
+# gf New pattern. (3.3.20)
+
+.X*           defend against atari inside eyespace
+O.O
+XOo
+
+:8,-,value(60)
+
+.B*
+a.O
+XOo
+
+;lib(a)==2 && lib(B)==3 && owl_big_eyespace(*)
+
+
 Pattern D716
 # gf New pattern. (3.1.11)
 
@@ -3582,6 +3634,7 @@
 
 
 Pattern D900
+# gf Added constraint. (3.3.20)
 
 ??O?        block on edge
 XO.?
@@ -3590,6 +3643,13 @@
 
 :8,-,value(75)
 
+??O?
+Xa.?
+xX*o
+----
+
+;oplay_attack(*,a)!=WIN
+
 
 # tm removed (3.1.15)
 #    This pattern way to generic.  Too many bad matches.
@@ -3943,6 +4003,7 @@
 
 Pattern D1007
 # gf Revised constraint. (3.1.14)
+# gf Revised constraint. (3.3.20)
 
 OXO            connect underneath in sente
 .*.
@@ -3954,7 +4015,7 @@
 .*.
 ---
 
-;lib(A) == 2 && lib(b)>1 && lib(c)>1 && !attack(A)
+;lib(A) == 2 && lib(b)>1 && lib(c)>1 && !attack(A) && !oplay_disconnect(*,b,c)
 
 
 #########################################################
Index: patterns/owl_vital_apats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_vital_apats.db,v
retrieving revision 1.36
diff -u -r1.36 owl_vital_apats.db
--- patterns/owl_vital_apats.db 1 Jan 2003 20:05:25 -0000       1.36
+++ patterns/owl_vital_apats.db 11 May 2003 21:18:35 -0000
@@ -868,4 +868,33 @@
 :8,-,value(35)
 
 
+Pattern VA52a
+# gf New pattern. (3.3.20)
+
+|*Oo         make X short of liberties
+|.XO
+|X.X
+|..X
+|OXX
+|.X?
++---
+
+:8,-,value(65)
+
+
+Pattern VA52b
+# gf New pattern. (3.3.20)
+
+|*Oo
+|OXO         make X short of liberties
+|.XO
+|X.X
+|..X
+|OXX
+|.X?
++---
+
+:8,-,value(65)
+
+
 # END OF FILE
Index: patterns/patterns2.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/patterns2.db,v
retrieving revision 1.58
diff -u -r1.58 patterns2.db
--- patterns/patterns2.db       8 May 2003 18:34:11 -0000       1.58
+++ patterns/patterns2.db       11 May 2003 21:18:36 -0000
@@ -2168,24 +2168,25 @@
 :8,-,shape(-2)
 
 
-Pattern Shape52
-# Questionable --- ponnuki capture leaves less aji.
-# Whether direct or indirect capture is best depends
-#    entirely on the context.
-
-?.?    Better to capture indirectly
-*.O
-OXO
-?O?
-
-:8,-,shape(1)
-
-?.?
-*.a
-bXa
-?c?
-
-;lib(a)>1 && lib(b)>1 && lib(c)>1
+# Pattern Shape52
+# # Questionable --- ponnuki capture leaves less aji.
+# # Whether direct or indirect capture is best depends
+# #    entirely on the context.
+# # gf Removed. (3.3.20)
+# 
+# ?.?  Better to capture indirectly
+# *.O
+# OXO
+# ?O?
+# 
+# :8,-,shape(1)
+# 
+# ?.?
+# *.a
+# bXa
+# ?c?
+# 
+# ;lib(a)>1 && lib(b)>1 && lib(c)>1
 
 
 Pattern Shape53




reply via email to

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