diff -N -r -u -X .ignore gnugo-copy/engine/board.c gnugo/engine/board.c
|
old
|
new
|
|
| 1972 | 1972 | * it is not optimized much. |
| 1973 | 1973 | */ |
| 1974 | 1974 | else { |
| 1975 | | int k; |
| | 1975 | const int *cur_delta, *last_delta; |
| 1976 | 1976 | int other = OTHER_COLOR(color); |
| 1977 | 1977 | |
| 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; |
| 1980 | 1982 | |
| 1981 | 1983 | if (LIBERTY(neighbor_pos) |
| 1982 | 1984 | && (ally1 < 0 || !NEIGHBOR_OF_STRING(neighbor_pos, ally1, color)) |
| … |
… |
|
| 2106 | 2108 | do_approxlib(int pos, int color, int maxlib, int *libs, |
| 2107 | 2109 | struct board_cache_entry *entry) |
| 2108 | 2110 | { |
| 2109 | | int k; |
| | 2111 | int *cur_lib, *last_lib; |
| 2110 | 2112 | int liberties = 0; |
| 2111 | | int checked_pos, str_nr, str_libs, checked_lib; |
| | 2113 | int checked_pos, str_nr; |
| 2112 | 2114 | |
| 2113 | 2115 | /* Look for empty neighbors and the liberties of the adjacent |
| 2114 | 2116 | * strings of the given color. The algorithm below won't work |
| … |
… |
|
| 2138 | 2140 | } |
| 2139 | 2141 | else if (board[checked_pos] == color) { |
| 2140 | 2142 | 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)) { |
| 2145 | 2147 | if (libs != NULL) |
| 2146 | | libs[liberties] = checked_lib; |
| | 2148 | libs[liberties] = *cur_lib; |
| 2147 | 2149 | liberties++; |
| 2148 | 2150 | if (liberties >= maxlib) |
| 2149 | 2151 | return liberties; |
| 2150 | | MARK_LIBERTY(checked_lib); |
| | 2152 | MARK_LIBERTY(*cur_lib); |
| 2151 | 2153 | } |
| 2152 | 2154 | } |
| 2153 | 2155 | } |
| … |
… |
|
| 2166 | 2168 | } |
| 2167 | 2169 | else if (board[checked_pos] == color) { |
| 2168 | 2170 | 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)) { |
| 2173 | 2175 | if (libs != NULL) |
| 2174 | | libs[liberties] = checked_lib; |
| | 2176 | libs[liberties] = *cur_lib; |
| 2175 | 2177 | liberties++; |
| 2176 | 2178 | if (liberties >= maxlib) |
| 2177 | 2179 | return liberties; |
| 2178 | | MARK_LIBERTY(checked_lib); |
| | 2180 | MARK_LIBERTY(*cur_lib); |
| 2179 | 2181 | } |
| 2180 | 2182 | } |
| 2181 | 2183 | } |
| … |
… |
|
| 2194 | 2196 | } |
| 2195 | 2197 | else if (board[checked_pos] == color) { |
| 2196 | 2198 | 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)) { |
| 2201 | 2203 | if (libs != NULL) |
| 2202 | | libs[liberties] = checked_lib; |
| | 2204 | libs[liberties] = *cur_lib; |
| 2203 | 2205 | liberties++; |
| 2204 | 2206 | if (liberties >= maxlib) |
| 2205 | 2207 | return liberties; |
| 2206 | | MARK_LIBERTY(checked_lib); |
| | 2208 | MARK_LIBERTY(*cur_lib); |
| 2207 | 2209 | } |
| 2208 | 2210 | } |
| 2209 | 2211 | } |
| … |
… |
|
| 2224 | 2226 | } |
| 2225 | 2227 | else if (board[checked_pos] == color) { |
| 2226 | 2228 | 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)) { |
| 2231 | 2233 | if (libs != NULL) |
| 2232 | | libs[liberties] = checked_lib; |
| | 2234 | libs[liberties] = *cur_lib; |
| 2233 | 2235 | liberties++; |
| 2234 | 2236 | if (liberties >= maxlib) |
| 2235 | 2237 | return liberties; |
| 2236 | | MARK_LIBERTY(checked_lib); |
| | 2238 | MARK_LIBERTY(*cur_lib); |
| 2237 | 2239 | } |
| 2238 | 2240 | } |
| 2239 | 2241 | } |
| … |
… |
|
| 2259 | 2261 | slow_approxlib(int pos, int color, int maxlib, int *libs, |
| 2260 | 2262 | struct board_cache_entry *entry) |
| 2261 | 2263 | { |
| 2262 | | int k; |
| | 2264 | const int *delta_o, *delta_i, *last_delta = delta + 4; |
| 2263 | 2265 | int liberties = 0; |
| 2264 | 2266 | int checked_pos, checked_pos2; |
| 2265 | 2267 | int pos2, str_nr, first_stone; |
| … |
… |
|
| 2268 | 2270 | MARK_LIBERTY(pos); |
| 2269 | 2271 | string_mark++; |
| 2270 | 2272 | |
| 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; |
| 2273 | 2275 | if (board[checked_pos] == EMPTY) { |
| 2274 | 2276 | if (ml[checked_pos] != liberty_mark) { |
| 2275 | 2277 | if (libs) |
| … |
… |
|
| 2286 | 2288 | pos2 = first_stone; |
| 2287 | 2289 | do { |
| 2288 | 2290 | 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; |
| 2291 | 2293 | if (UNMARKED_LIBERTY(checked_pos2)) { |
| 2292 | 2294 | if (libs) |
| 2293 | 2295 | libs[liberties] = checked_pos2; |
| … |
… |
|
| 2414 | 2416 | do_accuratelib(int pos, int color, int maxlib, int *libs, |
| 2415 | 2417 | struct board_cache_entry *entry) |
| 2416 | 2418 | { |
| 2417 | | int k, l; |
| | 2419 | const int *act_delta, *last_delta; |
| | 2420 | int *act_lib, *last_lib; |
| 2418 | 2421 | int lib_count = 0; |
| 2419 | | int lib; |
| 2420 | 2422 | int captured[4]; |
| 2421 | 2423 | int captures = 0; |
| | 2424 | int *act_capture, *check_capture, *last_capture; |
| 2422 | 2425 | int first_stone; |
| 2423 | 2426 | int stone_pos; |
| 2424 | 2427 | int checked_lib; |
| … |
… |
|
| 2427 | 2430 | liberty_mark++; |
| 2428 | 2431 | MARK_LIBERTY(pos); |
| 2429 | 2432 | |
| 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; |
| 2432 | 2437 | if (board[checked_pos] == EMPTY) { |
| 2433 | 2438 | if (ml[checked_pos] != liberty_mark) { |
| 2434 | 2439 | /* A trivial liberty */ |
| … |
… |
|
| 2451 | 2456 | /* The easy case - we already have all (necessary) liberties of |
| 2452 | 2457 | * the string listed |
| 2453 | 2458 | */ |
| 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)) { |
| 2458 | 2463 | if (libs) |
| 2459 | | libs[lib_count] = lib; |
| | 2464 | libs[lib_count] = *act_lib; |
| 2460 | 2465 | lib_count++; |
| 2461 | 2466 | if (lib_count >= maxlib) |
| 2462 | 2467 | return lib_count; |
| 2463 | 2468 | |
| 2464 | | MARK_LIBERTY(lib); |
| | 2469 | MARK_LIBERTY(*act_lib); |
| 2465 | 2470 | } |
| 2466 | 2471 | } |
| 2467 | 2472 | } |
| … |
… |
|
| 2531 | 2536 | } |
| 2532 | 2537 | |
| 2533 | 2538 | /* 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++) { |
| 2535 | 2542 | int capture_nr; |
| 2536 | | first_stone = captured[k]; |
| | 2543 | first_stone = *act_capture; |
| 2537 | 2544 | |
| 2538 | 2545 | /* Add the stone adjacent to (pos) to the list of liberties if |
| 2539 | 2546 | * it is not also adjacent to an own marked string (otherwise, |
| … |
… |
|
| 2557 | 2564 | |
| 2558 | 2565 | /* Check if we already know of this capture. */ |
| 2559 | 2566 | 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) |
| 2562 | 2570 | break; |
| 2563 | 2571 | |
| 2564 | | if (l == k) { |
| | 2572 | if (check_capture == act_capture) { |
| 2565 | 2573 | /* Traverse all the stones of the capture and add to the list |
| 2566 | 2574 | * of liberties those, which are adjacent to at least one own |
| 2567 | 2575 | * marked string. |
| … |
… |
|
| 2602 | 2610 | count_common_libs(int str1_pos, int str2_pos) |
| 2603 | 2611 | { |
| 2604 | 2612 | int all_libs1[MAXLIBS], *libs1; |
| | 2613 | int *last_lib; |
| 2605 | 2614 | int liberties1, liberties2; |
| 2606 | 2615 | int str1_nr, str2_nr; |
| 2607 | 2616 | int commonlibs = 0; |
| 2608 | | int k; |
| 2609 | 2617 | int color; |
| 2610 | 2618 | |
| 2611 | 2619 | ASSERT_ON_BOARD1(str1_pos); |
| … |
… |
|
| 2636 | 2644 | /* Speed optimization: NEIGHBOR_OF_STRING is quite expensive */ |
| 2637 | 2645 | liberty_mark++; |
| 2638 | 2646 | |
| 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); |
| 2641 | 2650 | |
| 2642 | 2651 | 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) |
| 2645 | 2655 | commonlibs++; |
| 2646 | 2656 | |
| 2647 | 2657 | return commonlibs; |
| … |
… |
|
| 2653 | 2663 | } |
| 2654 | 2664 | |
| 2655 | 2665 | 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)) |
| 2658 | 2669 | commonlibs++; |
| 2659 | 2670 | |
| 2660 | 2671 | return commonlibs; |
| … |
… |
|
| 2673 | 2684 | find_common_libs(int str1_pos, int str2_pos, int maxlib, int *libs) |
| 2674 | 2685 | { |
| 2675 | 2686 | int all_libs1[MAXLIBS], *libs1; |
| | 2687 | int *last_lib; |
| 2676 | 2688 | int liberties1, liberties2; |
| 2677 | 2689 | int str1_nr, str2_nr; |
| 2678 | 2690 | int commonlibs = 0; |
| 2679 | | int k; |
| 2680 | 2691 | int color; |
| 2681 | 2692 | |
| 2682 | 2693 | ASSERT_ON_BOARD1(str1_pos); |
| … |
… |
|
| 2708 | 2719 | /* Speed optimization: NEIGHBOR_OF_STRING is quite expensive */ |
| 2709 | 2720 | liberty_mark++; |
| 2710 | 2721 | |
| 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 | |
| 2714 | 2726 | 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; |
| 2719 | 2732 | commonlibs++; |
| 2720 | 2733 | } |
| 2721 | 2734 | |
| … |
… |
|
| 2728 | 2741 | } |
| 2729 | 2742 | |
| 2730 | 2743 | 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)) { |
| 2733 | 2747 | if (commonlibs < maxlib) |
| 2734 | | libs[commonlibs] = libs1[k]; |
| | 2748 | libs[commonlibs] = *libs1; |
| 2735 | 2749 | commonlibs++; |
| 2736 | 2750 | } |
| 2737 | 2751 | |
| … |
… |
|
| 2746 | 2760 | have_common_lib(int str1_pos, int str2_pos, int *lib) |
| 2747 | 2761 | { |
| 2748 | 2762 | int all_libs1[MAXLIBS], *libs1; |
| | 2763 | int *last_lib; |
| 2749 | 2764 | int liberties1, liberties2; |
| 2750 | 2765 | int str1_nr, str2_nr; |
| 2751 | | int k; |
| 2752 | 2766 | int color; |
| 2753 | 2767 | |
| 2754 | 2768 | ASSERT_ON_BOARD1(str1_pos); |
| … |
… |
|
| 2780 | 2794 | } |
| 2781 | 2795 | |
| 2782 | 2796 | 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)) { |
| 2785 | 2800 | if (lib) |
| 2786 | | *lib = libs1[k]; |
| | 2801 | *lib = *libs1; |
| 2787 | 2802 | return 1; |
| 2788 | 2803 | } |
| 2789 | | } |
| 2790 | 2804 | |
| 2791 | 2805 | return 0; |
| 2792 | 2806 | } |
| … |
… |
|
| 2818 | 2832 | int str_nr; |
| 2819 | 2833 | int size; |
| 2820 | 2834 | int pos; |
| 2821 | | int k; |
| 2822 | | int limit; |
| | 2835 | int *limit; |
| 2823 | 2836 | |
| 2824 | 2837 | ASSERT_ON_BOARD1(str_pos); |
| 2825 | 2838 | ASSERT1(IS_STONE(board[str_pos]), str_pos); |
| … |
… |
|
| 2829 | 2842 | |
| 2830 | 2843 | /* Traverse the stones of the string, by following the cyclic chain. */ |
| 2831 | 2844 | 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; |
| 2835 | 2848 | pos = NEXT_STONE(pos); |
| 2836 | 2849 | } |
| 2837 | 2850 | |
| … |
… |
|
| 2886 | 2899 | int |
| 2887 | 2900 | chainlinks(int str_pos, int adj[MAXCHAIN]) |
| 2888 | 2901 | { |
| 2889 | | struct string_neighbors_data *sn; |
| 2890 | | int k; |
| | 2902 | int *cur_neighbor, *last_neigbor; |
| 2891 | 2903 | int neighbors; |
| 2892 | 2904 | |
| 2893 | 2905 | ASSERT1(IS_STONE(board[str_pos]), str_pos); |
| … |
… |
|
| 2896 | 2908 | * desired information. |
| 2897 | 2909 | */ |
| 2898 | 2910 | 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; |
| 2902 | 2915 | |
| 2903 | 2916 | return neighbors; |
| 2904 | 2917 | } |
| … |
… |
|
| 2912 | 2925 | int |
| 2913 | 2926 | chainlinks2(int str_pos, int adj[MAXCHAIN], int lib) |
| 2914 | 2927 | { |
| 2915 | | struct string_neighbors_data *sn; |
| 2916 | | int k; |
| 2917 | | int neighbors, max_neighbors; |
| | 2928 | int *cur_neighbor, *last_neigbor; |
| | 2929 | int neighbors; |
| 2918 | 2930 | |
| 2919 | 2931 | ASSERT1(IS_STONE(board[str_pos]), str_pos); |
| 2920 | 2932 | |
| … |
… |
|
| 2922 | 2934 | * right number of liberties. |
| 2923 | 2935 | */ |
| 2924 | 2936 | 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; |
| 2930 | 2942 | } |
| 2931 | 2943 | return neighbors; |
| 2932 | 2944 | } |
| … |
… |
|
| 2940 | 2952 | int |
| 2941 | 2953 | chainlinks3(int str_pos, int adj[MAXCHAIN], int lib) |
| 2942 | 2954 | { |
| 2943 | | struct string_neighbors_data *sn; |
| 2944 | | int k; |
| 2945 | | int neighbors, max_neighbors; |
| | 2955 | int *cur_neighbor, *last_neigbor; |
| | 2956 | int neighbors; |
| 2946 | 2957 | |
| 2947 | 2958 | ASSERT1(IS_STONE(board[str_pos]), str_pos); |
| 2948 | 2959 | |
| … |
… |
|
| 2950 | 2961 | * right number of liberties. |
| 2951 | 2962 | */ |
| 2952 | 2963 | 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; |
| 2958 | 2969 | } |
| 2959 | 2970 | return neighbors; |
| 2960 | 2971 | } |
| … |
… |
|
| 2972 | 2983 | int |
| 2973 | 2984 | extended_chainlinks(int str_pos, int adj[MAXCHAIN], int both_colors) |
| 2974 | 2985 | { |
| 2975 | | struct string_neighbors_data *sn; |
| 2976 | | int n; |
| 2977 | | int r; |
| | 2986 | int *cur_neighbor, *last_neigbor; |
| 2978 | 2987 | int libs[MAXLIBS]; |
| 2979 | | int liberties; |
| | 2988 | int *cur_lib, *last_lib; |
| 2980 | 2989 | int checked_pos; |
| 2981 | 2990 | int color; |
| 2982 | 2991 | int other; |
| 2983 | | int neighbors; |
| 2984 | 2992 | int str_nr; |
| | 2993 | int *cur_adj; |
| 2985 | 2994 | |
| 2986 | 2995 | ASSERT1(IS_STONE(board[str_pos]), str_pos); |
| 2987 | 2996 | |
| 2988 | 2997 | str_nr = string_number[str_pos]; |
| 2989 | 2998 | color = string[str_nr].color; |
| 2990 | 2999 | other = OTHER_COLOR(color); |
| 2991 | | sn = string_neighbors + str_nr; |
| 2992 | 3000 | string_mark++; |
| | 3001 | cur_adj = adj; |
| 2993 | 3002 | |
| 2994 | 3003 | /* We already have the list of directly adjacent strings ready, just |
| 2995 | 3004 | * copy it and mark the strings. We also mark ourselves in case |
| … |
… |
|
| 2997 | 3006 | */ |
| 2998 | 3007 | MARK_STRING(str_nr); |
| 2999 | 3008 | |
| 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); |
| 3004 | 3014 | } |
| 3005 | 3015 | |
| 3006 | 3016 | /* Get the liberties. */ |
| 3007 | | liberties = findlib(str_pos, MAXLIBS, libs); |
| | 3017 | cur_lib = libs; |
| | 3018 | last_lib = cur_lib + findlib(str_pos, MAXLIBS, libs); |
| 3008 | 3019 | |
| 3009 | 3020 | /* Look for unmarked strings next to a liberty and add the |
| 3010 | 3021 | * ones which are found to the output. |
| 3011 | 3022 | */ |
| 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); |
| 3014 | 3025 | if (board[checked_pos] == other |
| 3015 | 3026 | || (both_colors && board[checked_pos] == color)) { |
| 3016 | 3027 | str_nr = string_number[checked_pos]; |
| 3017 | 3028 | if (UNMARKED_STRING(str_nr)) { |
| 3018 | 3029 | MARK_STRING(str_nr); |
| 3019 | | adj[n++] = string[str_nr].origin; |
| | 3030 | *cur_adj++ = string[str_nr].origin; |
| 3020 | 3031 | } |
| 3021 | 3032 | } |
| 3022 | 3033 | |
| 3023 | | checked_pos = WEST(libs[r]); |
| | 3034 | checked_pos = WEST(*cur_lib); |
| 3024 | 3035 | if (board[checked_pos] == other |
| 3025 | 3036 | || (both_colors && board[checked_pos] == color)) { |
| 3026 | 3037 | str_nr = string_number[checked_pos]; |
| 3027 | 3038 | if (UNMARKED_STRING(str_nr)) { |
| 3028 | 3039 | MARK_STRING(str_nr); |
| 3029 | | adj[n++] = string[str_nr].origin; |
| | 3040 | *cur_adj++ = string[str_nr].origin; |
| 3030 | 3041 | } |
| 3031 | 3042 | } |
| 3032 | 3043 | |
| 3033 | | checked_pos = NORTH(libs[r]); |
| | 3044 | checked_pos = NORTH(*cur_lib); |
| 3034 | 3045 | if (board[checked_pos] == other |
| 3035 | 3046 | || (both_colors && board[checked_pos] == color)) { |
| 3036 | 3047 | str_nr = string_number[checked_pos]; |
| 3037 | 3048 | if (UNMARKED_STRING(str_nr)) { |
| 3038 | 3049 | MARK_STRING(str_nr); |
| 3039 | | adj[n++] = string[str_nr].origin; |
| | 3050 | *cur_adj++ = string[str_nr].origin; |
| 3040 | 3051 | } |
| 3041 | 3052 | } |
| 3042 | 3053 | |
| 3043 | | checked_pos = EAST(libs[r]); |
| | 3054 | checked_pos = EAST(*cur_lib); |
| 3044 | 3055 | if (board[checked_pos] == other |
| 3045 | 3056 | || (both_colors && board[checked_pos] == color)) { |
| 3046 | 3057 | str_nr = string_number[checked_pos]; |
| 3047 | 3058 | if (UNMARKED_STRING(str_nr)) { |
| 3048 | 3059 | MARK_STRING(str_nr); |
| 3049 | | adj[n++] = string[str_nr].origin; |
| | 3060 | *cur_adj++ = string[str_nr].origin; |
| 3050 | 3061 | } |
| 3051 | 3062 | } |
| 3052 | 3063 | } |
| 3053 | 3064 | |
| 3054 | | return n; |
| | 3065 | return cur_adj - adj; |
| 3055 | 3066 | } |
| 3056 | 3067 | |
| 3057 | 3068 | |
| … |
… |
|
| 3321 | 3332 | int |
| 3322 | 3333 | adjacent_strings(int str1_pos, int str2_pos) |
| 3323 | 3334 | { |
| 3324 | | int k; |
| | 3335 | int *last_neighbor; |
| 3325 | 3336 | int neighbors1, neighbors2; |
| 3326 | 3337 | int str1_nr, str2_nr; |
| 3327 | 3338 | int *neighbors_list; |
| … |
… |
|
| 3344 | 3355 | else |
| 3345 | 3356 | neighbors_list = string_neighbors[str1_nr].list; |
| 3346 | 3357 | |
| 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) |
| 3349 | 3361 | return 1; |
| 3350 | 3362 | |
| 3351 | 3363 | return 0; |
| … |
… |
|
| 3553 | 3565 | int |
| 3554 | 3566 | move_in_stack(int pos, int cutoff) |
| 3555 | 3567 | { |
| 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) |
| 3559 | 3573 | return 1; |
| 3560 | 3574 | |
| 3561 | 3575 | return 0; |
| … |
… |
|
| 3757 | 3771 | propagate_string(int stone_pos, int str_pos, int color) |
| 3758 | 3772 | { |
| 3759 | 3773 | int size = 1; |
| 3760 | | int k; |
| | 3774 | const int *act_delta, *last_delta; |
| 3761 | 3775 | |
| 3762 | 3776 | if (stone_pos == str_pos) { |
| 3763 | 3777 | /* Start a new string. */ |
| … |
… |
|
| 3771 | 3785 | } |
| 3772 | 3786 | |
| 3773 | 3787 | /* 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; |
| 3776 | 3792 | if (board[new_pos] == color |
| 3777 | 3793 | && string_number[new_pos] == -1) |
| 3778 | 3794 | size += propagate_string(new_pos, str_pos, color); |
| … |
… |
|
| 3874 | 3890 | update_liberties(int str_nr) |
| 3875 | 3891 | { |
| 3876 | 3892 | int pos; |
| 3877 | | int k; |
| | 3893 | int liberties; |
| 3878 | 3894 | int first_stone; |
| | 3895 | int *cur_lib, *limit; |
| 3879 | 3896 | |
| 3880 | 3897 | /* Push the old information. */ |
| 3881 | 3898 | 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); |
| 3885 | 3904 | string[str_nr].liberties = 0; |
| 3886 | 3905 | |
| 3887 | 3906 | /* Clear the liberty mark. */ |
| … |
… |
|
| 3936 | 3955 | PUSH_VALUE(sn->list[s->neighbors - 1]); |
| 3937 | 3956 | PUSH_VALUE(sn->list[k]); |
| 3938 | 3957 | PUSH_VALUE(s->neighbors); |
| 3939 | | sn->list[k] = sn->list[s->neighbors - 1]; |
| 3940 | 3958 | s->neighbors--; |
| | 3959 | sn->list[k] = sn->list[s->neighbors]; |
| 3941 | 3960 | #ifndef GG_TURN_OFF_ASSERTS |
| 3942 | 3961 | done = 1; |
| 3943 | 3962 | #endif |
| … |
… |
|
| 3972 | 3991 | PUSH_VALUE(sl->list[s->liberties - 1]); |
| 3973 | 3992 | PUSH_VALUE(sl->list[k]); |
| 3974 | 3993 | PUSH_VALUE(s->liberties); |
| 3975 | | sl->list[k] = sl->list[s->liberties - 1]; |
| 3976 | 3994 | s->liberties--; |
| | 3995 | sl->list[k] = sl->list[s->liberties]; |
| 3977 | 3996 | break; |
| 3978 | 3997 | } |
| 3979 | 3998 | } |
| … |
… |
|
| 3988 | 4007 | do_remove_string(int str_nr) |
| 3989 | 4008 | { |
| 3990 | 4009 | int pos; |
| 3991 | | int k; |
| 3992 | | int *str_neighbors_list = string_neighbors[str_nr].list; |
| 3993 | 4010 | struct string_data *str_data = string + str_nr; |
| 3994 | 4011 | int size = str_data->size; |