diff -N -r -u -X .ignore gnugo-copy/engine/board.c gnugo/engine/board.c
--- gnugo-copy/engine/board.c	2007-02-01 18:23:58.593750000 +0100
+++ gnugo/engine/board.c	2007-02-22 17:35:27.031250000 +0100
@@ -1972,11 +1972,13 @@
    * it is not optimized much.
    */
   else {
-    int k;
+    const int *cur_delta, *last_delta;
     int other = OTHER_COLOR(color);
 
-    for (k = 0; k < 4; k++) {
-      int neighbor_pos = pos + delta[k];
+    cur_delta = delta;
+    last_delta = cur_delta + 4;
+    for (; cur_delta < last_delta; cur_delta++) {
+      int neighbor_pos = pos + *cur_delta;
 
       if (LIBERTY(neighbor_pos)
 	  && (ally1 < 0 || !NEIGHBOR_OF_STRING(neighbor_pos, ally1, color))
@@ -2106,9 +2108,9 @@
 do_approxlib(int pos, int color, int maxlib, int *libs,
              struct board_cache_entry *entry)
 {
-  int k;
+  int *cur_lib, *last_lib;
   int liberties = 0;
-  int checked_pos, str_nr, str_libs, checked_lib;
+  int checked_pos, str_nr;
 
   /* Look for empty neighbors and the liberties of the adjacent
    * strings of the given color. The algorithm below won't work
@@ -2138,16 +2140,16 @@
   }
   else if (board[checked_pos] == color) {
     str_nr = string_number[checked_pos];
-    str_libs = string[str_nr].liberties;
-    for (k = 0; k < str_libs; k++) {
-      checked_lib = string_libs[str_nr].list[k];
-      if (UNMARKED_LIBERTY(checked_lib)) {
+    cur_lib = string_libs[str_nr].list;
+    last_lib = cur_lib + string[str_nr].liberties;
+    for (; cur_lib < last_lib; cur_lib++) {
+      if (UNMARKED_LIBERTY(*cur_lib)) {
 	if (libs != NULL)
-	  libs[liberties] = checked_lib;
+	  libs[liberties] = *cur_lib;
 	liberties++;
 	if (liberties >= maxlib)
 	  return liberties;
-	MARK_LIBERTY(checked_lib);
+	MARK_LIBERTY(*cur_lib);
       }
     }
   }
@@ -2166,16 +2168,16 @@
   }
   else if (board[checked_pos] == color) {
     str_nr = string_number[checked_pos];
-    str_libs = string[str_nr].liberties;
-    for (k = 0; k < str_libs; k++) {
-      checked_lib = string_libs[str_nr].list[k];
-      if (UNMARKED_LIBERTY(checked_lib)) {
+    cur_lib = string_libs[str_nr].list;
+    last_lib = cur_lib + string[str_nr].liberties;
+    for (; cur_lib < last_lib; cur_lib++) {
+      if (UNMARKED_LIBERTY(*cur_lib)) {
 	if (libs != NULL)
-	  libs[liberties] = checked_lib;
+	  libs[liberties] = *cur_lib;
 	liberties++;
 	if (liberties >= maxlib)
 	  return liberties;
-	MARK_LIBERTY(checked_lib);
+	MARK_LIBERTY(*cur_lib);
       }
     }
   }
@@ -2194,16 +2196,16 @@
   }
   else if (board[checked_pos] == color) {
     str_nr = string_number[checked_pos];
-    str_libs = string[str_nr].liberties;
-    for (k = 0; k < str_libs; k++) {
-      checked_lib = string_libs[str_nr].list[k];
-      if (UNMARKED_LIBERTY(checked_lib)) {
+    cur_lib = string_libs[str_nr].list;
+    last_lib = cur_lib + string[str_nr].liberties;
+    for (; cur_lib < last_lib; cur_lib++) {
+      if (UNMARKED_LIBERTY(*cur_lib)) {
 	if (libs != NULL)
-	  libs[liberties] = checked_lib;
+	  libs[liberties] = *cur_lib;
 	liberties++;
 	if (liberties >= maxlib)
 	  return liberties;
-	MARK_LIBERTY(checked_lib);
+	MARK_LIBERTY(*cur_lib);
       }
     }
   }
@@ -2224,16 +2226,16 @@
   }
   else if (board[checked_pos] == color) {
     str_nr = string_number[checked_pos];
-    str_libs = string[str_nr].liberties;
-    for (k = 0; k < str_libs; k++) {
-      checked_lib = string_libs[str_nr].list[k];
-      if (UNMARKED_LIBERTY(checked_lib)) {
+    cur_lib = string_libs[str_nr].list;
+    last_lib = cur_lib + string[str_nr].liberties;
+    for (; cur_lib < last_lib; cur_lib++) {
+      if (UNMARKED_LIBERTY(*cur_lib)) {
 	if (libs != NULL)
-	  libs[liberties] = checked_lib;
+	  libs[liberties] = *cur_lib;
 	liberties++;
 	if (liberties >= maxlib)
 	  return liberties;
-	MARK_LIBERTY(checked_lib);
+	MARK_LIBERTY(*cur_lib);
       }
     }
   }
@@ -2259,7 +2261,7 @@
 slow_approxlib(int pos, int color, int maxlib, int *libs,
                struct board_cache_entry *entry)
 {
-  int k;
+  const int *delta_o, *delta_i, *last_delta = delta + 4;
   int liberties = 0;
   int checked_pos, checked_pos2;
   int pos2, str_nr, first_stone;
@@ -2268,8 +2270,8 @@
   MARK_LIBERTY(pos);
   string_mark++;
 
-  for (k = 0; k < 4; k++) {
-    checked_pos = pos + delta[k];
+  for (delta_o = delta; delta_o < last_delta; delta_o++) {
+    checked_pos = pos + *delta_o;
     if (board[checked_pos] == EMPTY) {
       if (ml[checked_pos] != liberty_mark) {
         if (libs)
@@ -2286,8 +2288,8 @@
       pos2 = first_stone;
       do {
 	int l;
-	for (l = 0; l < 4; l++) {
-	  checked_pos2 = pos2 + delta[l];
+	for (delta_i = delta; delta_i < last_delta; delta_i++) {
+	  checked_pos2 = pos2 + *delta_i;
 	  if (UNMARKED_LIBERTY(checked_pos2)) {
 	    if (libs)
 	      libs[liberties] = checked_pos2;
@@ -2414,11 +2416,12 @@
 do_accuratelib(int pos, int color, int maxlib, int *libs,
                struct board_cache_entry *entry)
 {
-  int k, l;
+  const int *act_delta, *last_delta;
+  int *act_lib, *last_lib;
   int lib_count = 0;
-  int lib;
   int captured[4];
   int captures = 0;
+  int *act_capture, *check_capture, *last_capture;
   int first_stone;
   int stone_pos;
   int checked_lib;
@@ -2427,8 +2430,10 @@
   liberty_mark++;
   MARK_LIBERTY(pos);
 
-  for (k = 0; k < 4; k++) {
-    int checked_pos = pos + delta[k];
+  act_delta = delta;
+  last_delta = act_delta + 4;
+  for (; act_delta < last_delta; act_delta++) {
+    int checked_pos = pos + *act_delta;
     if (board[checked_pos] == EMPTY) {
       if (ml[checked_pos] != liberty_mark) {
         /* A trivial liberty */
@@ -2451,17 +2456,17 @@
 	  /* The easy case - we already have all (necessary) liberties of
 	   * the string listed
 	   */
-	  struct string_liberties_data *sl = string_libs + neighbor_nr;
-	  for (l = 0; l < liberties; l++) {
-	    lib = sl->list[l];
-	    if (UNMARKED_LIBERTY(lib)) {
+	  act_lib = (string_libs + neighbor_nr)->list;
+	  last_lib = act_lib + liberties;
+	  for (; act_lib < last_lib; act_lib++) {
+	    if (UNMARKED_LIBERTY(*act_lib)) {
 	      if (libs)
-	        libs[lib_count] = lib;
+	        libs[lib_count] = *act_lib;
 	      lib_count++;
 	      if (lib_count >= maxlib)
 	        return lib_count;
 
-	      MARK_LIBERTY(lib);
+	      MARK_LIBERTY(*act_lib);
 	    }
 	  }
         }
@@ -2531,9 +2536,11 @@
   }
 
   /* Now we look at all the captures found in the previous step */
-  for (k = 0; k < captures; k++) {
+  act_capture = captured;
+  last_capture = captured + captures;
+  for (; act_capture < last_capture; act_capture++) {
     int capture_nr;
-    first_stone = captured[k];
+    first_stone = *act_capture;
 
     /* Add the stone adjacent to (pos) to the list of liberties if
      * it is not also adjacent to an own marked string (otherwise,
@@ -2557,11 +2564,12 @@
 
     /* Check if we already know of this capture. */
     capture_nr = string_number[stone_pos];
-    for (l = 0; l < k; l++)
-      if (string_number[captured[l]] == capture_nr)
+    check_capture = captured;
+    for (; check_capture < act_capture; check_capture++)
+      if (string_number[*check_capture] == capture_nr)
 	break;
 
-    if (l == k) {
+    if (check_capture == act_capture) {
       /* Traverse all the stones of the capture and add to the list
        * of liberties those, which are adjacent to at least one own
        * marked string.
@@ -2602,10 +2610,10 @@
 count_common_libs(int str1_pos, int str2_pos)
 {
   int all_libs1[MAXLIBS], *libs1;
+  int *last_lib;
   int liberties1, liberties2;
   int str1_nr, str2_nr;
   int commonlibs = 0;
-  int k;
   int color;
 
   ASSERT_ON_BOARD1(str1_pos);
@@ -2636,12 +2644,14 @@
       /* Speed optimization: NEIGHBOR_OF_STRING is quite expensive */
       liberty_mark++;
       
-      for (k = 0; k < liberties1; k++)
-	MARK_LIBERTY(libs1[k]);
+      last_lib = libs1 + liberties1;
+      for (; libs1 < last_lib; libs1++)
+	MARK_LIBERTY(*libs1);
 
       libs1 = string_libs[str2_nr].list;
-      for (k = 0; k < liberties2; k++)
-	if (ml[libs1[k]] == liberty_mark)
+      last_lib = libs1 + liberties2;
+      for (; libs1 < last_lib; libs1++)
+	if (ml[*libs1] == liberty_mark)
 	  commonlibs++;
 
       return commonlibs;
@@ -2653,8 +2663,9 @@
   }
   
   color = string[str2_nr].color;
-  for (k = 0; k < liberties1; k++)
-    if (NEIGHBOR_OF_STRING(libs1[k], str2_nr, color))
+  last_lib = libs1 + liberties1;
+  for (; libs1 < last_lib; libs1++)
+    if (NEIGHBOR_OF_STRING(*libs1, str2_nr, color))
       commonlibs++;
   
   return commonlibs;
@@ -2673,10 +2684,10 @@
 find_common_libs(int str1_pos, int str2_pos, int maxlib, int *libs)
 {
   int all_libs1[MAXLIBS], *libs1;
+  int *last_lib;
   int liberties1, liberties2;
   int str1_nr, str2_nr;
   int commonlibs = 0;
-  int k;
   int color;
 
   ASSERT_ON_BOARD1(str1_pos);
@@ -2708,14 +2719,16 @@
       /* Speed optimization: NEIGHBOR_OF_STRING is quite expensive */
       liberty_mark++;
 
-      for (k = 0; k < liberties1; k++)
-	MARK_LIBERTY(libs1[k]);
-      
+      last_lib = libs1 + liberties1;
+      for (; libs1 < last_lib; libs1++)
+	MARK_LIBERTY(*libs1);
+
       libs1 = string_libs[str2_nr].list;
-      for (k = 0; k < liberties2; k++)
-	if (ml[libs1[k]] == liberty_mark) {
-          if (commonlibs < maxlib)
-	    libs[commonlibs] = libs1[k];
+      last_lib = libs1 + liberties2;
+      for (; libs1 < last_lib; libs1++)
+	if (ml[*libs1] == liberty_mark) {
+	  if (commonlibs < maxlib)
+	    libs[commonlibs] = *libs1;
 	  commonlibs++;
 	}
       
@@ -2728,10 +2741,11 @@
   }
   
   color = string[str2_nr].color;
-  for (k = 0; k < liberties1; k++)
-    if (NEIGHBOR_OF_STRING(libs1[k], str2_nr, color)) {
+  last_lib = libs1 + liberties1;
+  for (; libs1 < last_lib; libs1++)
+    if (NEIGHBOR_OF_STRING(*libs1, str2_nr, color)) {
       if (commonlibs < maxlib)
-	libs[commonlibs] = libs1[k];
+	libs[commonlibs] = *libs1;
       commonlibs++;
     }
   
@@ -2746,9 +2760,9 @@
 have_common_lib(int str1_pos, int str2_pos, int *lib)
 {
   int all_libs1[MAXLIBS], *libs1;
+  int *last_lib;
   int liberties1, liberties2;
   int str1_nr, str2_nr;
-  int k;
   int color;
 
   ASSERT_ON_BOARD1(str1_pos);
@@ -2780,13 +2794,13 @@
   }
 
   color = string[str2_nr].color;
-  for (k = 0; k < liberties1; k++) {
-    if (NEIGHBOR_OF_STRING(libs1[k], str2_nr, color)) {
+  last_lib = libs1 + liberties1;
+  for (; libs1 < last_lib; libs1++)
+    if (NEIGHBOR_OF_STRING(*libs1, str2_nr, color)) {
       if (lib)
-	*lib = libs1[k];
+	*lib = *libs1;
       return 1;
     }
-  }
   
   return 0;
 }
@@ -2818,8 +2832,7 @@
   int str_nr;
   int size;
   int pos;
-  int k;
-  int limit;
+  int *limit;
 
   ASSERT_ON_BOARD1(str_pos);
   ASSERT1(IS_STONE(board[str_pos]), str_pos);
@@ -2829,9 +2842,9 @@
   
   /* Traverse the stones of the string, by following the cyclic chain. */
   pos = FIRST_STONE(str_nr);
-  limit = maxstones > size ? size : maxstones;
-  for (k = 0; k < limit; k++) {
-    stones[k] = pos;
+  limit = stones + (maxstones > size ? size : maxstones);
+  for (; stones < limit; stones++) {
+    *stones = pos;
     pos = NEXT_STONE(pos);
   }
 
@@ -2886,8 +2899,7 @@
 int 
 chainlinks(int str_pos, int adj[MAXCHAIN])
 {
-  struct string_neighbors_data *sn;
-  int k;
+  int *cur_neighbor, *last_neigbor;
   int neighbors;
 
   ASSERT1(IS_STONE(board[str_pos]), str_pos);
@@ -2896,9 +2908,10 @@
    * desired information.
    */
   neighbors = string[string_number[str_pos]].neighbors;
-  sn = string_neighbors + string_number[str_pos];
-  for (k = 0; k < neighbors; k++)
-    adj[k] = string[sn->list[k]].origin;
+  cur_neighbor = (string_neighbors + string_number[str_pos])->list;
+  last_neigbor = cur_neighbor + neighbors;
+  for (; cur_neighbor < last_neigbor; adj++, cur_neighbor++)
+    *adj = string[*cur_neighbor].origin;
 
   return neighbors;
 }
@@ -2912,9 +2925,8 @@
 int
 chainlinks2(int str_pos, int adj[MAXCHAIN], int lib)
 {
-  struct string_neighbors_data *sn;
-  int k;
-  int neighbors, max_neighbors;
+  int *cur_neighbor, *last_neigbor;
+  int neighbors;
 
   ASSERT1(IS_STONE(board[str_pos]), str_pos);
 
@@ -2922,11 +2934,11 @@
    * right number of liberties.
    */
   neighbors = 0;
-  max_neighbors = string[string_number[str_pos]].neighbors;
-  sn = string_neighbors + string_number[str_pos];
-  for (k = 0; k < max_neighbors; k++) {
-    if (string[sn->list[k]].liberties == lib)
-      adj[neighbors++] = string[sn->list[k]].origin;
+  cur_neighbor = (string_neighbors + string_number[str_pos])->list;
+  last_neigbor = cur_neighbor + string[string_number[str_pos]].neighbors;
+  for (; cur_neighbor < last_neigbor; cur_neighbor++) {
+    if (string[*cur_neighbor].liberties == lib)
+      adj[neighbors++] = string[*cur_neighbor].origin;
   }
   return neighbors;
 }
@@ -2940,9 +2952,8 @@
 int
 chainlinks3(int str_pos, int adj[MAXCHAIN], int lib)
 {
-  struct string_neighbors_data *sn;
-  int k;
-  int neighbors, max_neighbors;
+  int *cur_neighbor, *last_neigbor;
+  int neighbors;
 
   ASSERT1(IS_STONE(board[str_pos]), str_pos);
 
@@ -2950,11 +2961,11 @@
    * right number of liberties.
    */
   neighbors = 0;
-  max_neighbors = string[string_number[str_pos]].neighbors;
-  sn = string_neighbors + string_number[str_pos];
-  for (k = 0; k < max_neighbors; k++) {
-    if (string[sn->list[k]].liberties <= lib)
-      adj[neighbors++] = string[sn->list[k]].origin;
+  cur_neighbor = (string_neighbors + string_number[str_pos])->list;
+  last_neigbor = cur_neighbor + string[string_number[str_pos]].neighbors;
+  for (; cur_neighbor < last_neigbor; cur_neighbor++) {
+    if (string[*cur_neighbor].liberties <= lib)
+      adj[neighbors++] = string[*cur_neighbor].origin;
   }
   return neighbors;
 }
@@ -2972,24 +2983,22 @@
 int 
 extended_chainlinks(int str_pos, int adj[MAXCHAIN], int both_colors)
 {
-  struct string_neighbors_data *sn;
-  int n;
-  int r;
+  int *cur_neighbor, *last_neigbor;
   int libs[MAXLIBS];
-  int liberties;
+  int *cur_lib, *last_lib;
   int checked_pos;
   int color;
   int other;
-  int neighbors;
   int str_nr;
+  int *cur_adj;
 
   ASSERT1(IS_STONE(board[str_pos]), str_pos);
 
   str_nr = string_number[str_pos];
   color = string[str_nr].color;
   other = OTHER_COLOR(color);
-  sn = string_neighbors + str_nr;
   string_mark++;
+  cur_adj = adj;
 
   /* We already have the list of directly adjacent strings ready, just
    * copy it and mark the strings. We also mark ourselves in case
@@ -2997,61 +3006,63 @@
    */
   MARK_STRING(str_nr);
 
-  neighbors = string[str_nr].neighbors;
-  for (n = 0; n < neighbors; n++) {
-    adj[n] = string[sn->list[n]].origin;
-    MARK_STRING(sn->list[n]);
+  cur_neighbor = (string_neighbors + str_nr)->list;
+  last_neigbor = cur_neighbor + string[str_nr].neighbors;
+  for (; cur_neighbor < last_neigbor; cur_neighbor++) {
+    *cur_adj++ = string[*cur_neighbor].origin;
+    MARK_STRING(*cur_neighbor);
   }
 
   /* Get the liberties. */
-  liberties = findlib(str_pos, MAXLIBS, libs);
+  cur_lib = libs;
+  last_lib = cur_lib + findlib(str_pos, MAXLIBS, libs);
 
   /* Look for unmarked strings next to a liberty and add the
    * ones which are found to the output.
    */
-  for (r = 0; r < liberties; r++) {
-    checked_pos = SOUTH(libs[r]);
+  for (; cur_lib < last_lib; cur_lib++) {
+    checked_pos = SOUTH(*cur_lib);
     if (board[checked_pos] == other
         || (both_colors && board[checked_pos] == color)) {
       str_nr = string_number[checked_pos];
       if (UNMARKED_STRING(str_nr)) {
         MARK_STRING(str_nr);
-        adj[n++] = string[str_nr].origin;
+        *cur_adj++ = string[str_nr].origin;
       }
     }
 
-    checked_pos = WEST(libs[r]);
+    checked_pos = WEST(*cur_lib);
     if (board[checked_pos] == other
         || (both_colors && board[checked_pos] == color)) {
       str_nr = string_number[checked_pos];
       if (UNMARKED_STRING(str_nr)) {
         MARK_STRING(str_nr);
-        adj[n++] = string[str_nr].origin;
+        *cur_adj++ = string[str_nr].origin;
       }
     }
 
-    checked_pos = NORTH(libs[r]);
+    checked_pos = NORTH(*cur_lib);
     if (board[checked_pos] == other
         || (both_colors && board[checked_pos] == color)) {
       str_nr = string_number[checked_pos];
       if (UNMARKED_STRING(str_nr)) {
         MARK_STRING(str_nr);
-        adj[n++] = string[str_nr].origin;
+        *cur_adj++ = string[str_nr].origin;
       }
     }
 
-    checked_pos = EAST(libs[r]);
+    checked_pos = EAST(*cur_lib);
     if (board[checked_pos] == other
         || (both_colors && board[checked_pos] == color)) {
       str_nr = string_number[checked_pos];
       if (UNMARKED_STRING(str_nr)) {
         MARK_STRING(str_nr);
-        adj[n++] = string[str_nr].origin;
+        *cur_adj++ = string[str_nr].origin;
       }
     }
   }
   
-  return n;
+  return cur_adj - adj;
 }
 
 
@@ -3321,7 +3332,7 @@
 int
 adjacent_strings(int str1_pos, int str2_pos)
 {
-  int k;
+  int *last_neighbor;
   int neighbors1, neighbors2;
   int str1_nr, str2_nr;
   int *neighbors_list;
@@ -3344,8 +3355,9 @@
   else
     neighbors_list = string_neighbors[str1_nr].list;
   
-  for (k = 0; k < neighbors1; k++)
-    if (neighbors_list[k] == str2_nr)
+  last_neighbor = neighbors_list + neighbors1;
+  for (; neighbors_list < last_neighbor; neighbors_list++)
+    if (*neighbors_list == str2_nr)
       return 1;
 
   return 0;
@@ -3553,9 +3565,11 @@
 int
 move_in_stack(int pos, int cutoff)
 {
-  int k;
-  for (k = cutoff; k < stackp; k++)
-    if (stack[k] == pos)
+  int *act, *last;
+  act = stack + cutoff;
+  last = stack + stackp;
+  for (; act < last; act++)
+    if (*act == pos)
       return 1;
   
   return 0;
@@ -3757,7 +3771,7 @@
 propagate_string(int stone_pos, int str_pos, int color)
 {
   int size = 1;
-  int k;
+  const int *act_delta, *last_delta;
   
   if (stone_pos == str_pos) {
     /* Start a new string. */
@@ -3771,8 +3785,10 @@
   }
 
   /* Look in all four directions for more stones to add. */
-  for (k = 0; k < 4; k++) {
-    int new_pos = stone_pos + delta[k];
+  act_delta = delta;
+  last_delta = act_delta + 4;
+  for (; act_delta < last_delta; act_delta++) {
+    int new_pos = stone_pos + *act_delta;
     if (board[new_pos] == color
 	&& string_number[new_pos] == -1)
       size += propagate_string(new_pos, str_pos, color);
@@ -3874,14 +3890,17 @@
 update_liberties(int str_nr)
 {
   int pos;
-  int k;
+  int liberties;
   int first_stone;
+  int *cur_lib, *limit;
 
   /* Push the old information. */
   PUSH_VALUE(string[str_nr].liberties);
-  for (k = 0; k < string[str_nr].liberties && k < MAX_LIBERTIES; k++) {
-    PUSH_VALUE(string_libs[str_nr].list[k]);
-  }
+  liberties = string[str_nr].liberties;
+  cur_lib = string_libs[str_nr].list;
+  limit = cur_lib + (liberties < MAX_LIBERTIES ? liberties : MAX_LIBERTIES);
+  for (; cur_lib < limit; cur_lib++)
+    PUSH_VALUE(*cur_lib);
   string[str_nr].liberties = 0;
 
   /* Clear the liberty mark. */
@@ -3936,8 +3955,8 @@
       PUSH_VALUE(sn->list[s->neighbors - 1]);
       PUSH_VALUE(sn->list[k]);
       PUSH_VALUE(s->neighbors);
-      sn->list[k] = sn->list[s->neighbors - 1];
       s->neighbors--;
+      sn->list[k] = sn->list[s->neighbors];
 #ifndef GG_TURN_OFF_ASSERTS
       done = 1;
 #endif
@@ -3972,8 +3991,8 @@
 	PUSH_VALUE(sl->list[s->liberties - 1]);
 	PUSH_VALUE(sl->list[k]);
 	PUSH_VALUE(s->liberties);
-	sl->list[k] = sl->list[s->liberties - 1];
 	s->liberties--;
+	sl->list[k] = sl->list[s->liberties];
 	break;
       }
   }
@@ -3988,11 +4007,10 @@
 do_remove_string(int str_nr)
 {
   int pos;
-  int k;
-  int *str_neighbors_list = string_neighbors[str_nr].list;
   struct string_data *str_data = string + str_nr;
   int size = str_data->size;
-  int neighbors = str_data->neighbors;
+  int *str_neighbors_list = string_neighbors[str_nr].list;
+  int *last_neighbor = str_neighbors_list + str_data->neighbors;
   int first_stone;
 
   /* Traverse the stones of the string, by following the cyclic chain. */
@@ -4012,8 +4030,8 @@
    * update_liberties().
    */
   if (size == 1) {
-    for (k = 0; k < neighbors; k++) {
-      int neighbor_nr = str_neighbors_list[k];
+    for (; str_neighbors_list < last_neighbor; str_neighbors_list++) {
+      int neighbor_nr = *str_neighbors_list;
       int *neighbor_libs = &(string[neighbor_nr].liberties);
 
       remove_neighbor(neighbor_nr, str_nr);
@@ -4028,8 +4046,8 @@
     int other = OTHER_COLOR(str_data->color);
     int pos2 = NEXT_STONE(pos);
 
-    for (k = 0; k < neighbors; k++) {
-      int neighbor_nr = str_neighbors_list[k];  
+    for (; str_neighbors_list < last_neighbor; str_neighbors_list++) {
+      int neighbor_nr = *str_neighbors_list;
       int *neighbor_libs = &(string[neighbor_nr].liberties);
 
       remove_neighbor(neighbor_nr, str_nr);
@@ -4049,9 +4067,9 @@
     }
   }
   else {
-    for (k = 0; k < neighbors; k++) {
-      remove_neighbor(str_neighbors_list[k], str_nr);
-      update_liberties(str_neighbors_list[k]);
+    for (; str_neighbors_list < last_neighbor; str_neighbors_list++) {
+      remove_neighbor(*str_neighbors_list, str_nr);
+      update_liberties(*str_neighbors_list);
     }
   }
 
@@ -4174,11 +4192,10 @@
 static void
 extend_neighbor_string(int pos, int str_nr, int color)
 {
-  int k;
   int liberties_updated = 0;
   int other = OTHER_COLOR(color);
   int checked_pos;
-  int *neighbors_list = string_neighbors[str_nr].list;
+  int *neighbors_list, *last_neighbor;
 
   /* Link in the stone in the cyclic list. */
   int origin = string[str_nr].origin;
@@ -4214,8 +4231,10 @@
 
   /* Mark old neighbors of the string. */
   string_mark++;
-  for (k = 0; k < string[str_nr].neighbors; k++)
-    string[neighbors_list[k]].mark = string_mark;
+  neighbors_list = string_neighbors[str_nr].list;
+  last_neighbor = neighbors_list + string[str_nr].neighbors;
+  for (; neighbors_list < last_neighbor; neighbors_list++)
+    string[*neighbors_list].mark = string_mark;
 
   /* Look at the neighbor locations of pos for new liberties and/or
    * neighbor strings.
@@ -4302,10 +4321,10 @@
 static void
 assimilate_string(int str_nr, int ass_pos)
 {
-  int k;
   int last;
   int ass_nr = string_number[ass_pos];
   int first_stone;
+  int *cur_neighbor, *last_neigbor;
   string[str_nr].size += string[ass_nr].size;
 
   /* Walk through the assimilated string stones and change
@@ -4339,10 +4358,11 @@
    * been marked before this function is called.
    */
   if (string[ass_nr].liberties <= MAX_LIBERTIES) {
-    for (k = 0; k < string[ass_nr].liberties; k++) {
-      int lib_pos = string_libs[ass_nr].list[k];
-      if (UNMARKED_LIBERTY(lib_pos)) {
-	ADD_AND_MARK_LIBERTY(str_nr, lib_pos);
+    int *cur_lib = string_libs[ass_nr].list;
+    int *last_lib = cur_lib + string[ass_nr].liberties;
+    for (; cur_lib < last_lib; cur_lib++) {
+      if (UNMARKED_LIBERTY(*cur_lib)) {
+	ADD_AND_MARK_LIBERTY(str_nr, *cur_lib);
       }
     }
   }
@@ -4367,8 +4387,10 @@
    * known neighbors of str_nr are assumed to have been marked before this
    * function is called.
    */
-  for (k = 0; k < string[ass_nr].neighbors; k++) {
-    int neighbor_nr = string_neighbors[ass_nr].list[k];
+  cur_neighbor = string_neighbors[ass_nr].list;
+  last_neigbor = cur_neighbor + string[ass_nr].neighbors;
+  for (; cur_neighbor < last_neigbor; cur_neighbor++) {
+    int neighbor_nr = *cur_neighbor;
     remove_neighbor(neighbor_nr, ass_nr);
     if (string[neighbor_nr].mark != string_mark) {
       PUSH_VALUE(string[neighbor_nr].neighbors);
@@ -4764,13 +4786,12 @@
     else { \
       (*number_opponent)++; \
       if (string[str_nr].liberties == 1) { \
-	int r; \
 	int *neighbors_list = string_neighbors[str_nr].list; \
-	int neighbors = string[str_nr].neighbors; \
+	int *last_neighbor = neighbors_list + string[str_nr].neighbors; \
 	(*captured_stones) += string[str_nr].size; \
-	for (r = 0; r < neighbors; r++) { \
-	  if (string[neighbors_list[r]].liberties == 1) \
-	    (*saved_stones) += string[neighbors_list[r]].size; \
+	for (; neighbors_list < last_neighbor; neighbors_list++) { \
+	  if (string[*neighbors_list].liberties == 1) \
+	    (*saved_stones) += string[*neighbors_list].size; \
 	} \
       } \
       else if (string[str_nr].liberties == 2 && UNMARKED_STRING(str_nr)) { \
diff -N -r -u -X .ignore gnugo-copy/engine/matchpat.c gnugo/engine/matchpat.c
--- gnugo-copy/engine/matchpat.c	2007-02-10 21:54:42.362125000 +0100
+++ gnugo/engine/matchpat.c	2007-02-22 17:34:04.093750000 +0100
@@ -741,7 +741,7 @@
 		    struct pattern *pattern, int ll, void *callback_data,
 		    signed char goal[BOARDMAX])
 {
-  int k;			/* Iterate over elements of pattern */
+  struct patval *cur_pat, *last_pat; /* Iterate over elements of pattern */
   int found_goal = (goal == NULL);
   
 #if PROFILE_PATTERNS
@@ -754,13 +754,15 @@
 #endif
 
   /* Iterate over the elements of the pattern. */
-  for (k = 0; k < pattern->patlen; k++) {
+  cur_pat = pattern->patn;
+  last_pat = cur_pat + pattern->patlen;
+  for (; cur_pat < last_pat; cur_pat++) {
   				/* match each point */
     int pos;			/* absolute (board) co-ords of 
   				   (transformed) pattern element */
 
     /* transform pattern real coordinate... */
-    pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor);
+    pos = AFFINE_TRANSFORM(cur_pat->offset, ll, anchor);
     ASSERT_ON_BOARD1(pos);
 
     /* goal check */
diff -N -r -u -X .ignore gnugo-copy/engine/movelist.c gnugo/engine/movelist.c
--- gnugo-copy/engine/movelist.c	2007-02-01 19:40:14.078125000 +0100
+++ gnugo/engine/movelist.c	2007-02-22 15:15:08.437500000 +0100
@@ -55,12 +55,12 @@
 int
 discarded_move_known(int move, int max_points, int points[])
 {
-  int k;
+  int *last_point = points + max_points;
 
-  for (k = 0; k < max_points; k++) {
-    if (points[k] == 0)
+  for (; points < last_point; points++) {
+    if (*points == 0)
       return 0;
-    if (points[k] == move)
+    if (*points == move)
       return 1;
   }
   return 0;
@@ -122,15 +122,15 @@
 void
 movelist_change_discarded(int move, int max_points, int points[])
 {
-  int k;
+  int *last_point = points + max_points;
 
   /* We store only max_points discarded moves. */
-  for (k = 0; k < max_points; k++) {
-    if (points[k] == move)
+  for (; points < last_point; points++) {
+    if (*points == move)
       return;
 
-    if (points[k] == 0) {
-      points[k] = move;
+    if (*points == 0) {
+      *points = move;
       return;
     }
   }
diff -N -r -u -X .ignore gnugo-copy/engine/unconditional.c gnugo/engine/unconditional.c
--- gnugo-copy/engine/unconditional.c	2007-01-25 13:24:25.046875000 +0100
+++ gnugo/engine/unconditional.c	2007-02-22 17:34:04.031250000 +0100
@@ -47,7 +47,7 @@
   int libs[MAXLIBS];
   int liberties;
   int pos;
-  int k;
+  int *cur_lib, *last_lib;
   
   while (something_captured) {
     /* Nothing captured so far in this turn of the loop. */
@@ -63,10 +63,11 @@
 	continue;
 
       /* Try to capture the string at pos. */
-      liberties = findlib(pos, MAXLIBS, libs);
+      cur_lib = libs;
+      last_lib = cur_lib + findlib(pos, MAXLIBS, libs);
       save_moves = moves_played;
-      for (k = 0; k < liberties; k++)
-	moves_played += trymove(libs[k], other, "unconditional_life", pos);
+      for (; cur_lib < last_lib; cur_lib++)
+	moves_played += trymove(*cur_lib, other, "unconditional_life", pos);
       
       /* Successful if already captured or a single liberty remains.
        * Otherwise we must rewind and take back the last batch of moves.
@@ -326,8 +327,9 @@
   int other = OTHER_COLOR(color);
   int libs[MAXLIBS];
   int liberties;
+  int *cur_lib, *last_lib;
   int pos;
-  int k, r;
+  int k;
   int moves_played;
   int potential_sekis[BOARDMAX];
   int none_invincible;
@@ -345,6 +347,7 @@
     int stones[2];
     int pos2;
     int checked_stone;
+    const int *cur_delta, *last_delta;
     
     if (board[pos] != color
 	|| find_origin(pos) != pos
@@ -354,8 +357,10 @@
     findstones(pos, 2, stones);
     for (k = 0; k < 2 && isolated; k++) {
       checked_stone = stones[k];
-      for (r = 0; r < 8; r++) {
-	pos2 = checked_stone + delta[r];
+      cur_delta = delta;
+      last_delta = cur_delta + 8;
+      for (; cur_delta < last_delta; cur_delta++) {
+	pos2 = checked_stone + *cur_delta;
 	if (!ON_BOARD(pos2)
 	    || (board[pos2] == color
 		&& !same_string(pos, pos2)))
@@ -399,9 +404,10 @@
       continue;
       
     /* Play as many liberties as we can. */
-    liberties = findlib(pos, MAXLIBS, libs);
-    for (k = 0; k < liberties; k++) {
-      moves_played += trymove(libs[k], other, "unconditional_life", pos);
+    cur_lib = libs;
+    last_lib = cur_lib + findlib(pos, MAXLIBS, libs);
+    for (; cur_lib < last_lib; cur_lib++) {
+      moves_played += trymove(*cur_lib, other, "unconditional_life", pos);
     }
   }
 
@@ -424,6 +430,7 @@
 
   /* Now see whether there are any significant sekis on the board. */
   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+    int r;
     if (!potential_sekis[pos]
 	|| board[pos] == EMPTY
 	|| find_origin(pos) != pos)
@@ -478,9 +485,10 @@
     if (!potential_sekis[pos] || board[pos] == EMPTY)
       continue;
     /* Play as many liberties as we can. */
-    liberties = findlib(pos, MAXLIBS, libs);
-    for (k = 0; k < liberties; k++)
-      moves_played += trymove(libs[k], other, "unconditional_life", pos);
+    cur_lib = libs;
+    last_lib = cur_lib + findlib(pos, MAXLIBS, libs);
+    for (; cur_lib < last_lib; cur_lib++)
+      moves_played += trymove(*cur_lib, other, "unconditional_life", pos);
   }
     
   /* All opponent strings liberties are now inside opponent territory
diff -N -r -u -X .ignore gnugo-copy/engine/worm.c gnugo/engine/worm.c
--- gnugo-copy/engine/worm.c	2007-02-01 19:01:08.187500000 +0100
+++ gnugo/engine/worm.c	2007-02-24 15:00:29.656250000 +0100
@@ -102,18 +102,13 @@
   
   gg_assert(stackp == 0);
 
-  /* Count liberties of different orders and initialize cutstone fields. */
+  /* Count liberties of different orders. */
   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+    int lib1;
     if (IS_STONE(board[pos]) && is_worm_origin(pos, pos)) {
-      int lib1, lib2, lib3, lib4;
-      
-      ping_cave(pos, &lib1, &lib2, &lib3, &lib4);
+      ping_cave(pos, &lib1, &worm[pos].liberties2, &worm[pos].liberties3,
+		&worm[pos].liberties4);
       ASSERT1(worm[pos].liberties == lib1, pos);
-      worm[pos].liberties2 = lib2;
-      worm[pos].liberties3 = lib3;
-      worm[pos].liberties4 = lib4;
-      worm[pos].cutstone = 0;
-      worm[pos].cutstone2 = 0;
       propagate_worm(pos);
     }
   }
@@ -745,14 +740,13 @@
 find_worm_attacks_and_defenses()
 {
   int str;
-  int k;
   int acode, dcode;
   int attack_point;
   int defense_point;
   static int libs[MAXLIBS];
-  int liberties;
   int color;
   int other;
+  int pos;
 
    /* 1. Start with finding attack points. */
   for (str = BOARDMIN; str < BOARDMAX; str++) {
@@ -779,11 +773,11 @@
     if (!IS_STONE(board[str]) || !is_worm_origin(str, str))
       continue;
 
-    if (worm[str].attack_codes[0] != 0) {
+    if (worm[str].attack_codes[0]) {
 
       TRACE("considering defense of %1m\n", str);
       dcode = find_defense(str, &defense_point);
-      if (dcode != 0) {
+      if (dcode) {
 	TRACE("worm at %1m can be defended at %1m\n", str, defense_point);
 	if (defense_point != NO_MOVE)
 	  change_defense(str, defense_point, dcode);
@@ -815,28 +809,28 @@
   
   /*
    * 5. Find additional attacks and defenses by testing all immediate
-   *    liberties. Further attacks and defenses are found by pattern
-   *    matching and by trying whether each attack or defense point
-   *    attacks or defends other strings.
+   *    liberties. 
    */
   for (str = BOARDMIN; str < BOARDMAX; str++) {
-    color = board[str];
-    if (!IS_STONE(color) || !is_worm_origin(str, str))
+    int *cur_lib, *last_lib;
+    if (!IS_STONE(board[str]) || !is_worm_origin(str, str)
+	|| !worm[str].attack_codes[0])
       continue;
-    
+
+    color = board[str];
     other = OTHER_COLOR(color);
     
-    if (worm[str].attack_codes[0] == 0)
-      continue;
-    
     /* There is at least one attack on this group. Try the
      * liberties.
      */
-    liberties = findlib(str, MAXLIBS, libs);
+    cur_lib = libs;
+    last_lib = cur_lib + findlib(str, MAXLIBS, libs);
     
-    for (k = 0; k < liberties; k++) {
-      int pos = libs[k];
-      if (!attack_move_known(pos, str)) {
+    for (; cur_lib < last_lib; cur_lib++) {
+      pos = *cur_lib;
+      if (!attack_move_known(pos, str)
+	  && !discarded_move_known(pos, MAX_TACTICAL_POINTS,
+				   worm[str].discarded_attacks)) {
 	/* Try to attack on the liberty. Don't consider
 	 * send-two-return-one moves.
 	 */
@@ -855,14 +849,17 @@
 	}
       }
       /* Try to defend at the liberty. */
-      if (!defense_move_known(pos, str)) {
-	if (worm[str].defense_codes[0] != 0)
-	  if (trymove(pos, color, "make_worms", NO_MOVE)) {
+      if (worm[str].defense_codes[0] && !defense_move_known(pos, str)
+	  && !discarded_move_known(pos, MAX_TACTICAL_POINTS,
+				   worm[str].discarded_defenses)) {
+	if (trymove(pos, color, "make_worms", NO_MOVE)) {
+	  if (countlib(pos) > 1) {
 	    acode = attack(str, NULL);
 	    if (acode != WIN)
 	      change_defense(str, pos, REVERSE_RESULT(acode));
-	    popgo();
 	  }
+	  popgo();
+	}
       }
     }
   }
@@ -1215,16 +1212,16 @@
 void 
 propagate_worm(int pos)
 {
-  int k;
-  int num_stones;
+  int *cur_stone, *last_stone;
   int stones[MAX_BOARD * MAX_BOARD];
   gg_assert(stackp == 0);
   ASSERT1(IS_STONE(board[pos]), pos);
 
-  num_stones = findstones(pos, MAX_BOARD * MAX_BOARD, stones);
-  for (k = 0; k < num_stones; k++)
-    if (stones[k] != pos)
-      memcpy(worm + stones[k], worm + pos, sizeof(struct worm_data));
+  cur_stone = stones;
+  last_stone = cur_stone + findstones(pos, MAX_BOARD * MAX_BOARD, stones);
+  for (; cur_stone < last_stone; cur_stone++)
+    if (*cur_stone != pos)
+      memcpy(worm + (*cur_stone), worm + pos, sizeof(struct worm_data));
 }
 
 
@@ -1576,7 +1573,7 @@
 		void *data)
 {
   int move;
-  int k;
+  struct patval *cur_el, *last_el;
   UNUSED(data);
 
   gg_assert(stackp==0);
@@ -1604,10 +1601,12 @@
   }
 
   /* Loop through pattern elements in search of X strings to attack. */
-  for (k = 0; k < pattern->patlen; ++k) { /* match each point */
-    if (pattern->patn[k].att == ATT_X) {
+  cur_el = pattern->patn;
+  last_el = cur_el + pattern->patlen;
+  for (; cur_el < last_el; ++cur_el) { /* match each point */
+    if (cur_el->att == ATT_X) {
       /* transform pattern real coordinate */
-      int pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor);
+      int pos = AFFINE_TRANSFORM(cur_el->offset, ll, anchor);
 
       int str = worm[pos].origin;
 
@@ -1672,7 +1671,7 @@
 		 void *data)
 {
   int move;
-  int k;
+  struct patval *cur_el, *last_el;
   UNUSED(data);
 
   gg_assert(stackp==0);
@@ -1700,10 +1699,12 @@
   }
 
   /* Loop through pattern elements in search for O strings to defend. */
-  for (k = 0; k < pattern->patlen; ++k) { /* match each point */
-    if (pattern->patn[k].att == ATT_O) {
+  cur_el = pattern->patn;
+  last_el = cur_el + pattern->patlen;
+  for (; cur_el < last_el; ++cur_el) { /* match each point */
+    if (cur_el->att == ATT_O) {
       /* transform pattern real coordinate */
-      int pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor);
+      int pos = AFFINE_TRANSFORM(cur_el->offset, ll, anchor);
       int str = worm[pos].origin;
 
       if (worm[str].attack_codes[0] == 0
