Index: engine/utils.c
===================================================================
--- engine/utils.c	(revision 2382)
+++ engine/utils.c	(working copy)
@@ -133,11 +133,11 @@
 
 
 /*
- * does_defend(move, str) returns true if the move at (move)
- * defends (str). This means that it defends the string, and that
- * (str) can be captured if no defense is made.
- *
- * FIXME: Make does_defend() ko aware like does_attack().
+ * does_defend(move, str) returns the result code for a defense on the
+ * string 'str' by the move 'move'. However, if the move does not
+ * improve the defense result compared to tenuki, 0 is returned. If the
+ * string (str) can't be captured if no defense is made, 0 is returned
+ * too.
  */
 
 int
@@ -147,22 +147,30 @@
   int other = OTHER_COLOR(color);
   int result = 0;
   int spos = NO_MOVE;
+  int acode;
 
-  if (!attack(str, &spos))
+  acode = attack(str, &spos);
+  if (!acode)
     return 0;
 
   gg_assert(spos != NO_MOVE);
   
   if (trymove(move, color, "does_defend-A", str)) {
-    if (!attack(str, NULL)) {
-      result = 1;
-      increase_depth_values();
+    int acode2 = attack(str, NULL);
+    if (acode2 < acode) {
+      result = REVERSE_RESULT(acode2);
       if (trymove(spos, other, "does_defend-B", str)) {
-	if (!board[str] || !find_defense(str, NULL))
+	increase_depth_values();
+	if (board[str]) {
+	  int new_result = find_defense(str, NULL);
+	  if (new_result < result)
+	    result = new_result;
+	}
+	else
 	  result = 0;
 	popgo();
+	decrease_depth_values();
       }
-      decrease_depth_values();
     }
     popgo();
   }
Index: engine/worm.c
===================================================================
--- engine/worm.c	(revision 2382)
+++ engine/worm.c	(working copy)
@@ -402,48 +402,37 @@
    * incorrectly, which may lead to some confusion later.
    */
 
-  /* First look for vertical neighbors. */
   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
-    if (IS_STONE(board[pos])
-	&& IS_STONE(board[SOUTH(pos)])
-	&& !is_same_worm(pos, SOUTH(pos))) {
-      if (worm[pos].attack_codes[0] != 0
-	  && worm[SOUTH(pos)].attack_codes[0] != 0) {
-	if (worm[pos].defense_codes[0] == 0
-	    && does_defend(worm[SOUTH(pos)].attack_points[0], pos)) {
-	  /* FIXME: need to check ko relationship here */
-	  change_defense(pos, worm[SOUTH(pos)].attack_points[0], WIN);
+    int neighbor_pos;
+    if (IS_STONE(board[pos])) {
+      int str;
+      /* First look for vertical neighbors, then horizontal. */
+      for (str = 0; str < 2; str++) {
+	if (str)
+	  neighbor_pos = EAST(pos);
+	else
+	  neighbor_pos = SOUTH(pos);
+
+	if (IS_STONE(board[neighbor_pos])
+	    && !is_same_worm(pos, neighbor_pos)) {
+	  int dcode;
+	  if (!worm[pos].defense_codes[0]
+	      && worm[neighbor_pos].attack_codes[0]) {
+	    dcode = does_defend(worm[neighbor_pos].attack_points[0], pos);
+	    if (dcode)
+	      change_defense(pos, worm[neighbor_pos].attack_points[0], dcode);
+	  }
+	  if (!worm[neighbor_pos].defense_codes[0]
+	      && worm[pos].attack_codes[0]) {
+	    dcode = does_defend(worm[pos].attack_points[0], neighbor_pos);
+	    if (dcode)
+	      change_defense(neighbor_pos, worm[pos].attack_points[0], dcode);
+	  }
 	}
-	if (worm[SOUTH(pos)].defense_codes[0] == 0
-	    && does_defend(worm[pos].attack_points[0], SOUTH(pos))) {
-	  /* FIXME: need to check ko relationship here */	    
-	  change_defense(SOUTH(pos), worm[pos].attack_points[0], WIN);
-	}
       }
     }
   }
   
-  /* Then look for horizontal neighbors. */
-  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
-    if (IS_STONE(board[pos])
-	&& IS_STONE(board[EAST(pos)])
-	&& !is_same_worm(pos, EAST(pos))) {
-      if (worm[pos].attack_codes[0] != 0
-	  && worm[EAST(pos)].attack_codes[0] != 0) {
-	if (worm[pos].defense_codes[0] == 0
-	    && does_defend(worm[EAST(pos)].attack_points[0], pos)) {
-	  /* FIXME: need to check ko relationship here */	    
-	  change_defense(pos, worm[EAST(pos)].attack_points[0], WIN);
-	}
-	if (worm[EAST(pos)].defense_codes[0] == 0
-	    && does_defend(worm[pos].attack_points[0], EAST(pos))) {
-	  /* FIXME: need to check ko relationship here */	    
-	  change_defense(EAST(pos), worm[pos].attack_points[0], WIN);
-	}
-      }
-    }
-  }
-  
   gg_assert(stackp == 0);
   
   /* Find adjacent worms that can be easily captured, aka lunches. */
Index: patterns/barriers.db
===================================================================
--- patterns/barriers.db	(revision 2382)
+++ patterns/barriers.db	(working copy)
@@ -1892,7 +1892,7 @@
 cDf
 bae
 
-;safe_omove(a)
+;safe_omove(a)>KO_B
 ;&& (o_somewhere(e) || oplay_attack(a,e,e))
 ;&& !oplay_defend_both(a,b,c,b,D)
 >return (!xplay_attack(a,f) && (o_somewhere(e) || (!xplay_attack(e,f))));
@@ -1911,7 +1911,7 @@
 eFho
 cab?
 
-;safe_omove(a)
+;safe_omove(a)>KO_B
 ;&& (o_somewhere(b) || oplay_attack(a,b,b))
 ;&& !oplay_defend_both(a,c,d,e,F,G)
 >return (!xplay_attack(a,h));
