Ticket #148: loops.patch

File loops.patch, 34.8 kB (added by draqo, 19 months ago)

Loops optimization - and small cleanup in worm.c

  • engine/board.c

    diff -N -r -u -X .ignore gnugo-copy/engine/board.c gnugo/engine/board.c
    old new  
    19721972   * it is not optimized much. 
    19731973   */ 
    19741974  else { 
    1975     int k; 
     1975    const int *cur_delta, *last_delta; 
    19761976    int other = OTHER_COLOR(color); 
    19771977 
    1978     for (k = 0; k < 4; k++) { 
    1979       int neighbor_pos = pos + delta[k]; 
     1978    cur_delta = delta; 
     1979    last_delta = cur_delta + 4; 
     1980    for (; cur_delta < last_delta; cur_delta++) { 
     1981      int neighbor_pos = pos + *cur_delta; 
    19801982 
    19811983      if (LIBERTY(neighbor_pos) 
    19821984          && (ally1 < 0 || !NEIGHBOR_OF_STRING(neighbor_pos, ally1, color)) 
     
    21062108do_approxlib(int pos, int color, int maxlib, int *libs, 
    21072109             struct board_cache_entry *entry) 
    21082110{ 
    2109   int k; 
     2111  int *cur_lib, *last_lib; 
    21102112  int liberties = 0; 
    2111   int checked_pos, str_nr, str_libs, checked_lib; 
     2113  int checked_pos, str_nr; 
    21122114 
    21132115  /* Look for empty neighbors and the liberties of the adjacent 
    21142116   * strings of the given color. The algorithm below won't work 
     
    21382140  } 
    21392141  else if (board[checked_pos] == color) { 
    21402142    str_nr = string_number[checked_pos]; 
    2141     str_libs = string[str_nr].liberties; 
    2142     for (k = 0; k < str_libs; k++) { 
    2143       checked_lib = string_libs[str_nr].list[k]; 
    2144       if (UNMARKED_LIBERTY(checked_lib)) { 
     2143    cur_lib = string_libs[str_nr].list; 
     2144    last_lib = cur_lib + string[str_nr].liberties; 
     2145    for (; cur_lib < last_lib; cur_lib++) { 
     2146      if (UNMARKED_LIBERTY(*cur_lib)) { 
    21452147        if (libs != NULL) 
    2146           libs[liberties] = checked_lib; 
     2148          libs[liberties] = *cur_lib; 
    21472149        liberties++; 
    21482150        if (liberties >= maxlib) 
    21492151          return liberties; 
    2150         MARK_LIBERTY(checked_lib); 
     2152        MARK_LIBERTY(*cur_lib); 
    21512153      } 
    21522154    } 
    21532155  } 
     
    21662168  } 
    21672169  else if (board[checked_pos] == color) { 
    21682170    str_nr = string_number[checked_pos]; 
    2169     str_libs = string[str_nr].liberties; 
    2170     for (k = 0; k < str_libs; k++) { 
    2171       checked_lib = string_libs[str_nr].list[k]; 
    2172       if (UNMARKED_LIBERTY(checked_lib)) { 
     2171    cur_lib = string_libs[str_nr].list; 
     2172    last_lib = cur_lib + string[str_nr].liberties; 
     2173    for (; cur_lib < last_lib; cur_lib++) { 
     2174      if (UNMARKED_LIBERTY(*cur_lib)) { 
    21732175        if (libs != NULL) 
    2174           libs[liberties] = checked_lib; 
     2176          libs[liberties] = *cur_lib; 
    21752177        liberties++; 
    21762178        if (liberties >= maxlib) 
    21772179          return liberties; 
    2178         MARK_LIBERTY(checked_lib); 
     2180        MARK_LIBERTY(*cur_lib); 
    21792181      } 
    21802182    } 
    21812183  } 
     
    21942196  } 
    21952197  else if (board[checked_pos] == color) { 
    21962198    str_nr = string_number[checked_pos]; 
    2197     str_libs = string[str_nr].liberties; 
    2198     for (k = 0; k < str_libs; k++) { 
    2199       checked_lib = string_libs[str_nr].list[k]; 
    2200       if (UNMARKED_LIBERTY(checked_lib)) { 
     2199    cur_lib = string_libs[str_nr].list; 
     2200    last_lib = cur_lib + string[str_nr].liberties; 
     2201    for (; cur_lib < last_lib; cur_lib++) { 
     2202      if (UNMARKED_LIBERTY(*cur_lib)) { 
    22012203        if (libs != NULL) 
    2202           libs[liberties] = checked_lib; 
     2204          libs[liberties] = *cur_lib; 
    22032205        liberties++; 
    22042206        if (liberties >= maxlib) 
    22052207          return liberties; 
    2206         MARK_LIBERTY(checked_lib); 
     2208        MARK_LIBERTY(*cur_lib); 
    22072209      } 
    22082210    } 
    22092211  } 
     
    22242226  } 
    22252227  else if (board[checked_pos] == color) { 
    22262228    str_nr = string_number[checked_pos]; 
    2227     str_libs = string[str_nr].liberties; 
    2228     for (k = 0; k < str_libs; k++) { 
    2229       checked_lib = string_libs[str_nr].list[k]; 
    2230       if (UNMARKED_LIBERTY(checked_lib)) { 
     2229    cur_lib = string_libs[str_nr].list; 
     2230    last_lib = cur_lib + string[str_nr].liberties; 
     2231    for (; cur_lib < last_lib; cur_lib++) { 
     2232      if (UNMARKED_LIBERTY(*cur_lib)) { 
    22312233        if (libs != NULL) 
    2232           libs[liberties] = checked_lib; 
     2234          libs[liberties] = *cur_lib; 
    22332235        liberties++; 
    22342236        if (liberties >= maxlib) 
    22352237          return liberties; 
    2236         MARK_LIBERTY(checked_lib); 
     2238        MARK_LIBERTY(*cur_lib); 
    22372239      } 
    22382240    } 
    22392241  } 
     
    22592261slow_approxlib(int pos, int color, int maxlib, int *libs, 
    22602262               struct board_cache_entry *entry) 
    22612263{ 
    2262   int k; 
     2264  const int *delta_o, *delta_i, *last_delta = delta + 4; 
    22632265  int liberties = 0; 
    22642266  int checked_pos, checked_pos2; 
    22652267  int pos2, str_nr, first_stone; 
     
    22682270  MARK_LIBERTY(pos); 
    22692271  string_mark++; 
    22702272 
    2271   for (k = 0; k < 4; k++) { 
    2272     checked_pos = pos + delta[k]; 
     2273  for (delta_o = delta; delta_o < last_delta; delta_o++) { 
     2274    checked_pos = pos + *delta_o; 
    22732275    if (board[checked_pos] == EMPTY) { 
    22742276      if (ml[checked_pos] != liberty_mark) { 
    22752277        if (libs) 
     
    22862288      pos2 = first_stone; 
    22872289      do { 
    22882290        int l; 
    2289         for (l = 0; l < 4; l++) { 
    2290           checked_pos2 = pos2 + delta[l]; 
     2291        for (delta_i = delta; delta_i < last_delta; delta_i++) { 
     2292          checked_pos2 = pos2 + *delta_i; 
    22912293          if (UNMARKED_LIBERTY(checked_pos2)) { 
    22922294            if (libs) 
    22932295              libs[liberties] = checked_pos2; 
     
    24142416do_accuratelib(int pos, int color, int maxlib, int *libs, 
    24152417               struct board_cache_entry *entry) 
    24162418{ 
    2417   int k, l; 
     2419  const int *act_delta, *last_delta; 
     2420  int *act_lib, *last_lib; 
    24182421  int lib_count = 0; 
    2419   int lib; 
    24202422  int captured[4]; 
    24212423  int captures = 0; 
     2424  int *act_capture, *check_capture, *last_capture; 
    24222425  int first_stone; 
    24232426  int stone_pos; 
    24242427  int checked_lib; 
     
    24272430  liberty_mark++; 
    24282431  MARK_LIBERTY(pos); 
    24292432 
    2430   for (k = 0; k < 4; k++) { 
    2431     int checked_pos = pos + delta[k]; 
     2433  act_delta = delta; 
     2434  last_delta = act_delta + 4; 
     2435  for (; act_delta < last_delta; act_delta++) { 
     2436    int checked_pos = pos + *act_delta; 
    24322437    if (board[checked_pos] == EMPTY) { 
    24332438      if (ml[checked_pos] != liberty_mark) { 
    24342439        /* A trivial liberty */ 
     
    24512456          /* The easy case - we already have all (necessary) liberties of 
    24522457           * the string listed 
    24532458           */ 
    2454           struct string_liberties_data *sl = string_libs + neighbor_nr; 
    2455           for (l = 0; l < liberties; l++) { 
    2456             lib = sl->list[l]; 
    2457             if (UNMARKED_LIBERTY(lib)) { 
     2459          act_lib = (string_libs + neighbor_nr)->list; 
     2460          last_lib = act_lib + liberties; 
     2461          for (; act_lib < last_lib; act_lib++) { 
     2462            if (UNMARKED_LIBERTY(*act_lib)) { 
    24582463              if (libs) 
    2459                 libs[lib_count] = lib; 
     2464                libs[lib_count] = *act_lib; 
    24602465              lib_count++; 
    24612466              if (lib_count >= maxlib) 
    24622467                return lib_count; 
    24632468 
    2464               MARK_LIBERTY(lib); 
     2469              MARK_LIBERTY(*act_lib); 
    24652470            } 
    24662471          } 
    24672472        } 
     
    25312536  } 
    25322537 
    25332538  /* Now we look at all the captures found in the previous step */ 
    2534   for (k = 0; k < captures; k++) { 
     2539  act_capture = captured; 
     2540  last_capture = captured + captures; 
     2541  for (; act_capture < last_capture; act_capture++) { 
    25352542    int capture_nr; 
    2536     first_stone = captured[k]; 
     2543    first_stone = *act_capture; 
    25372544 
    25382545    /* Add the stone adjacent to (pos) to the list of liberties if 
    25392546     * it is not also adjacent to an own marked string (otherwise, 
     
    25572564 
    25582565    /* Check if we already know of this capture. */ 
    25592566    capture_nr = string_number[stone_pos]; 
    2560     for (l = 0; l < k; l++) 
    2561       if (string_number[captured[l]] == capture_nr) 
     2567    check_capture = captured; 
     2568    for (; check_capture < act_capture; check_capture++) 
     2569      if (string_number[*check_capture] == capture_nr) 
    25622570        break; 
    25632571 
    2564     if (l == k) { 
     2572    if (check_capture == act_capture) { 
    25652573      /* Traverse all the stones of the capture and add to the list 
    25662574       * of liberties those, which are adjacent to at least one own 
    25672575       * marked string. 
     
    26022610count_common_libs(int str1_pos, int str2_pos) 
    26032611{ 
    26042612  int all_libs1[MAXLIBS], *libs1; 
     2613  int *last_lib; 
    26052614  int liberties1, liberties2; 
    26062615  int str1_nr, str2_nr; 
    26072616  int commonlibs = 0; 
    2608   int k; 
    26092617  int color; 
    26102618 
    26112619  ASSERT_ON_BOARD1(str1_pos); 
     
    26362644      /* Speed optimization: NEIGHBOR_OF_STRING is quite expensive */ 
    26372645      liberty_mark++; 
    26382646       
    2639       for (k = 0; k < liberties1; k++) 
    2640         MARK_LIBERTY(libs1[k]); 
     2647      last_lib = libs1 + liberties1; 
     2648      for (; libs1 < last_lib; libs1++) 
     2649        MARK_LIBERTY(*libs1); 
    26412650 
    26422651      libs1 = string_libs[str2_nr].list; 
    2643       for (k = 0; k < liberties2; k++) 
    2644         if (ml[libs1[k]] == liberty_mark) 
     2652      last_lib = libs1 + liberties2; 
     2653      for (; libs1 < last_lib; libs1++) 
     2654        if (ml[*libs1] == liberty_mark) 
    26452655          commonlibs++; 
    26462656 
    26472657      return commonlibs; 
     
    26532663  } 
    26542664   
    26552665  color = string[str2_nr].color; 
    2656   for (k = 0; k < liberties1; k++) 
    2657     if (NEIGHBOR_OF_STRING(libs1[k], str2_nr, color)) 
     2666  last_lib = libs1 + liberties1; 
     2667  for (; libs1 < last_lib; libs1++) 
     2668    if (NEIGHBOR_OF_STRING(*libs1, str2_nr, color)) 
    26582669      commonlibs++; 
    26592670   
    26602671  return commonlibs; 
     
    26732684find_common_libs(int str1_pos, int str2_pos, int maxlib, int *libs) 
    26742685{ 
    26752686  int all_libs1[MAXLIBS], *libs1; 
     2687  int *last_lib; 
    26762688  int liberties1, liberties2; 
    26772689  int str1_nr, str2_nr; 
    26782690  int commonlibs = 0; 
    2679   int k; 
    26802691  int color; 
    26812692 
    26822693  ASSERT_ON_BOARD1(str1_pos); 
     
    27082719      /* Speed optimization: NEIGHBOR_OF_STRING is quite expensive */ 
    27092720      liberty_mark++; 
    27102721 
    2711       for (k = 0; k < liberties1; k++) 
    2712         MARK_LIBERTY(libs1[k]); 
    2713        
     2722      last_lib = libs1 + liberties1; 
     2723      for (; libs1 < last_lib; libs1++) 
     2724        MARK_LIBERTY(*libs1); 
     2725 
    27142726      libs1 = string_libs[str2_nr].list; 
    2715       for (k = 0; k < liberties2; k++) 
    2716         if (ml[libs1[k]] == liberty_mark) { 
    2717           if (commonlibs < maxlib) 
    2718             libs[commonlibs] = libs1[k]; 
     2727      last_lib = libs1 + liberties2; 
     2728      for (; libs1 < last_lib; libs1++) 
     2729        if (ml[*libs1] == liberty_mark) { 
     2730          if (commonlibs < maxlib) 
     2731            libs[commonlibs] = *libs1; 
    27192732          commonlibs++; 
    27202733        } 
    27212734       
     
    27282741  } 
    27292742   
    27302743  color = string[str2_nr].color; 
    2731   for (k = 0; k < liberties1; k++) 
    2732     if (NEIGHBOR_OF_STRING(libs1[k], str2_nr, color)) { 
     2744  last_lib = libs1 + liberties1; 
     2745  for (; libs1 < last_lib; libs1++) 
     2746    if (NEIGHBOR_OF_STRING(*libs1, str2_nr, color)) { 
    27332747      if (commonlibs < maxlib) 
    2734         libs[commonlibs] = libs1[k]; 
     2748        libs[commonlibs] = *libs1; 
    27352749      commonlibs++; 
    27362750    } 
    27372751   
     
    27462760have_common_lib(int str1_pos, int str2_pos, int *lib) 
    27472761{ 
    27482762  int all_libs1[MAXLIBS], *libs1; 
     2763  int *last_lib; 
    27492764  int liberties1, liberties2; 
    27502765  int str1_nr, str2_nr; 
    2751   int k; 
    27522766  int color; 
    27532767 
    27542768  ASSERT_ON_BOARD1(str1_pos); 
     
    27802794  } 
    27812795 
    27822796  color = string[str2_nr].color; 
    2783   for (k = 0; k < liberties1; k++) { 
    2784     if (NEIGHBOR_OF_STRING(libs1[k], str2_nr, color)) { 
     2797  last_lib = libs1 + liberties1; 
     2798  for (; libs1 < last_lib; libs1++) 
     2799    if (NEIGHBOR_OF_STRING(*libs1, str2_nr, color)) { 
    27852800      if (lib) 
    2786         *lib = libs1[k]; 
     2801        *lib = *libs1; 
    27872802      return 1; 
    27882803    } 
    2789   } 
    27902804   
    27912805  return 0; 
    27922806} 
     
    28182832  int str_nr; 
    28192833  int size; 
    28202834  int pos; 
    2821   int k; 
    2822   int limit; 
     2835  int *limit; 
    28232836 
    28242837  ASSERT_ON_BOARD1(str_pos); 
    28252838  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
     
    28292842   
    28302843  /* Traverse the stones of the string, by following the cyclic chain. */ 
    28312844  pos = FIRST_STONE(str_nr); 
    2832   limit = maxstones > size ? size : maxstones; 
    2833   for (k = 0; k < limit; k++) { 
    2834     stones[k] = pos; 
     2845  limit = stones + (maxstones > size ? size : maxstones); 
     2846  for (; stones < limit; stones++) { 
     2847    *stones = pos; 
    28352848    pos = NEXT_STONE(pos); 
    28362849  } 
    28372850 
     
    28862899int  
    28872900chainlinks(int str_pos, int adj[MAXCHAIN]) 
    28882901{ 
    2889   struct string_neighbors_data *sn; 
    2890   int k; 
     2902  int *cur_neighbor, *last_neigbor; 
    28912903  int neighbors; 
    28922904 
    28932905  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
     
    28962908   * desired information. 
    28972909   */ 
    28982910  neighbors = string[string_number[str_pos]].neighbors; 
    2899   sn = string_neighbors + string_number[str_pos]; 
    2900   for (k = 0; k < neighbors; k++) 
    2901     adj[k] = string[sn->list[k]].origin; 
     2911  cur_neighbor = (string_neighbors + string_number[str_pos])->list; 
     2912  last_neigbor = cur_neighbor + neighbors; 
     2913  for (; cur_neighbor < last_neigbor; adj++, cur_neighbor++) 
     2914    *adj = string[*cur_neighbor].origin; 
    29022915 
    29032916  return neighbors; 
    29042917} 
     
    29122925int 
    29132926chainlinks2(int str_pos, int adj[MAXCHAIN], int lib) 
    29142927{ 
    2915   struct string_neighbors_data *sn; 
    2916   int k; 
    2917   int neighbors, max_neighbors; 
     2928  int *cur_neighbor, *last_neigbor; 
     2929  int neighbors; 
    29182930 
    29192931  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
    29202932 
     
    29222934   * right number of liberties. 
    29232935   */ 
    29242936  neighbors = 0; 
    2925   max_neighbors = string[string_number[str_pos]].neighbors; 
    2926   sn = string_neighbors + string_number[str_pos]; 
    2927   for (k = 0; k < max_neighbors; k++) { 
    2928     if (string[sn->list[k]].liberties == lib) 
    2929       adj[neighbors++] = string[sn->list[k]].origin; 
     2937  cur_neighbor = (string_neighbors + string_number[str_pos])->list; 
     2938  last_neigbor = cur_neighbor + string[string_number[str_pos]].neighbors; 
     2939  for (; cur_neighbor < last_neigbor; cur_neighbor++) { 
     2940    if (string[*cur_neighbor].liberties == lib) 
     2941      adj[neighbors++] = string[*cur_neighbor].origin; 
    29302942  } 
    29312943  return neighbors; 
    29322944} 
     
    29402952int 
    29412953chainlinks3(int str_pos, int adj[MAXCHAIN], int lib) 
    29422954{ 
    2943   struct string_neighbors_data *sn; 
    2944   int k; 
    2945   int neighbors, max_neighbors; 
     2955  int *cur_neighbor, *last_neigbor; 
     2956  int neighbors; 
    29462957 
    29472958  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
    29482959 
     
    29502961   * right number of liberties. 
    29512962   */ 
    29522963  neighbors = 0; 
    2953   max_neighbors = string[string_number[str_pos]].neighbors; 
    2954   sn = string_neighbors + string_number[str_pos]; 
    2955   for (k = 0; k < max_neighbors; k++) { 
    2956     if (string[sn->list[k]].liberties <= lib) 
    2957       adj[neighbors++] = string[sn->list[k]].origin; 
     2964  cur_neighbor = (string_neighbors + string_number[str_pos])->list; 
     2965  last_neigbor = cur_neighbor + string[string_number[str_pos]].neighbors; 
     2966  for (; cur_neighbor < last_neigbor; cur_neighbor++) { 
     2967    if (string[*cur_neighbor].liberties <= lib) 
     2968      adj[neighbors++] = string[*cur_neighbor].origin; 
    29582969  } 
    29592970  return neighbors; 
    29602971} 
     
    29722983int  
    29732984extended_chainlinks(int str_pos, int adj[MAXCHAIN], int both_colors) 
    29742985{ 
    2975   struct string_neighbors_data *sn; 
    2976   int n; 
    2977   int r; 
     2986  int *cur_neighbor, *last_neigbor; 
    29782987  int libs[MAXLIBS]; 
    2979   int liberties; 
     2988  int *cur_lib, *last_lib; 
    29802989  int checked_pos; 
    29812990  int color; 
    29822991  int other; 
    2983   int neighbors; 
    29842992  int str_nr; 
     2993  int *cur_adj; 
    29852994 
    29862995  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
    29872996 
    29882997  str_nr = string_number[str_pos]; 
    29892998  color = string[str_nr].color; 
    29902999  other = OTHER_COLOR(color); 
    2991   sn = string_neighbors + str_nr; 
    29923000  string_mark++; 
     3001  cur_adj = adj; 
    29933002 
    29943003  /* We already have the list of directly adjacent strings ready, just 
    29953004   * copy it and mark the strings. We also mark ourselves in case 
     
    29973006   */ 
    29983007  MARK_STRING(str_nr); 
    29993008 
    3000   neighbors = string[str_nr].neighbors; 
    3001   for (n = 0; n < neighbors; n++) { 
    3002     adj[n] = string[sn->list[n]].origin; 
    3003     MARK_STRING(sn->list[n]); 
     3009  cur_neighbor = (string_neighbors + str_nr)->list; 
     3010  last_neigbor = cur_neighbor + string[str_nr].neighbors; 
     3011  for (; cur_neighbor < last_neigbor; cur_neighbor++) { 
     3012    *cur_adj++ = string[*cur_neighbor].origin; 
     3013    MARK_STRING(*cur_neighbor); 
    30043014  } 
    30053015 
    30063016  /* Get the liberties. */ 
    3007   liberties = findlib(str_pos, MAXLIBS, libs); 
     3017  cur_lib = libs; 
     3018  last_lib = cur_lib + findlib(str_pos, MAXLIBS, libs); 
    30083019 
    30093020  /* Look for unmarked strings next to a liberty and add the 
    30103021   * ones which are found to the output. 
    30113022   */ 
    3012   for (r = 0; r < liberties; r++) { 
    3013     checked_pos = SOUTH(libs[r]); 
     3023  for (; cur_lib < last_lib; cur_lib++) { 
     3024    checked_pos = SOUTH(*cur_lib); 
    30143025    if (board[checked_pos] == other 
    30153026        || (both_colors && board[checked_pos] == color)) { 
    30163027      str_nr = string_number[checked_pos]; 
    30173028      if (UNMARKED_STRING(str_nr)) { 
    30183029        MARK_STRING(str_nr); 
    3019         adj[n++] = string[str_nr].origin; 
     3030        *cur_adj++ = string[str_nr].origin; 
    30203031      } 
    30213032    } 
    30223033 
    3023     checked_pos = WEST(libs[r]); 
     3034    checked_pos = WEST(*cur_lib); 
    30243035    if (board[checked_pos] == other 
    30253036        || (both_colors && board[checked_pos] == color)) { 
    30263037      str_nr = string_number[checked_pos]; 
    30273038      if (UNMARKED_STRING(str_nr)) { 
    30283039        MARK_STRING(str_nr); 
    3029         adj[n++] = string[str_nr].origin; 
     3040        *cur_adj++ = string[str_nr].origin; 
    30303041      } 
    30313042    } 
    30323043 
    3033     checked_pos = NORTH(libs[r]); 
     3044    checked_pos = NORTH(*cur_lib); 
    30343045    if (board[checked_pos] == other 
    30353046        || (both_colors && board[checked_pos] == color)) { 
    30363047      str_nr = string_number[checked_pos]; 
    30373048      if (UNMARKED_STRING(str_nr)) { 
    30383049        MARK_STRING(str_nr); 
    3039         adj[n++] = string[str_nr].origin; 
     3050        *cur_adj++ = string[str_nr].origin; 
    30403051      } 
    30413052    } 
    30423053 
    3043     checked_pos = EAST(libs[r]); 
     3054    checked_pos = EAST(*cur_lib); 
    30443055    if (board[checked_pos] == other 
    30453056        || (both_colors && board[checked_pos] == color)) { 
    30463057      str_nr = string_number[checked_pos]; 
    30473058      if (UNMARKED_STRING(str_nr)) { 
    30483059        MARK_STRING(str_nr); 
    3049         adj[n++] = string[str_nr].origin; 
     3060        *cur_adj++ = string[str_nr].origin; 
    30503061      } 
    30513062    } 
    30523063  } 
    30533064   
    3054   return n; 
     3065  return cur_adj - adj; 
    30553066} 
    30563067 
    30573068 
     
    33213332int 
    33223333adjacent_strings(int str1_pos, int str2_pos) 
    33233334{ 
    3324   int k; 
     3335  int *last_neighbor; 
    33253336  int neighbors1, neighbors2; 
    33263337  int str1_nr, str2_nr; 
    33273338  int *neighbors_list; 
     
    33443355  else 
    33453356    neighbors_list = string_neighbors[str1_nr].list; 
    33463357   
    3347   for (k = 0; k < neighbors1; k++) 
    3348     if (neighbors_list[k] == str2_nr) 
     3358  last_neighbor = neighbors_list + neighbors1; 
     3359  for (; neighbors_list < last_neighbor; neighbors_list++) 
     3360    if (*neighbors_list == str2_nr) 
    33493361      return 1; 
    33503362 
    33513363  return 0; 
     
    35533565int 
    35543566move_in_stack(int pos, int cutoff) 
    35553567{ 
    3556   int k; 
    3557   for (k = cutoff; k < stackp; k++) 
    3558     if (stack[k] == pos) 
     3568  int *act, *last; 
     3569  act = stack + cutoff; 
     3570  last = stack + stackp; 
     3571  for (; act < last; act++) 
     3572    if (*act == pos) 
    35593573      return 1; 
    35603574   
    35613575  return 0; 
     
    37573771propagate_string(int stone_pos, int str_pos, int color) 
    37583772{ 
    37593773  int size = 1; 
    3760   int k; 
     3774  const int *act_delta, *last_delta; 
    37613775   
    37623776  if (stone_pos == str_pos) { 
    37633777    /* Start a new string. */ 
     
    37713785  } 
    37723786 
    37733787  /* Look in all four directions for more stones to add. */ 
    3774   for (k = 0; k < 4; k++) { 
    3775     int new_pos = stone_pos + delta[k]; 
     3788  act_delta = delta; 
     3789  last_delta = act_delta + 4; 
     3790  for (; act_delta < last_delta; act_delta++) { 
     3791    int new_pos = stone_pos + *act_delta; 
    37763792    if (board[new_pos] == color 
    37773793        && string_number[new_pos] == -1) 
    37783794      size += propagate_string(new_pos, str_pos, color); 
     
    38743890update_liberties(int str_nr) 
    38753891{ 
    38763892  int pos; 
    3877   int k; 
     3893  int liberties; 
    38783894  int first_stone; 
     3895  int *cur_lib, *limit; 
    38793896 
    38803897  /* Push the old information. */ 
    38813898  PUSH_VALUE(string[str_nr].liberties); 
    3882   for (k = 0; k < string[str_nr].liberties && k < MAX_LIBERTIES; k++) { 
    3883     PUSH_VALUE(string_libs[str_nr].list[k]); 
    3884   } 
     3899  liberties = string[str_nr].liberties; 
     3900  cur_lib = string_libs[str_nr].list; 
     3901  limit = cur_lib + (liberties < MAX_LIBERTIES ? liberties : MAX_LIBERTIES); 
     3902  for (; cur_lib < limit; cur_lib++) 
     3903    PUSH_VALUE(*cur_lib); 
    38853904  string[str_nr].liberties = 0; 
    38863905 
    38873906  /* Clear the liberty mark. */ 
     
    39363955      PUSH_VALUE(sn->list[s->neighbors - 1]); 
    39373956      PUSH_VALUE(sn->list[k]); 
    39383957      PUSH_VALUE(s->neighbors); 
    3939       sn->list[k] = sn->list[s->neighbors - 1]; 
    39403958      s->neighbors--; 
     3959      sn->list[k] = sn->list[s->neighbors]; 
    39413960#ifndef GG_TURN_OFF_ASSERTS 
    39423961      done = 1; 
    39433962#endif 
     
    39723991        PUSH_VALUE(sl->list[s->liberties - 1]); 
    39733992        PUSH_VALUE(sl->list[k]); 
    39743993        PUSH_VALUE(s->liberties); 
    3975         sl->list[k] = sl->list[s->liberties - 1]; 
    39763994        s->liberties--; 
     3995        sl->list[k] = sl->list[s->liberties]; 
    39773996        break; 
    39783997      } 
    39793998  } 
     
    39884007do_remove_string(int str_nr) 
    39894008{ 
    39904009  int pos; 
    3991   int k; 
    3992   int *str_neighbors_list = string_neighbors[str_nr].list; 
    39934010  struct string_data *str_data = string + str_nr; 
    39944011  int size = str_data->size;