Index: engine/reading.c
===================================================================
RCS file: /home/arend/Go/gnugo-rsync/gnugo/engine/reading.c,v
retrieving revision 1.168
diff -u -p -r1.168 reading.c
--- engine/reading.c	4 Feb 2006 18:46:04 -0000	1.168
+++ engine/reading.c	9 Feb 2006 18:15:33 -0000
@@ -299,6 +299,7 @@ static void order_moves(int str, struct 
 			int color, const char *funcname, int killer);
 static int simple_ladder_defend(int str, int *move);
 static int in_list(int move, int num_moves, int *moves);
+static int is_single(int pos, int color);
 
 
 /* Statistics. */
@@ -4467,36 +4468,52 @@ do_find_break_chain3_moves(int *chain_li
 
     /* If the 3 liberty chain easily can run away through one of the
      * liberties, we don't play on any of the other liberties.
+     * The heuristic for "easily run away" is defined as:
+     * 1. Playing on any of the 3 liberties of the chain and the resulting
+     *    number of liberty of the chain will be less than 4. Or
+     * 2. Playing on the 3 liberties in turn will resulting in:
+     *    4 or more liberties, 4 or less liberties and less than
+     *    4 liberties. In this case we only try one breaking chain move
+     *    on the position with escape potential of 4 or more liberties.
      */
     lib1 = approxlib(libs[0], other, 4, NULL);
     lib2 = approxlib(libs[1], other, 4, NULL);
-    if (lib1 >= 4 && lib2 >= 4)
-      continue;
     lib3 = approxlib(libs[2], other, 4, NULL);
 
-    if ((lib1 >= 4 || lib2 >= 4) && lib3 >= 4)
-      continue;
-
     if (lib1 >= 4) {
-      if (!move_added[libs[0]]) {
+      /* For the safety of the breaking chain move,
+       * the move must be either a single stone, or a resulting
+       * string of 4 or more liberties
+       */
+      if (((lib2 <= 4 && lib3 < 4)
+	    || (lib3 <= 4 && lib2 < 4))
+	  && ((is_single(libs[0], color)
+	      || approxlib(libs[0], color, 4, NULL) > 3))
+	  && !move_added[libs[0]]) {
 	possible_moves[num_possible_moves++] = libs[0];
 	move_added[libs[0]] = 1;
       }
-
       continue;
     }
 
     if (lib2 >= 4) {
-      if (!move_added[libs[1]]) {
+      if (((lib1 <= 4 && lib3 < 4)
+	    || (lib3 <= 4 && lib1 < 4))
+	  && (is_single(libs[1], color)
+	      || approxlib(libs[1], color, 4, NULL) > 3)
+	  && !move_added[libs[1]]) {
 	possible_moves[num_possible_moves++] = libs[1];
 	move_added[libs[1]] = 1;
       }
-
       continue;
     }
 
     if (lib3 >= 4) {
-      if (!move_added[libs[2]]) {
+      if (((lib2 <= 4 && lib1 < 4)
+	    || (lib1 <= 4 && lib2 < 4))
+	  && (is_single(libs[2], color)
+	      || approxlib(libs[2], color, 4, NULL) > 3)
+	  && !move_added[libs[2]]) {
 	possible_moves[num_possible_moves++] = libs[2];
 	move_added[libs[2]] = 1;
       }
@@ -4504,6 +4521,9 @@ do_find_break_chain3_moves(int *chain_li
       continue;
     }
 
+    if (lib1 >= 4 || lib2 >= 4 || lib3 >= 4)
+      continue;
+
     /* No easy escape, try all liberties. */
     for (k = 0; k < 3; k++) {
       if (!move_added[libs[k]]) {
@@ -4557,6 +4577,14 @@ break_chain3_moves(int str, struct readi
   }
 }
 
+static int
+is_single(int pos, int color)
+{
+  if ((board[SOUTH(pos)] != color) && (board[EAST(pos)] != color) &&
+      (board[WEST(pos)] != color) && (board[NORTH(pos)] != color))
+    return(1);
+  return(0);
+}
 
 /*
  * (str) points to a group.
