diff -N -r -u -X .ignore gnugo-copy/doc/utils.texi gnugo/doc/utils.texi
--- gnugo-copy/doc/utils.texi	2006-11-25 13:22:49.421875000 +0100
+++ gnugo/doc/utils.texi	2007-03-06 14:19:56.531250000 +0100
@@ -35,15 +35,18 @@
 @item @code{int does_attack(int move, int str)}
 @findex does_attack
 @quotation
-returns true if the move at @code{move} attacks @code{str}. This means that it captures
-the string, and that @code{str} is not already dead.  
+returns the result code for an attack on the string @code{'str'} by the move
+@code{'move'}. However, if the move does not improve the attack result compared
+to tenuki, 0 is returned. In particular if the string is already captured,
+@code{does_attack()} always returns 0.
 @end quotation
 @item @code{int does_defend(int move, int str)}
 @findex does_defend
 @quotation
-@code{does_defend(move, str)} returns true if the move at @code{move}
-defends @code{str}. This means that it defends the string, and that
-@code{str} can be captured if no defense is made.
+returns the result code for a defense on the string @code{'str'} by the move
+@code{'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.
 @end quotation
 @item @code{int somewhere(int color, int last_move, ...)}
 @findex somewhere
@@ -770,7 +773,13 @@
 @item @code{int has_neighbor(int pos, int color)}
 @findex has_neighbor
 @quotation
-Returns true if @code{pos} has a neighbor of @code{color}.
+Returns true if @code{pos} has a neighbor of color @code{color}.
+@end quotation
+@item @code{int find_neighbor(int pos, int color)}
+@findex find_neighbor
+@quotation
+If @code{pos} has exactly one neighbor of color @code{color} returns
+position of this neighbor. Otherwise returns -1.
 @end quotation
 @item @code{int same_string(int str1_pos, int str2_pos)}
 @findex same_string
diff -N -r -u -X .ignore gnugo-copy/engine/board.c gnugo/engine/board.c
--- gnugo-copy/engine/board.c	2007-03-01 15:20:18.843750000 +0100
+++ gnugo/engine/board.c	2007-03-06 13:32:11.250000000 +0100
@@ -374,6 +374,8 @@
 const int deltai[8] = { 1,  0, -1,  0,  1, -1, -1, 1};
 const int deltaj[8] = { 0, -1,  0,  1, -1, -1,  1, 1};
 const int delta[8]  = { NS, -WE, -NS, WE, NS-WE, -NS-WE, -NS+WE, NS+WE};
+const int *last_delta_4 = delta + 4;
+const int *last_delta_8 = delta + 8;
 
 
 /* ================================================================ */
@@ -1542,6 +1544,9 @@
  * 5b) Unconditional ko capture is only allowed if it is nested ko capture.
  *     Kom_pos is moved to the old value of board_ko_pos.
  * 5c) Conditional ko capture is allowed according to the rules of 1b.
+ *
+ * For description what is "conditional ko" look in the documentation:
+ * Tactical reading: Ko Handling
  */
 int
 komaster_trymove(int pos, int color, const char *message, int str,
@@ -1972,12 +1977,10 @@
    * it is not optimized much.
    */
   else {
-    const int *cur_delta, *last_delta;
+    const int *cur_delta;
     int other = OTHER_COLOR(color);
 
-    cur_delta = delta;
-    last_delta = cur_delta + 4;
-    for (; cur_delta < last_delta; cur_delta++) {
+    for (cur_delta = delta; cur_delta < last_delta_4; cur_delta++) {
       int neighbor_pos = pos + *cur_delta;
 
       if (LIBERTY(neighbor_pos)
@@ -2261,7 +2264,7 @@
 slow_approxlib(int pos, int color, int maxlib, int *libs,
                struct board_cache_entry *entry)
 {
-  const int *delta_o, *delta_i, *last_delta = delta + 4;
+  const int *delta_o, *delta_i;
   int liberties = 0;
   int checked_pos, checked_pos2;
   int pos2, str_nr, first_stone;
@@ -2270,7 +2273,7 @@
   MARK_LIBERTY(pos);
   string_mark++;
 
-  for (delta_o = delta; delta_o < last_delta; delta_o++) {
+  for (delta_o = delta; delta_o < last_delta_4; delta_o++) {
     checked_pos = pos + *delta_o;
     if (board[checked_pos] == EMPTY) {
       if (ml[checked_pos] != liberty_mark) {
@@ -2287,8 +2290,7 @@
       first_stone = FIRST_STONE(str_nr);
       pos2 = first_stone;
       do {
-	int l;
-	for (delta_i = delta; delta_i < last_delta; delta_i++) {
+	for (delta_i = delta; delta_i < last_delta_4; delta_i++) {
 	  checked_pos2 = pos2 + *delta_i;
 	  if (UNMARKED_LIBERTY(checked_pos2)) {
 	    if (libs)
@@ -2416,7 +2418,7 @@
 do_accuratelib(int pos, int color, int maxlib, int *libs,
                struct board_cache_entry *entry)
 {
-  const int *act_delta, *last_delta;
+  const int *act_delta;
   int *act_lib, *last_lib;
   int lib_count = 0;
   int captured[4];
@@ -2430,9 +2432,7 @@
   liberty_mark++;
   MARK_LIBERTY(pos);
 
-  act_delta = delta;
-  last_delta = act_delta + 4;
-  for (; act_delta < last_delta; act_delta++) {
+  for (act_delta = delta; act_delta < last_delta_4; act_delta++) {
     int checked_pos = pos + *act_delta;
     if (board[checked_pos] == EMPTY) {
       if (ml[checked_pos] != liberty_mark) {
@@ -3809,7 +3809,7 @@
 propagate_string(int stone_pos, int str_pos, int color)
 {
   int size = 1;
-  const int *act_delta, *last_delta;
+  const int *act_delta;
   
   if (stone_pos == str_pos) {
     /* Start a new string. */
@@ -3823,9 +3823,7 @@
   }
 
   /* Look in all four directions for more stones to add. */
-  act_delta = delta;
-  last_delta = act_delta + 4;
-  for (; act_delta < last_delta; act_delta++) {
+  for (act_delta = delta; act_delta < last_delta_4; act_delta++) {
     int new_pos = stone_pos + *act_delta;
     if (board[new_pos] == color
 	&& string_number[new_pos] == -1)
diff -N -r -u -X .ignore gnugo-copy/engine/board.h gnugo/engine/board.h
--- gnugo-copy/engine/board.h	2007-03-01 15:20:22.671875000 +0100
+++ gnugo/engine/board.h	2007-03-06 12:49:32.640625000 +0100
@@ -2,7 +2,7 @@
  * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see       *
  * http://www.gnu.org/software/gnugo/ for more information.          *
  *                                                                   *
- * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006       *
+ * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 *
  * by the Free Software Foundation.                                  *
  *                                                                   *
  * This program is free software; you can redistribute it and/or     *
@@ -393,6 +393,8 @@
 extern const int deltai[8]; /* = { 1,  0, -1,  0,  1, -1, -1, 1}; */
 extern const int deltaj[8]; /* = { 0, -1,  0,  1, -1, -1,  1, 1}; */
 extern const int delta[8];  /* = { NS, -WE, -NS, WE, NS-WE, -NS-WE, -NS+WE, NS+WE}; */
+extern const int *last_delta_4;
+extern const int *last_delta_8;
 
 
 
diff -N -r -u -X .ignore gnugo-copy/engine/liberty.h gnugo/engine/liberty.h
--- gnugo-copy/engine/liberty.h	2007-02-01 19:40:54.578125000 +0100
+++ gnugo/engine/liberty.h	2007-03-06 14:59:14.187500000 +0100
@@ -835,7 +835,7 @@
    * points with corresponding result codes. (0 = loss, 1 = bad ko, 2
    * = good ko, 3 = win). The arrays are guaranteed to be sorted with
    * respect to the codes so that the first element contains the best
-   * result.
+   * result. Checked and discarded moves are stored, too.
    */
   int attack_points[MAX_TACTICAL_POINTS];
   int attack_codes[MAX_TACTICAL_POINTS];
diff -N -r -u -X .ignore gnugo-copy/engine/unconditional.c gnugo/engine/unconditional.c
--- gnugo-copy/engine/unconditional.c	2007-02-22 17:34:04.031250000 +0100
+++ gnugo/engine/unconditional.c	2007-03-06 13:14:52.906250000 +0100
@@ -45,7 +45,6 @@
   int moves_played = 0;
   int save_moves;
   int libs[MAXLIBS];
-  int liberties;
   int pos;
   int *cur_lib, *last_lib;
   
@@ -347,7 +346,7 @@
     int stones[2];
     int pos2;
     int checked_stone;
-    const int *cur_delta, *last_delta;
+    const int *cur_delta;
     
     if (board[pos] != color
 	|| find_origin(pos) != pos
@@ -357,9 +356,7 @@
     findstones(pos, 2, stones);
     for (k = 0; k < 2 && isolated; k++) {
       checked_stone = stones[k];
-      cur_delta = delta;
-      last_delta = cur_delta + 8;
-      for (; cur_delta < last_delta; cur_delta++) {
+      for (cur_delta = delta; cur_delta < last_delta_8; cur_delta++) {
 	pos2 = checked_stone + *cur_delta;
 	if (!ON_BOARD(pos2)
 	    || (board[pos2] == color
diff -N -r -u -X .ignore gnugo-copy/engine/worm.c gnugo/engine/worm.c
--- gnugo-copy/engine/worm.c	2007-03-02 11:08:37.687500000 +0100
+++ gnugo/engine/worm.c	2007-03-06 14:58:57.953125000 +0100
@@ -72,10 +72,6 @@
  * the first element when they are given the lexicographical order,
  * though its location is irrelevant for applications. To see if two
  * stones lie in the same worm, compare their origins.
- *
- * We will use the field dragon[pos].genus to keep track of
- * black- or white-bordered cavities (essentially eyes) which are found.  
- * so this field must be zero'd now.
  */
 
 void
@@ -83,7 +79,9 @@
 {
   int pos;
   int str;
-  int dcode;
+  int acode, dcode;
+  int other;
+  const int *cur_delta;
 
   /* Build the basic worm data:  color, origin, size, liberties. */
   build_worms();
@@ -104,19 +102,6 @@
   
   gg_assert(stackp == 0);
 
-  /* Count liberties of different orders. */
-  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
-    int lib1;
-    if (IS_STONE(board[pos]) && is_worm_origin(pos, pos)) {
-      ping_cave(pos, &lib1, &worm[pos].liberties2, &worm[pos].liberties3,
-		&worm[pos].liberties4);
-      ASSERT1(worm[pos].liberties == lib1, pos);
-      propagate_worm(pos);
-    }
-  }
-  
-  gg_assert(stackp == 0);
-
   /*
    * There are two concepts of cutting stones in the worm array.
    *
@@ -164,42 +149,56 @@
    *
    * For the time being we use both concepts in parallel. It's
    * possible we also need the old concept for correct handling of lunches.
+   *
+   * We also set liberties and genus fields of worm_data in this loop.
    */
 
-  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
-    int w1 = NO_MOVE;
-    int w2 = NO_MOVE;
-    int k;
-    int pos2;
+  for (str = BOARDMIN; str < BOARDMAX; str++) {
+    int w1;
+    int w2;
     
     /* Only work on each worm once. This is easiest done if we only 
      * work with the origin of each worm.
      */
-    if (!IS_STONE(board[pos]) || !is_worm_origin(pos, pos))
+    if (!IS_STONE(board[str]) || !is_worm_origin(str, str))
       continue;
+
+    /* Count liberties of different orders. */
+    ping_cave(str, &worm[str].liberties, &worm[str].liberties2,
+	      &worm[str].liberties3, &worm[str].liberties4);
+    ASSERT1(worm[str].liberties == countlib(str), str);
+
+    /* Set the genus of all worms. */
+    worm[str].genus = genus(str);
+
+    w1 = 0;
+    w2 = 0;
+    other = OTHER_COLOR(board[str]);
     
     /* Try to find two adjacent worms (w1) and (w2) 
-     * of opposite colour from (pos).
+     * of opposite color from (str).
      */
-    for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++) {
-      /* Work only with the opposite color from (pos). */
-      if (board[pos2] != OTHER_COLOR(board[pos])) 
+    for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+      /* Work only with the opposite color from (str). */
+      if (board[pos] != other) 
 	continue;
       
-      for (k = 0; k < 4; k++) {
-	if (!IS_STONE(board[pos2 + delta[k]])
-	    || worm[pos2 + delta[k]].origin != pos)
+      for (cur_delta = delta; cur_delta < last_delta_4; cur_delta++) {
+	if (!IS_STONE(board[pos + *cur_delta])
+	    || worm[pos + *cur_delta].origin != str)
 	  continue;
 	
-	ASSERT1(board[pos2 + delta[k]] == board[pos], pos);
+	ASSERT1(board[pos + *cur_delta] == board[str], str);
 	
 	/* If we have not already found a worm which meets the criteria,
 	 * store it into (w1), otherwise store it into (w2).
 	 */
-	if (w1 == NO_MOVE)
-	  w1 = worm[pos2].origin;
-	else if (!is_same_worm(pos2, w1))
-	  w2 = worm[pos2].origin;
+	if (!w1)
+	  w1 = pos;
+	else if (!is_same_worm(pos, w1)) {
+	  w2 = pos;
+	  break;
+	}
       }
     }
     
@@ -211,27 +210,21 @@
      */
     
     /* Only do this if we really found something. */
-    if (w2 != NO_MOVE) {
-      worm[pos].cutstone = 2;
-      if (count_common_libs(w1, w2) > 0)
-	worm[pos].cutstone = 1;
+    if (w2) {
+      if (have_common_lib(w1, w2, NULL))
+	worm[str].cutstone = 1;
+      else
+	worm[str].cutstone = 2;
       
       DEBUG(DEBUG_WORMS, "Worm at %1m has w1 %1m and w2 %1m, cutstone %d\n",
-	    pos, w1, w2, worm[pos].cutstone);
+	    str, worm[w1].origin, worm[w2].origin, worm[str].cutstone);
     }
+
+    propagate_worm(str);
   }
   
   gg_assert(stackp == 0);
   
-  /* Set the genus of all worms. */
-  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
-    if (IS_STONE(board[pos]) && is_worm_origin(pos, pos)) {
-      worm[pos].genus = genus(pos);
-      propagate_worm(pos);
-    }
-  }
-  gg_assert(stackp == 0);
-
   /* Now we try to improve the values of worm.attack and worm.defend.
    * If we find that capturing the string at str also defends the
    * string at str2, or attacks it, then we add points of attack and
@@ -240,6 +233,8 @@
    */
   {
     int color;
+    int attack_works, defense_works;
+    int worm_acode, worm_dcode;
     int moves_to_try[BOARDMAX];
     memset(moves_to_try, 0, sizeof(moves_to_try));
 
@@ -252,8 +247,13 @@
       }
     }
 
+    increase_depth_values();
+
     /* Loop over the board and over the colors and try the moves found
-     * in the previous loop.
+     * in the previous loop. We must read to the same depth that was
+     * used in the initial determination of worm.attack and worm.defend
+     * to avoid horizon effects - that's why we must also increment
+     * depth values.
      */
     for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
       if (!ON_BOARD(pos))
@@ -267,14 +267,9 @@
 	if (!trymove(pos, color, "make_worms", NO_MOVE))
 	  continue;
 	  
-	/* We must read to the same depth that was used in the
-	 * initial determination of worm.attack and worm.defend
-	 * to avoid horizon effects. Since stackp has been
-	 * incremented we must also increment depth values.
-	 */
-	
 	DEBUG(DEBUG_WORMS, "trying %1m\n", pos);
-	increase_depth_values();
+
+	other = OTHER_COLOR(color);
 	
 	/* Now we try to find a group which is saved or attacked as well
 	 * by this move.
@@ -283,19 +278,20 @@
 	  if (!IS_STONE(board[str])
 	      || find_origin(str) != str)
 	    continue;
+
+	  worm_acode = worm[str].attack_codes[0];
 	  
 	  /* If the worm is of the opposite color to the move,
 	   * then we try to defend it. If there was a previous 
 	   * attack and defense of it, and there is no defense
 	   * for the attack now...
 	   */
-	  if (worm[str].color == OTHER_COLOR(color)
-	      && worm[str].attack_codes[0] != 0
-	      && worm[str].attack_points[0] != pos
-	      && worm[str].defense_codes[0] != 0) {
+	  if (worm[str].color == other
+	      && worm_acode && worm[str].attack_points[0] != pos
+	      && (worm_dcode = worm[str].defense_codes[0])) {
 	    dcode = find_defense(str, NULL);
-	    if (dcode < worm[str].defense_codes[0]) {
-	      int attack_works = 1;
+	    if (dcode < worm_dcode) {
+	      attack_works = 1;
 
 	      /* Sometimes find_defense() fails to find a
 	       * defense which has been found by other means.
@@ -305,15 +301,15 @@
 	       * because we could, for instance, drive the worm into
 	       * seki with our move.
 	       */
-	      if (attack(str, NULL) >= worm[str].attack_codes[0]) {
-		if (worm[str].defense_codes[0] != 0
-		    && trymove(worm[str].defense_points[0],
-			       OTHER_COLOR(color), "make_worms", 0)) {
+	      if (attack(str, NULL) >= worm_acode) {
+		if (trymove(worm[str].defense_points[0], other,
+			    "make_worms", 0)) {
 		  int this_dcode = REVERSE_RESULT(attack(str, NULL));
 		  if (this_dcode > dcode) {
-		    dcode = this_dcode;
-		    if (dcode >= worm[str].defense_codes[0])
+		    if (this_dcode >= worm_dcode)
 		      attack_works = 0;
+		    else
+		      dcode = this_dcode;
 		  }
 		  popgo();
 		}
@@ -336,28 +332,27 @@
 	   * there is none now, then add a defense point of str at
 	   * pos.
 	   */
-	  else if (worm[str].color == color
-		   && worm[str].attack_codes[0] != 0
+	  else if (worm[str].color == color && worm_acode
 		   && worm[str].defense_points[0] != pos) {
-	    int acode = attack(str, NULL);
-	    if (acode < worm[str].attack_codes[0]) {
-	      int defense_works = 1;
+	    acode = attack(str, NULL);
+	    if (acode < worm_acode) {
+	      defense_works = 1;
 	      /* Sometimes attack() fails to find an
 	       * attack which has been found by other means.
 	       * Try if the old attack move still works.
 	       */
-	      if (worm[str].attack_codes[0] != 0
-		  && trymove(worm[str].attack_points[0],
-			     OTHER_COLOR(color), "make_worms", 0)) {
-		int this_acode;
-		if (board[str] == EMPTY)
-		  this_acode = WIN;
-		else
-		  this_acode = REVERSE_RESULT(find_defense(str, NULL));
-		if (this_acode > acode) {
-		  acode = this_acode;
-		  if (acode >= worm[str].attack_codes[0])
-		    defense_works = 0;
+	      if (trymove(worm[str].attack_points[0], other,
+			  "make_worms", 0)) {
+		if (!board[str])
+		  defense_works = 0;
+		else {
+		  int this_acode = REVERSE_RESULT(find_defense(str, NULL));
+		  if (this_acode > acode) {
+		    if (this_acode >= worm_acode)
+		      defense_works = 0;
+		    else
+		      acode = this_acode;
+		  }
 		}
 		popgo();
 	      }
@@ -372,10 +367,10 @@
 	    }
 	  }
 	}
-	decrease_depth_values();
 	popgo();
       }
     }
+    decrease_depth_values();
   }
   
   gg_assert(stackp == 0);
@@ -428,26 +423,6 @@
   
   gg_assert(stackp == 0);
   
-  /* Find adjacent worms that can be easily captured, aka lunches. */
-
-  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
-    int lunch;
-    
-    if (!IS_STONE(board[pos]) || !is_worm_origin(pos, pos))
-      continue;
-    
-    if (find_lunch(pos, &lunch)
-	&& (worm[lunch].attack_codes[0] == WIN
-	    || worm[lunch].attack_codes[0] == KO_A)) {
-      DEBUG(DEBUG_WORMS, "lunch found for %1m at %1m\n", pos, lunch);
-      worm[pos].lunch = lunch;
-    }
-    else
-      worm[pos].lunch = NO_MOVE;
-    
-    propagate_worm(pos);
-  }
-  
   if (!disable_threat_computation)
     find_worm_threats();
 
@@ -457,8 +432,8 @@
    * potential unless part of their surrounding chain can be captured.
    * We give a conservative definition of inessential:
    *  - the genus must be zero 
-   *  - there can no second order liberties
-   *  - there can be no more than two edge liberties
+   *  - there can be no second order liberties
+   *  - it can't be a cutstone
    *  - if it is removed from the board, the remaining cavity has
    *    border color the opposite color of the string 
    *  - it contains at most two edge vertices.
@@ -472,24 +447,39 @@
    *
    * An inessential string can be thought of as residing inside the
    * opponent's eye space.
+   *
+   * We also find lunches here.
    */
 
   gg_assert(stackp == 0);
 
   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+    int edge;
+    int lunch;
+
     if (IS_STONE(board[pos])
-	&& worm[pos].origin == pos
-	&& worm[pos].genus == 0
-	&& worm[pos].liberties2 == 0
-	&& !worm[pos].cutstone
-	&& worm[pos].lunch == NO_MOVE) {
-      int edge;
-      int border_color = examine_cavity(pos, &edge);
-      if (border_color != GRAY && edge < 3) {
-	DEBUG(DEBUG_WORMS, "Worm %1m identified as inessential.\n", pos);
-	worm[pos].inessential = 1;
+	&& worm[pos].origin == pos) {
+
+      /* Find adjacent worms that can be easily captured, aka lunches. */
+      if (find_lunch(pos, &lunch)
+	  && ((acode = worm[lunch].attack_codes[0]) == WIN
+	      || acode == KO_A)) {
+	DEBUG(DEBUG_WORMS, "lunch found for %1m at %1m\n", pos, lunch);
+	worm[pos].lunch = lunch;
 	propagate_worm(pos);
       }
+      else {
+	/* Identify INESSENTIAL strings. */
+	if (!worm[pos].genus
+	    && !worm[pos].liberties2
+	    && !worm[pos].cutstone) {
+	  if (examine_cavity(pos, &edge) != GRAY && edge < 3) {
+	    DEBUG(DEBUG_WORMS, "Worm %1m identified as inessential.\n", pos);
+	    worm[pos].inessential = 1;
+	    propagate_worm(pos);
+	  }
+	}
+      }
     }
   }
 }
@@ -746,7 +736,7 @@
     TRACE("considering attack of %1m\n", str);
     
     acode = attack(str, &attack_point);
-    if (acode != 0) {
+    if (acode) {
       DEBUG(DEBUG_WORMS, "worm at %1m can be attacked at %1m\n",
 	    str, attack_point);
       change_attack(str, attack_point, acode);
@@ -1601,11 +1591,13 @@
   cur_el = pattern->patn;
   last_el = cur_el + pattern->patlen;
   for (; cur_el < last_el; ++cur_el) { /* match each point */
+    int pos;
+    int str;
     if (cur_el->att == ATT_X) {
       /* transform pattern real coordinate */
-      int pos = AFFINE_TRANSFORM(cur_el->offset, ll, anchor);
+      pos = AFFINE_TRANSFORM(cur_el->offset, ll, anchor);
 
-      int str = worm[pos].origin;
+      str = worm[pos].origin;
 
       /* A string with 5 liberties or more is considered tactically alive. */
       if (countlib(str) > 4)
@@ -1699,12 +1691,14 @@
   cur_el = pattern->patn;
   last_el = cur_el + pattern->patlen;
   for (; cur_el < last_el; ++cur_el) { /* match each point */
+    int pos;
+    int str;
     if (cur_el->att == ATT_O) {
       /* transform pattern real coordinate */
-      int pos = AFFINE_TRANSFORM(cur_el->offset, ll, anchor);
-      int str = worm[pos].origin;
+      pos = AFFINE_TRANSFORM(cur_el->offset, ll, anchor);
+      str = worm[pos].origin;
 
-      if (worm[str].attack_codes[0] == 0
+      if (!worm[str].attack_codes[0]
 	  || defense_move_known(move, str)
 	  || discarded_move_known(move, MAX_TACTICAL_POINTS,
 				  worm[str].discarded_defenses))
