diff -N -r -u -X .ignore gnugo-copy/engine/reading.c gnugo/engine/reading.c
--- gnugo-copy/engine/reading.c	2007-03-05 12:33:43.062500000 +0100
+++ gnugo/engine/reading.c	2007-03-06 17:11:34.531250000 +0100
@@ -131,6 +131,12 @@
  * is a defense version.
  */
 #define DEFEND_TRY_MOVES(no_deep_branching, attack_hint)		\
+  DEFEND_TRY_MOVES_LIMIT(no_deep_branching, attack_hint, WIN)
+
+/* Like DEFEND_TRY_MOVES but called when the best possible result is
+ * known - we can finish trying moves earlier.
+ */
+#define DEFEND_TRY_MOVES_LIMIT(no_deep_branching, attack_hint, limit)	\
   do {									\
     int k;								\
 									\
@@ -139,7 +145,7 @@
       int dpos = moves.pos[k];						\
 									\
       if (komaster_trymove(dpos, color, moves.message[k], str, &ko_move,\
-			   stackp <= ko_depth && savecode == 0)) {	\
+			   stackp <= ko_depth && !savecode)) {		\
 	int acode = do_attack(str, (attack_hint));			\
 	popgo();							\
 									\
@@ -153,10 +159,13 @@
 	    savecode = KO_B;						\
 	  }								\
 	}								\
-      }									\
 									\
-      if ((no_deep_branching) && stackp >= branch_depth)		\
-	RETURN_RESULT(savecode, savemove, move, "branching limit");	\
+	if (savecode == (limit))					\
+	  RETURN_RESULT(savecode, savemove, move, "best defense");	\
+									\
+	if ((no_deep_branching) && stackp >= branch_depth)		\
+	  RETURN_RESULT(savecode, savemove, move, "branching limit");	\
+      }									\
     }									\
 									\
     moves.num_tried = moves.num;					\
@@ -177,13 +186,13 @@
 									\
       if ((board_ko_pos || !send_two_return_one(apos, other))		\
 	  && komaster_trymove(apos, other,moves.message[k],str,&ko_move,\
-			      stackp <= ko_depth && savecode == 0)) {	\
+			      stackp <= ko_depth && !savecode)) {	\
 	int dcode = do_find_defense(str, (defense_hint));		\
 									\
 	if (REVERSE_RESULT(dcode) > savecode				\
 	    && do_attack(str, NULL)) {	\
 	  if (!ko_move) {						\
-	    if (dcode == 0) {						\
+	    if (!dcode) {						\
 	      popgo();							\
 	      RETURN_RESULT(WIN, apos, move, "attack effective");	\
 	    }								\
@@ -198,10 +207,10 @@
 	}								\
 									\
 	popgo();							\
-      }									\
 									\
-      if ((no_deep_branching) && stackp >= branch_depth)		\
-	RETURN_RESULT(savecode, savemove, move, "branching limit");	\
+	if ((no_deep_branching) && stackp >= branch_depth)		\
+	  RETURN_RESULT(savecode, savemove, move, "branching limit");	\
+      }									\
     }									\
 									\
     moves.num_tried = moves.num;					\
@@ -1420,6 +1429,7 @@
   int savecode = 0;
   int liberties;
   int k;
+  int suggest_move;
 
   SETUP_TRACE_INFO("defend1", str);
   reading_node_counter++;
@@ -1444,12 +1454,13 @@
   moves.message[0] = "liberty";
   moves.num = 1;
   moves.num_tried = 0;
+  suggest_move = NO_MOVE;
 
   break_chain_moves(str, &moves);
   set_up_snapback_moves(str, lib, &moves);
 
   order_moves(str, &moves, color, READ_FUNCTION_NAME, *move);
-  DEFEND_TRY_MOVES(0, NULL);
+  DEFEND_TRY_MOVES(0, &suggest_move);
 
   /* If the string is a single stone and a capture would give a ko,
    * try to defend it with ko by backfilling or killing neighbors
@@ -1483,8 +1494,6 @@
      * (see trevord:700 for example, when these moves could be
      * helpful). */
     if (!savecode && stackp <= break_chain_depth) {
-      int k;
-
       /* Find neighbors of group created by filling a ko, which
        * have up to two liberties and aren't neighbors of a ko
        * stone.
@@ -1497,20 +1506,7 @@
       popgo();
 
       order_moves(str, &moves, color, READ_FUNCTION_NAME, *move);
-
-      for (k = moves.num_tried; k < moves.num; k++) {
-	int dpos = moves.pos[k];
-	if (komaster_trymove(dpos, color, moves.message[k], str,
-			     &ko_move, stackp <= ko_depth)) {
-	  int acode = do_attack(str, NULL);
-	  popgo();
-	  CHECK_RESULT(savecode, savemove, acode, dpos, move,
-		       "defense effective");
-
-	  if (savecode)
-	    break;
-	}
-      }
+      DEFEND_TRY_MOVES_LIMIT(0, &suggest_move, KO_B);
     }
   }
   
