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 Aug 2002 12:47:13 +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 some mixed tuning.

- extended_chainlinks() revised
- MAX_REASONS increased from 80 to 100
- modify_stupid_eye_vital_point() revised
- new functions improve_lunch_attack() and improve_lunch_defense()
- backfilling in do_owl_attack() when trying the defender's best move
- sniff_lunch() revised
- new experimental_connections contingent code in shapes_callback()
- induce_secondary_move_reasons() revised
- tuning
- endgame tuning
- owl tuning

The regression results are somewhat mixed too, with a net result of
plus 2. 

New passes
----------
owl: 65
ld_owl: 182
golife: 1
nicklas1: 1405
trevorc: 890, 1580
global: 34
arend: 29
strategy4: 166, 199
nngs2: 110
strategy5: 227, 235

New failures
------------
owl: 47, 66
nngs1: 30
neurogo: 13
rosebud: 1
viking: 12
nicklas1: 1801
global: 40, 41
vie: 41
nngs2: 40

/Gunnar

Index: engine/board.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/board.c,v
retrieving revision 1.47
diff -u -r1.47 board.c
--- engine/board.c      3 May 2002 17:57:58 -0000       1.47
+++ engine/board.c      10 Aug 2002 19:43:55 -0000
@@ -2486,10 +2486,13 @@
 /* extended_chainlinks() returns (in the (adj) array) the opponent
  * strings being directly adjacent to (str) or having a common liberty
  * with (str). The number of such strings is returned.
+ *
+ * If the both_colors parameter is true, also own strings sharing a
+ * liberty are returned.
  */
 
 int 
-extended_chainlinks(int str, int adj[MAXCHAIN])
+extended_chainlinks(int str, int adj[MAXCHAIN], int both_colors)
 {
   struct string_data *s;
   int n;
@@ -2521,7 +2524,8 @@
    */
   for (r = 0; r < liberties; r++) {
     for (k = 0; k < 4; k++) {
-      if (board[libs[r] + delta[k]] == OTHER_COLOR(board[str])
+      if ((board[libs[r] + delta[k]] == OTHER_COLOR(board[str])
+          || (both_colors && board[libs[r] + delta[k]] == board[str]))
          && UNMARKED_STRING(libs[r] + delta[k])) {
        adj[n] = string[string_number[libs[r] + delta[k]]].origin;
        MARK_STRING(adj[n]);
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.107
diff -u -r1.107 liberty.h
--- engine/liberty.h    6 Aug 2002 19:04:11 -0000       1.107
+++ engine/liberty.h    10 Aug 2002 19:43:59 -0000
@@ -141,7 +141,7 @@
 int chainlinks(int str, int adj[MAXCHAIN]);
 int chainlinks2(int str, int adj[MAXCHAIN], int lib);
 int chainlinks3(int str, int adj[MAXCHAIN], int lib);
-int extended_chainlinks(int str, int adj[MAXCHAIN]);
+int extended_chainlinks(int str, int adj[MAXCHAIN], int both_colors);
 
 
 /* This is increased by one anytime a move is (permanently) played or
Index: engine/move_reasons.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.h,v
retrieving revision 1.20
diff -u -r1.20 move_reasons.h
--- engine/move_reasons.h       11 Jun 2002 14:25:22 -0000      1.20
+++ engine/move_reasons.h       10 Aug 2002 19:43:59 -0000
@@ -73,7 +73,7 @@
 #define REDUNDANT               (TERRITORY_REDUNDANT | STRATEGICALLY_REDUNDANT)
 #define SECONDARY               4
 
-#define MAX_REASONS 80
+#define MAX_REASONS 100
 
 #define MAX_TRACE_LENGTH  160
 
Index: engine/owl.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v
retrieving revision 1.98
diff -u -r1.98 owl.c
--- engine/owl.c        8 Aug 2002 23:03:03 -0000       1.98
+++ engine/owl.c        10 Aug 2002 19:44:10 -0000
@@ -208,7 +208,9 @@
                              int color, int komaster, int does_attack,
                              struct owl_move_data *moves, int *probable_min,
                              int *probable_max);
-static int modify_stupid_eye_vital_point(int *vital_point);
+static int modify_stupid_eye_vital_point(struct local_owl_data *owl,
+                                        int *vital_point,
+                                        int is_attack_point);
 static void owl_mark_dragon(int apos, int bpos,
                            struct local_owl_data *owl);
 static void owl_mark_worm(int apos, int bpos,
@@ -218,6 +220,8 @@
                            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);
+static int improve_lunch_attack(int lunch, int attack_point);
+static int improve_lunch_defense(int lunch, int defense_point);
 static void owl_make_domains(struct local_owl_data *owla,
                             struct local_owl_data *owlb);
 static int owl_safe_move(int move, int color);
@@ -1374,16 +1378,34 @@
        READ_RETURN(read_result, move, 0, WIN);
       }
       else if (dpos != NO_MOVE) {
-       /* The dragon could be defended by another move. Try to attack
-         * with this move.
+       /* The dragon could be defended by one more move. Try to
+         * attack with this move.
+        *
+        * If the move is suicide for us, try to find a backfilling
+        * move to play instead.
         */
-       shape_moves[0].pos         = dpos;
-       shape_moves[0].value       = 25;
-       shape_moves[0].name        = "defense move";
-       shape_moves[0].same_dragon = 1;
-       shape_moves[0].escape = 0;
-       shape_moves[1].value       = 0;
-       moves = shape_moves;
+       shape_moves[0].name = "defense move";
+       
+       if (is_suicide(dpos, other)) {
+         int dpos2;
+         for (k = 0; k < 4; k++) {
+           if (board[dpos + delta[k]] == other
+               && find_defense(dpos + delta[k], &dpos2)) {
+             dpos = dpos2;
+             shape_moves[0].name = "defense move (backfill)";
+             break;
+           }
+         }
+       }
+
+       if (dpos != NO_MOVE) {
+         shape_moves[0].pos         = dpos;
+         shape_moves[0].value       = 25;
+         shape_moves[0].same_dragon = 1;
+         shape_moves[0].escape      = 0;
+         shape_moves[1].value       = 0;
+         moves = shape_moves;
+       }
       }
     }
       
@@ -1465,7 +1487,8 @@
                            &ko_move, savecode == 0))
        continue;
 
-      TRACE("Trying %C %1m.  Current stack: ", other, mpos);
+      TRACE("Trying %C %1m. Escape = %d. Current stack: ",
+           other, mpos, escape);
       if (verbose)
        dump_stack();
 
@@ -2047,7 +2070,8 @@
       if (moves[k].escape)
        new_escape++;
 
-      TRACE("Trying %C %1m.  Current stack: ", color, mpos);
+      TRACE("Trying %C %1m. Escape = %d. Current stack: ",
+           color, mpos, escape);
       if (verbose)
        dump_stack();
 
@@ -2483,7 +2507,7 @@
                  pos, eyevalue.maxeye, eyevalue.mineye, pessimistic_min);
            
            if (eye[attack_point].marginal
-               && modify_stupid_eye_vital_point(&attack_point))
+               && modify_stupid_eye_vital_point(owl, &attack_point, 1))
              TRACE("vital point looked stupid, moved it to %1m\n",
                    attack_point);
            
@@ -2531,8 +2555,9 @@
                  reason, defense_point, value, pos,
                  eyevalue.maxeye, eyevalue.mineye, pessimistic_min);
 
-           if (eye[defense_point].marginal
-               && modify_stupid_eye_vital_point(&defense_point))
+           if ((eye[defense_point].marginal
+                || eye[defense_point].origin != pos)
+               && modify_stupid_eye_vital_point(owl, &defense_point, 0))
              TRACE("vital point looked stupid, moved it to %1m\n",
                    defense_point);
            
@@ -2577,16 +2602,18 @@
          continue;
 
        if (does_attack) {
+         defense_point = improve_lunch_defense(owl->lunch[lunch],
+                                               
owl->lunch_defense_point[lunch]);
          TRACE("save lunch at %1m with %1m, score %d\n",
-               owl->lunch[lunch], owl->lunch_defense_point[lunch], value);
-         owl_add_move(moves, owl->lunch_defense_point[lunch], value,
-                      "save lunch", 1, 0);
+               owl->lunch[lunch], defense_point, value);
+         owl_add_move(moves, defense_point, value, "save lunch", 1, 0);
        }
        else {
+         attack_point = improve_lunch_attack(owl->lunch[lunch],
+                                             owl->lunch_attack_point[lunch]);
          TRACE("eat lunch at %1m with %1m, score %d\n",
-               owl->lunch[lunch], owl->lunch_attack_point[lunch], value);
-         owl_add_move(moves, owl->lunch_attack_point[lunch], value,
-                      "eat lunch", 1, 0);
+               owl->lunch[lunch], attack_point, value);
+         owl_add_move(moves, attack_point, value, "eat lunch", 1, 0);
        }
       }
   }
@@ -2596,7 +2623,9 @@
 }
 
 
-/* The optics code occasionally comes up with stupid vital moves, like
+/* Case 1.
+ *
+ * The optics code occasionally comes up with stupid vital moves, like
  * a in this position:
  *
  * ----+
@@ -2609,14 +2638,29 @@
  *
  * This function moves such moves to the second line.
  *
+ * Case 2.
+ *
+ * In this position the optics code can suggest the empty 1-2 point as
+ * vital move for the eyespace on the right edge. That is okay for attack
+ * but obviously not for defense.
+ *
+ * ----+
+ * XO.O|
+ * XOOX|
+ * XXO.|
+ * .XOO|
+ * .XXX|
+ *
  */
 static int
-modify_stupid_eye_vital_point(int *vital_point)
+modify_stupid_eye_vital_point(struct local_owl_data *owl, int *vital_point,
+                             int is_attack_point)
 {
   int up;
   int right;
   int k;
-  
+
+  /* Case 1. */
   for (k = 0; k < 4; k++) {
     up = delta[k];
     if (ON_BOARD(*vital_point - up))
@@ -2638,6 +2682,20 @@
       return 1;
     }
   }
+
+  /* Case 2. */
+  if (!is_attack_point) {
+    if (approxlib(*vital_point, OTHER_COLOR(owl->color), 1, NULL) == 0) {
+      for (k = 4; k < 8; k++) {
+       int pos = *vital_point + delta[k];
+       if (board[pos] == OTHER_COLOR(owl->color)
+           && countlib(pos) == 1) {
+         findlib(pos, 1, vital_point);
+         return 1;
+       }
+      }
+    }
+  }
   
   return 0;
 }
@@ -3343,6 +3401,11 @@
     int pos2 = pos + delta[k];
     if (ON_BOARD(pos2) && owl->boundary[pos2] > boundary_mark)
       boundary_mark = owl->boundary[pos2];
+    if (board[pos2] == owl->color
+       && dragon[pos2].color == owl->color
+       && dragon[pos2].status == ALIVE
+       && !owl->goal[pos2])
+      boundary_mark = 2;
   }
   owl->boundary[pos] = boundary_mark;
 
@@ -4000,6 +4063,81 @@
 }
 
 
+/* Try to improve the move to attack a lunch. Essentially we try to
+ * avoid unsafe moves when there are less risky ways to attack.
+ */
+static int
+improve_lunch_attack(int lunch, int attack_point)
+{
+  int color = OTHER_COLOR(board[lunch]);
+  int defense_point;
+  int k;
+
+  if (safe_move(attack_point, color))
+    return attack_point;
+
+  for (k = 0; k < 4; k++) {
+    int pos = attack_point + delta[k];
+    if (board[pos] == color
+       && attack(pos, NULL)
+       && find_defense(pos, &defense_point)
+       && defense_point != NO_MOVE
+       && does_attack(defense_point, lunch)) {
+      TRACE("Moved attack of lunch %1m from %1m to %1m.\n",
+           lunch, attack_point, defense_point);
+      return defense_point;
+    }
+  }
+  
+  return attack_point;
+}
+
+/* Try to improve the move to defend a lunch.
+ *
+ * An example where this is useful is the position below, where the
+ * defense of A is moved from b to c. This is a possible variation in
+ * ld_owl:182.
+ *
+ * ...X..|      ...X..|
+ * ...X..|     ...Xc.|
+ * ..XXO.|     ..XXOb|
+ * XXXOOX|     XXXOOA|
+ * XOOOX.|     XOOOX.|
+ * .XOX.X|     .XOX.X|
+ * ------+     ------+
+ */
+static int improve_lunch_defense(int lunch, int defense_point)
+{
+  int color = board[lunch];
+  int k;
+  
+  for (k = 0; k < 4; k++) {
+    int pos = defense_point + delta[k];
+    if (board[pos] == OTHER_COLOR(color)
+       && countlib(pos) == 2) {
+      int libs[2];
+      int pos2;
+      
+      findlib(pos, 2, libs);
+      if (libs[0] == defense_point)
+       pos2 = libs[1];
+      else
+       pos2 = libs[0];
+
+      if (accurate_approxlib(pos2, color, MAXLIBS, NULL)
+         > accurate_approxlib(defense_point, color, MAXLIBS, NULL)
+         && does_defend(pos2, lunch)) {
+       TRACE("Moved defense of lunch %1m from %1m to %1m.\n",
+             lunch, defense_point, pos2);
+       return pos2;
+      }
+    }
+  }
+  
+  return defense_point;
+}
+
+
 /* Wrapper for make domains. The second set of owl data is optional.
  * Use a null pointer if it is not needed. Otherwise, make_domains
  * is run separately for the two owl data, but information about
@@ -4261,22 +4399,43 @@
  */
 
 static void
-sniff_lunch(int pos, int *min, int *probable, int *max,
+sniff_lunch(int lunch, int *min, int *probable, int *max,
            struct local_owl_data *owl)
 {
-  int other = OTHER_COLOR(board[pos]);
+  int other = OTHER_COLOR(board[lunch]);
   int size;
+  int libs[MAXLIBS];
+  int liberties;
+  int r;
 
-  ASSERT1(IS_STONE(board[pos]), pos);
+  ASSERT1(IS_STONE(board[lunch]), lunch);
 
-  if (owl->boundary[pos] == 2) {
+  if (owl->boundary[lunch] == 2) {
     *min = 2;
     *probable = 2;
     *max = 2;
     return;
   }
 
-  size = countstones(pos);
+  /* Do we believe this capture would help escaping? */
+  liberties = findlib(lunch, MAXLIBS, libs);
+  for (r = 0; r < liberties; r++) {
+    if (owl->escape_values[libs[r]] > 0
+       && !is_self_atari(libs[r], other)) {
+      int k;
+      for (k = 0; k < 8; k++)
+       if (owl->goal[libs[r] + delta[k]])
+         break;
+      if (k == 8) {
+       *min = 2;
+       *probable = 2;
+       *max = 2;
+       return;
+      }
+    }
+  }
+  
+  size = countstones(lunch);
   if (size > 6) {
     *min = 2;
     *probable = 2;
@@ -4294,7 +4453,7 @@
   }
   else if (size == 2) {
     int stones[2];
-    findstones(pos, 2, stones);
+    findstones(lunch, 2, stones);
     /* A lunch on a 1-2 point tends always to be worth contesting. */
     if ((obvious_false_eye(stones[0], other)
        || obvious_false_eye(stones[1], other))
@@ -4306,11 +4465,11 @@
     else {
       *min = 0;
       *probable = 1;
-      *max = 1;
+      *max = 2;
     }
   }
   else if (size == 1) {
-    if (!obvious_false_eye(pos, other)) {
+    if (!obvious_false_eye(lunch, other)) {
       *min = 0;
       *probable = 1;
       *max = 1;
Index: engine/shapes.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/shapes.c,v
retrieving revision 1.33
diff -u -r1.33 shapes.c
--- engine/shapes.c     5 Aug 2002 23:42:15 -0000       1.33
+++ engine/shapes.c     10 Aug 2002 19:44:10 -0000
@@ -29,6 +29,7 @@
 
 /* Maximum number of dragons considered by a, B, C, and d class patterns. */
 #define MAX_DRAGONS_PER_PATTERN 5
+#define MAX_STRINGS_PER_PATTERN 5
 
 /* Values of joseki patterns. */
 #define U_VALUE 40.0
@@ -45,17 +46,27 @@
 shapes_callback(int m, int n, int color, struct pattern *pattern, int ll,
                void *data)
 {
+  int other = OTHER_COLOR(color);
+  
   int k, l;
   int move;
   
   /* Dragons of our color. */
   int my_dragons[MAX_DRAGONS_PER_PATTERN];
   int my_ndragons = 0;
-
+  
   /* Dragons of other color. */
   int your_dragons[MAX_DRAGONS_PER_PATTERN];
   int your_ndragons = 0;
 
+  /* Strings of our color. */
+  int my_strings[MAX_STRINGS_PER_PATTERN];
+  int my_nstrings = 0;
+  
+  /* Strings of other color. */
+  int your_strings[MAX_STRINGS_PER_PATTERN];
+  int your_nstrings = 0;
+
   /* Make a local copy of the classification that we may modify. */
   unsigned int class = pattern->class;
 
@@ -75,8 +86,6 @@
   if ((class & (CLASS_B | CLASS_C | CLASS_c | CLASS_a | CLASS_d | CLASS_O |
                CLASS_J | CLASS_j | CLASS_U | CLASS_T | CLASS_t)) != 0)
   {
-    int other = OTHER_COLOR(color);
-
     /* Match each point. */
     for (k = 0; k < pattern->patlen; ++k) { 
       int pos; /* absolute (board) co-ord of (transformed) pattern element */
@@ -133,16 +142,54 @@
          your_dragons[l] = origin;
          your_ndragons++;
        }
-      }      
+      }
+      
+      if (pattern->patn[k].att == ATT_O || pattern->patn[k].att == ATT_X) {
+       origin = find_origin(pos);
+       if (board[pos] == color && my_nstrings < MAX_STRINGS_PER_PATTERN) {
+         for (l = 0; l < my_nstrings; l++) {
+           if (my_strings[l] == origin)
+             break;
+         }
+         if (l == my_nstrings) {
+           /* We found another string of our color. Check that it
+            * cannot be tactically captured before adding it to the
+            * list of my_strings.
+            */
+           if (worm[pos].attack_codes[0] == 0
+               || does_defend(move, pos)) {
+             /* Ok, add the string to the list. */
+             my_strings[l] = origin;
+             my_nstrings++;
+           }
+         }
+       }
+       
+       if (board[pos] == other && your_nstrings < MAX_STRINGS_PER_PATTERN) {
+         for (l = 0; l < your_nstrings; l++) {
+           if (your_strings[l] == origin)
+             break;
+         }
+         if (l == your_nstrings) {
+           /* We found another opponent string, add it to the list. */
+           your_strings[l] = origin;
+           your_nstrings++;
+         }
+       }
+      }
     } /* loop over elements */
   } /* if we need to loop over the elements */
 
   /* Nothing to connect. Remove C class bit. */
-  if (my_ndragons < 2)
+  if (my_ndragons < 2 && !experimental_connections)
+    class &= ~CLASS_C;
+  if (my_nstrings < 2 && experimental_connections)
     class &= ~CLASS_C;
 
   /* Nothing to cut. Remove B class bit. */
-  if (your_ndragons < 2)
+  if (your_ndragons < 2 && !experimental_connections)
+    class &= ~CLASS_B;
+  if (your_nstrings < 2 && experimental_connections)
     class &= ~CLASS_B;
   
   /*
@@ -183,7 +230,7 @@
    */
   if (class & CLASS_n) {
     /* Allow ko unsafety. */
-    if (safe_move(move, OTHER_COLOR(color)) == 0) {
+    if (safe_move(move, other) == 0) {
       if (0)
        TRACE("  opponent can't play safely at %1m, move discarded\n", move);
       return;
@@ -228,7 +275,7 @@
   }
 
   /* Pattern class B, cut all combinations of opponent dragons. */
-  if (class & CLASS_B) {
+  if ((class & CLASS_B) && !experimental_connections) {
     for (k = 0; k < your_ndragons; k++)
       for (l = k+1; l < your_ndragons; l++) {
        add_cut_move(move, your_dragons[k], your_dragons[l]);
@@ -237,11 +284,39 @@
   }
 
   /* Pattern class C, connect all combinations of our dragons. */
-  if (class & CLASS_C) {
+  if ((class & CLASS_C) && !experimental_connections) {
     for (k = 0; k < my_ndragons; k++)
       for (l = k+1; l < my_ndragons; l++) {
        add_connection_move(move, my_dragons[k], my_dragons[l]);
        TRACE("...connects dragons %1m, %1m\n", my_dragons[k], my_dragons[l]);
+      }
+  }
+
+  /* Pattern class B, try to cut all combinations of opponent strings. */
+  if ((class & CLASS_B) && experimental_connections) {
+    for (k = 0; k < your_nstrings; k++)
+      for (l = k+1; l < your_nstrings; l++) {
+       if (string_connect(your_strings[k], your_strings[l], NULL)
+           && !play_connect_n(color, 1, 1, move,
+                              your_strings[k], your_strings[l])) {
+         add_cut_move(move, your_strings[k], your_strings[l]);
+         TRACE("...cuts strings %1m, %1m\n",
+               your_strings[k], your_strings[l]);
+       }
+      }
+  }
+
+  /* Pattern class C, try to connect all combinations of our strings. */
+  if ((class & CLASS_C) && experimental_connections) {
+    for (k = 0; k < my_nstrings; k++)
+      for (l = k+1; l < my_nstrings; l++) {
+       if (disconnect(my_strings[k], my_strings[l], NULL)
+           && !play_connect_n(color, 0, 1, move,
+                              my_strings[k], my_strings[l])) {
+         add_connection_move(move, my_strings[k], my_strings[l]);
+         TRACE("...connects strings %1m, %1m\n",
+               my_strings[k], my_strings[l]);
+       }
       }
   }
 
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.46
diff -u -r1.46 value_moves.c
--- engine/value_moves.c        8 Aug 2002 23:03:03 -0000       1.46
+++ engine/value_moves.c        10 Aug 2002 19:44:16 -0000
@@ -475,34 +475,60 @@
        if (!attack_move && !strategically_sound_defense(aa, pos))
          continue;
        
-       num_adj = extended_chainlinks(aa, adjs);
+       num_adj = extended_chainlinks(aa, adjs, 1);
        
        for (i = 0; i < num_adj; i++) {
          for (j = i+1; j < num_adj; j++) {
            int adj1 = adjs[i];
            int adj2 = adjs[j];
-
-           if (attack_move && !disconnect(adj1, adj2, NULL))
+           
+           if (board[adj1] != board[adj2])
+             continue;
+           if (attack_move
+               && board[adj1] != board[aa]
+               && !disconnect(adj1, adj2, NULL))
+             continue;
+           if (!attack_move
+               && board[adj1] != board[aa]
+               && !string_connect(adj1, adj2, NULL))
+             continue;
+           if (attack_move
+               && board[adj1] == board[aa])
              continue;
-           if (!attack_move && !string_connect(adj1, adj2, NULL))
+           if (!attack_move
+               && board[adj1] == board[aa]
+               && !disconnect(adj1, adj2, NULL))
              continue;
 
            if (trymove(pos, color_to_move, "induce_secondary_move_reasons",
                        aa, EMPTY, NO_MOVE)) {
-             if (attack_move && !disconnect(adj1, adj2, NULL)) {
+             if (attack_move
+                 && board[adj1] != board[aa]
+                 && !disconnect(adj1, adj2, NULL)) {
                DEBUG(DEBUG_MOVE_REASONS,
                      "Connection move at %1m induced for %1m/%1m due to attack 
of %1m\n",
                      pos, adj1, adj2, aa);
                add_connection_move(pos, adj1, adj2);
              }
                  
-             if (!attack_move && !string_connect(adj1, adj2, NULL)) {
+             if (!attack_move
+                 && board[adj1] != board[aa]
+                 && !string_connect(adj1, adj2, NULL)) {
                DEBUG(DEBUG_MOVE_REASONS,
                      "Cut move at %1m induced for %1m/%1m due to defense of 
%1m\n",
                      pos, adj1, adj2, aa);
                add_cut_move(pos, adj1, adj2);
              }
 
+             if (!attack_move
+                 && board[adj1] == board[aa]
+                 && !disconnect(adj1, adj2, NULL)) {
+               DEBUG(DEBUG_MOVE_REASONS,
+                     "Connection move at %1m induced for %1m/%1m due to 
defense of %1m\n",
+                     pos, adj1, adj2, aa);
+               add_connection_move(pos, adj1, adj2);
+             }
+                 
              popgo();
            }
          }
@@ -1501,10 +1527,12 @@
 
       /* If the dragon is a single ko stone, the owl code currently
        * won't detect that the owl attack is conditional. As a
-       * workaround we deduct 0.5 points for the move here.
+       * workaround we deduct 0.5 points for the move here, but only
+       * if the move is a liberty of the string.
        */
       if (dragon[aa].size == 1
-         && is_ko_point(aa)) {
+         && is_ko_point(aa)
+         && liberty_of_string(pos, aa)) {
        TRACE("  %1m: -0.5 - penalty for ko stone %1m (workaround)\n",
              pos, aa);
        tot_value -= 0.5;
Index: interface/play_ascii.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/play_ascii.c,v
retrieving revision 1.19
diff -u -r1.19 play_ascii.c
--- interface/play_ascii.c      6 Aug 2002 19:04:11 -0000       1.19
+++ interface/play_ascii.c      10 Aug 2002 19:44:17 -0000
@@ -460,7 +460,8 @@
   last_move_i = i;
   last_move_j = j;
   
-  mprintf("%s(%d): %m\n", color_to_string(gameinfo->to_move), movenum+1, i, j);
+  mprintf("%s(%d): %m\n", color_to_string(gameinfo->to_move),
+         movenum+1, i, j);
   if (is_pass(POS(i, j)))
     (*passes)++;
   else
@@ -910,11 +911,10 @@
          if (tmpstring) {
            /* discard newline */
            tmpstring[strlen(tmpstring)-1] = 0;
-           if (!sgftree_readfile(&sgftree, tmpstring))
-             {
-               fprintf(stderr, "Cannot open or parse '%s'\n", tmpstring);
-               break;
-             }
+           if (!sgftree_readfile(&sgftree, tmpstring)) {
+             fprintf(stderr, "Cannot open or parse '%s'\n", tmpstring);
+             break;
+           }
            sgf_initialized = 0;
            gameinfo_play_sgftree(gameinfo, sgftree.root, NULL);
            sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap);
Index: patterns/endgame.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/endgame.db,v
retrieving revision 1.35
diff -u -r1.35 endgame.db
--- patterns/endgame.db 4 Jul 2002 19:33:00 -0000       1.35
+++ patterns/endgame.db 10 Aug 2002 19:44:19 -0000
@@ -1393,6 +1393,16 @@
 ; && proper_eye(b) && oplay_attack(*,A)
 
 
+Pattern CE31
+# gf New pattern. (3.3.6)
+
+X.X
+?*?
+?O?
+
+:|,OXe
+
+
 ######################################################################
 #
 # Center followup patterns
Index: patterns/mkpat.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/mkpat.c,v
retrieving revision 1.77
diff -u -r1.77 mkpat.c
--- patterns/mkpat.c    6 Aug 2002 19:04:11 -0000       1.77
+++ patterns/mkpat.c    10 Aug 2002 19:44:22 -0000
@@ -1979,10 +1979,10 @@
   if (tree_output)
     tree_write_patterns(outfile, name);
   else
-#endif
     fprintf(outfile, "\nvoid\ninit_tree_%s(void)\n{\n"
            "  /* nothing to do - tree option not compiled */\n"
            "}\n\n", name);
+#endif
 
   /* Write out the patterns. */
   if (fullboard)
Index: patterns/owl_defendpats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_defendpats.db,v
retrieving revision 1.64
diff -u -r1.64 owl_defendpats.db
--- patterns/owl_defendpats.db  11 Jun 2002 14:12:32 -0000      1.64
+++ patterns/owl_defendpats.db  10 Aug 2002 19:44:28 -0000
@@ -599,11 +599,12 @@
 
 Pattern D207
 # tm reduced value (3.1.22) (see nngs:710)
+# gf Modified. (3.3.6)
 
-O.X          second line kosumi
-.*x
-...
----
+?O.X          second line kosumi
+o.*x
+o...
+----
 
 :8,-,value(66)
 
@@ -2219,6 +2220,7 @@
 
 Pattern D625
 # gf New pattern. (3.1.14)
+# gf Revised constraint. (3.3.6)
 
 O*o      prevent eye stealing capture
 XO.
@@ -2227,10 +2229,10 @@
 :8,n,value(45)
 
 a*o
-XO.
+XOb
 ---
 
-;lib(a)==1
+;lib(a)==1 && !obvious_false_oeye(b)
 
 
 Pattern D626
@@ -3769,6 +3771,7 @@
 
 Pattern D1006
 # gf Added n classification. (3.1.11)
+# gf Revised constraint. (3.3.6)
 
 OXO            connect underneath
 .*.
@@ -3776,11 +3779,11 @@
 
 :|,n,value(60)
 
-aXb
+aCb
 .*.
 ---
 
-;lib(a)>1 && lib(b)>1
+;lib(a)>1 && lib(b)>1 && !attack(C)
 
 
 Pattern D1006b
@@ -4215,6 +4218,7 @@
 
 
 Pattern D1122
+# gf Repaired constraint. (3.3.6)
 
 ?O?        Cut and maybe capture to make eye
 X*X
@@ -4226,7 +4230,7 @@
 A*B
 ---
 
-;oplay_attack(*,A,A) || oplay_attack(*,B,B)
+;oplay_attack(*,A) || oplay_attack(*,B)
 
 
 Pattern D1123
@@ -6538,6 +6542,18 @@
 +----
 
 ;lib(A)==1
+
+
+Pattern D1423
+# gf New pattern. (3.3.6)
+
+|OO?      throw in to make ko or better
+|.O?
+|XOO         
+|*.O
++---
+
+:8,s,value(45)
 
 
 # END OF FILE
Index: patterns/owl_vital_apats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_vital_apats.db,v
retrieving revision 1.29
diff -u -r1.29 owl_vital_apats.db
--- patterns/owl_vital_apats.db 3 Jun 2002 15:01:00 -0000       1.29
+++ patterns/owl_vital_apats.db 10 Aug 2002 19:44:29 -0000
@@ -741,11 +741,12 @@
 
 Pattern VA44
 # tm New Pattern (3.1.17)
+# gf Fixed symmetry. (3.3.6)
 
 XoX
 o*o
 
-:8,s,value(57)
+:|,s,value(57)
 
 XbX
 a*c
Index: patterns/patterns2.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/patterns2.db,v
retrieving revision 1.41
diff -u -r1.41 patterns2.db
--- patterns/patterns2.db       3 Jun 2002 15:01:00 -0000       1.41
+++ patterns/patterns2.db       10 Aug 2002 19:44:32 -0000
@@ -3386,4 +3386,27 @@
 :8,-,shape(-10)
 
 
+Pattern Temp9
+# gf New pattern. (3.3.6)
+
+|............  don't play halfways between hoshi
+|...O.....O..
+|......*.....
+|............
+|............
++------------
+
+:8,-
+
+|............
+|...O..a..O..
+|......*.....
+|............
+|............
++------------
+
+>antisuji(*);
+>antisuji(a);
+
+
 # END OF FILE




reply via email to

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