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; |
| 3995 | | int neighbors = str_data->neighbors; |
| | 4012 | int *str_neighbors_list = string_neighbors[str_nr].list; |
| | 4013 | int *last_neighbor = str_neighbors_list + str_data->neighbors; |
| 3996 | 4014 | int first_stone; |
| 3997 | 4015 | |
| 3998 | 4016 | /* Traverse the stones of the string, by following the cyclic chain. */ |
| … |
… |
|
| 4012 | 4030 | * update_liberties(). |
| 4013 | 4031 | */ |
| 4014 | 4032 | if (size == 1) { |
| 4015 | | for (k = 0; k < neighbors; k++) { |
| 4016 | | int neighbor_nr = str_neighbors_list[k]; |
| | 4033 | for (; str_neighbors_list < last_neighbor; str_neighbors_list++) { |
| | 4034 | int neighbor_nr = *str_neighbors_list; |
| 4017 | 4035 | int *neighbor_libs = &(string[neighbor_nr].liberties); |
| 4018 | 4036 | |
| 4019 | 4037 | remove_neighbor(neighbor_nr, str_nr); |
| … |
… |
|
| 4028 | 4046 | int other = OTHER_COLOR(str_data->color); |
| 4029 | 4047 | int pos2 = NEXT_STONE(pos); |
| 4030 | 4048 | |
| 4031 | | for (k = 0; k < neighbors; k++) { |
| 4032 | | int neighbor_nr = str_neighbors_list[k]; |
| | 4049 | for (; str_neighbors_list < last_neighbor; str_neighbors_list++) { |
| | 4050 | int neighbor_nr = *str_neighbors_list; |
| 4033 | 4051 | int *neighbor_libs = &(string[neighbor_nr].liberties); |
| 4034 | 4052 | |
| 4035 | 4053 | remove_neighbor(neighbor_nr, str_nr); |
| … |
… |
|
| 4049 | 4067 | } |
| 4050 | 4068 | } |
| 4051 | 4069 | else { |
| 4052 | | for (k = 0; k < neighbors; k++) { |
| 4053 | | remove_neighbor(str_neighbors_list[k], str_nr); |
| 4054 | | update_liberties(str_neighbors_list[k]); |
| | 4070 | for (; str_neighbors_list < last_neighbor; str_neighbors_list++) { |
| | 4071 | remove_neighbor(*str_neighbors_list, str_nr); |
| | 4072 | update_liberties(*str_neighbors_list); |
| 4055 | 4073 | } |
| 4056 | 4074 | } |
| 4057 | 4075 | |
| … |
… |
|
| 4174 | 4192 | static void |
| 4175 | 4193 | extend_neighbor_string(int pos, int str_nr, int color) |
| 4176 | 4194 | { |
| 4177 | | int k; |
| 4178 | 4195 | int liberties_updated = 0; |
| 4179 | 4196 | int other = OTHER_COLOR(color); |
| 4180 | 4197 | int checked_pos; |
| 4181 | | int *neighbors_list = string_neighbors[str_nr].list; |
| | 4198 | int *neighbors_list, *last_neighbor; |
| 4182 | 4199 | |
| 4183 | 4200 | /* Link in the stone in the cyclic list. */ |
| 4184 | 4201 | int origin = string[str_nr].origin; |
| … |
… |
|
| 4214 | 4231 | |
| 4215 | 4232 | /* Mark old neighbors of the string. */ |
| 4216 | 4233 | string_mark++; |
| 4217 | | for (k = 0; k < string[str_nr].neighbors; k++) |
| 4218 | | string[neighbors_list[k]].mark = string_mark; |
| | 4234 | neighbors_list = string_neighbors[str_nr].list; |
| | 4235 | last_neighbor = neighbors_list + string[str_nr].neighbors; |
| | 4236 | for (; neighbors_list < last_neighbor; neighbors_list++) |
| | 4237 | string[*neighbors_list].mark = string_mark; |
| 4219 | 4238 | |
| 4220 | 4239 | /* Look at the neighbor locations of pos for new liberties and/or |
| 4221 | 4240 | * neighbor strings. |
| … |
… |
|
| 4302 | 4321 | static void |
| 4303 | 4322 | assimilate_string(int str_nr, int ass_pos) |
| 4304 | 4323 | { |
| 4305 | | int k; |
| 4306 | 4324 | int last; |
| 4307 | 4325 | int ass_nr = string_number[ass_pos]; |
| 4308 | 4326 | int first_stone; |
| | 4327 | int *cur_neighbor, *last_neigbor; |
| 4309 | 4328 | string[str_nr].size += string[ass_nr].size; |
| 4310 | 4329 | |
| 4311 | 4330 | /* Walk through the assimilated string stones and change |
| … |
… |
|
| 4339 | 4358 | * been marked before this function is called. |
| 4340 | 4359 | */ |
| 4341 | 4360 | if (string[ass_nr].liberties <= MAX_LIBERTIES) { |
| 4342 | | for (k = 0; k < string[ass_nr].liberties; k++) { |
| 4343 | | int lib_pos = string_libs[ass_nr].list[k]; |
| 4344 | | if (UNMARKED_LIBERTY(lib_pos)) { |
| 4345 | | ADD_AND_MARK_LIBERTY(str_nr, lib_pos); |
| | 4361 | int *cur_lib = string_libs[ass_nr].list; |
| | 4362 | int *last_lib = cur_lib + string[ass_nr].liberties; |
| | 4363 | for (; cur_lib < last_lib; cur_lib++) { |
| | 4364 | if (UNMARKED_LIBERTY(*cur_lib)) { |
| | 4365 | ADD_AND_MARK_LIBERTY(str_nr, *cur_lib); |
| 4346 | 4366 | } |
| 4347 | 4367 | } |
| 4348 | 4368 | } |
| … |
… |
|
| 4367 | 4387 | * known neighbors of str_nr are assumed to have been marked before this |
| 4368 | 4388 | * function is called. |
| 4369 | 4389 | */ |
| 4370 | | for (k = 0; k < string[ass_nr].neighbors; k++) { |
| 4371 | | int neighbor_nr = string_neighbors[ass_nr].list[k]; |
| | 4390 | cur_neighbor = string_neighbors[ass_nr].list; |
| | 4391 | last_neigbor = cur_neighbor + string[ass_nr].neighbors; |
| | 4392 | for (; cur_neighbor < last_neigbor; cur_neighbor++) { |
| | 4393 | int neighbor_nr = *cur_neighbor; |
| 4372 | 4394 | remove_neighbor(neighbor_nr, ass_nr); |
| 4373 | 4395 | if (string[neighbor_nr].mark != string_mark) { |
| 4374 | 4396 | PUSH_VALUE(string[neighbor_nr].neighbors); |
| … |
… |
|
| 4764 | 4786 | else { \ |
| 4765 | 4787 | (*number_opponent)++; \ |
| 4766 | 4788 | if (string[str_nr].liberties == 1) { \ |
| 4767 | | int r; \ |
| 4768 | 4789 | int *neighbors_list = string_neighbors[str_nr].list; \ |
| 4769 | | int neighbors = string[str_nr].neighbors; \ |
| | 4790 | int *last_neighbor = neighbors_list + string[str_nr].neighbors; \ |
| 4770 | 4791 | (*captured_stones) += string[str_nr].size; \ |
| 4771 | | for (r = 0; r < neighbors; r++) { \ |
| 4772 | | if (string[neighbors_list[r]].liberties == 1) \ |
| 4773 | | (*saved_stones) += string[neighbors_list[r]].size; \ |
| | 4792 | for (; neighbors_list < last_neighbor; neighbors_list++) { \ |
| | 4793 | if (string[*neighbors_list].liberties == 1) \ |
| | 4794 | (*saved_stones) += string[*neighbors_list].size; \ |
| 4774 | 4795 | } \ |
| 4775 | 4796 | } \ |
| 4776 | 4797 | 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
|
old
|
new
|
|
| 741 | 741 | struct pattern *pattern, int ll, void *callback_data, |
| 742 | 742 | signed char goal[BOARDMAX]) |
| 743 | 743 | { |
| 744 | | int k; /* Iterate over elements of pattern */ |
| | 744 | struct patval *cur_pat, *last_pat; /* Iterate over elements of pattern */ |
| 745 | 745 | int found_goal = (goal == NULL); |
| 746 | 746 | |
| 747 | 747 | #if PROFILE_PATTERNS |
| … |
… |
|
| 754 | 754 | #endif |
| 755 | 755 | |
| 756 | 756 | /* Iterate over the elements of the pattern. */ |
| 757 | | for (k = 0; k < pattern->patlen; k++) { |
| | 757 | cur_pat = pattern->patn; |
| | 758 | last_pat = cur_pat + pattern->patlen; |
| | 759 | for (; cur_pat < last_pat; cur_pat++) { |
| 758 | 760 | /* match each point */ |
| 759 | 761 | int pos; /* absolute (board) co-ords of |
| 760 | 762 | (transformed) pattern element */ |
| 761 | 763 | |
| 762 | 764 | /* transform pattern real coordinate... */ |
| 763 | | pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor); |
| | 765 | pos = AFFINE_TRANSFORM(cur_pat->offset, ll, anchor); |
| 764 | 766 | ASSERT_ON_BOARD1(pos); |
| 765 | 767 | |
| 766 | 768 | /* goal check */ |
diff -N -r -u -X .ignore gnugo-copy/engine/movelist.c gnugo/engine/movelist.c
|
old
|
new
|
|
| 55 | 55 | int |
| 56 | 56 | discarded_move_known(int move, int max_points, int points[]) |
| 57 | 57 | { |
| 58 | | int k; |
| | 58 | int *last_point = points + max_points; |
| 59 | 59 | |
| 60 | | for (k = 0; k < max_points; k++) { |
| 61 | | if (points[k] == 0) |
| | 60 | for (; points < last_point; points++) { |
| | 61 | if (*points == 0) |
| 62 | 62 | return 0; |
| 63 | | if (points[k] == move) |
| | 63 | if (*points == move) |
| 64 | 64 | return 1; |
| 65 | 65 | } |
| 66 | 66 | return 0; |
| … |
… |
|
| 122 | 122 | void |
| 123 | 123 | movelist_change_discarded(int move, int max_points, int points[]) |
| 124 | 124 | { |
| 125 | | int k; |
| | 125 | int *last_point = points + max_points; |
| 126 | 126 | |
| 127 | 127 | /* We store only max_points discarded moves. */ |
| 128 | | for (k = 0; k < max_points; k++) { |
| 129 | | if (points[k] == move) |
| | 128 | for (; points < last_point; points++) { |
| | 129 | if (*points == move) |
| 130 | 130 | return; |
| 131 | 131 | |
| 132 | | if (points[k] == 0) { |
| 133 | | points[k] = move; |
| | 132 | if (*points == 0) { |
| | 133 | *points = move; |
| 134 | 134 | return; |
| 135 | 135 | } |
| 136 | 136 | } |
diff -N -r -u -X .ignore gnugo-copy/engine/unconditional.c gnugo/engine/unconditional.c
|
old
|
new
|
|
| 47 | 47 | int libs[MAXLIBS]; |
| 48 | 48 | int liberties; |
| 49 | 49 | int pos; |
| 50 | | int k; |
| | 50 | int *cur_lib, *last_lib; |
| 51 | 51 | |
| 52 | 52 | while (something_captured) { |
| 53 | 53 | /* Nothing captured so far in this turn of the loop. */ |
| … |
… |
|
| 63 | 63 | continue; |
| 64 | 64 | |
| 65 | 65 | /* Try to capture the string at pos. */ |
| 66 | | liberties = findlib(pos, MAXLIBS, libs); |
| | 66 | cur_lib = libs; |
| | 67 | last_lib = cur_lib + findlib(pos, MAXLIBS, libs); |
| 67 | 68 | save_moves = moves_played; |
| 68 | | for (k = 0; k < liberties; k++) |
| 69 | | moves_played += trymove(libs[k], other, "unconditional_life", pos); |
| | 69 | for (; cur_lib < last_lib; cur_lib++) |
| | 70 | moves_played += trymove(*cur_lib, other, "unconditional_life", pos); |
| 70 | 71 | |
| 71 | 72 | /* Successful if already captured or a single liberty remains. |
| 72 | 73 | * Otherwise we must rewind and take back the last batch of moves. |
| … |
… |
|
| 326 | 327 | int other = OTHER_COLOR(color); |
| 327 | 328 | int libs[MAXLIBS]; |
| 328 | 329 | int liberties; |
| | 330 | int *cur_lib, *last_lib; |
| 329 | 331 | int pos; |
| 330 | | int k, r; |
| | 332 | int k; |
| 331 | 333 | int moves_played; |
| 332 | 334 | int potential_sekis[BOARDMAX]; |
| 333 | 335 | int none_invincible; |
| … |
… |
|
| 345 | 347 | int stones[2]; |
| 346 | 348 | int pos2; |
| 347 | 349 | int checked_stone; |
| | 350 | const int *cur_delta, *last_delta; |
| 348 | 351 | |
| 349 | 352 | if (board[pos] != color |
| 350 | 353 | || find_origin(pos) != pos |
| … |
… |
|
| 354 | 357 | findstones(pos, 2, stones); |
| 355 | 358 | for (k = 0; k < 2 && isolated; k++) { |
| 356 | 359 | checked_stone = stones[k]; |
| 357 | | for (r = 0; r < 8; r++) { |
| 358 | | pos2 = checked_stone + delta[r]; |
| | 360 | cur_delta = delta; |
| | 361 | last_delta = cur_delta + 8; |
| | 362 | for (; cur_delta < last_delta; cur_delta++) { |
| | 363 | pos2 = checked_stone + *cur_delta; |
| 359 | 364 | if (!ON_BOARD(pos2) |
| 360 | 365 | || (board[pos2] == color |
| 361 | 366 | && !same_string(pos, pos2))) |
| … |
… |
|
| 399 | 404 | continue; |
| 400 | 405 | |
| 401 | 406 | /* Play as many liberties as we can. */ |
| 402 | | liberties = findlib(pos, MAXLIBS, libs); |
| 403 | | for (k = 0; k < liberties; k++) { |
| 404 | | moves_played += trymove(libs[k], other, "unconditional_life", pos); |
| | 407 | cur_lib = libs; |
| | 408 | last_lib = cur_lib + findlib(pos, MAXLIBS, libs); |
| | 409 | for (; cur_lib < last_lib; cur_lib++) { |
| | 410 | moves_played += trymove(*cur_lib, other, "unconditional_life", pos); |
| 405 | 411 | } |
| 406 | 412 | } |
| 407 | 413 | |
| … |
… |
|
| 424 | 430 | |
| 425 | 431 | /* Now see whether there are any significant sekis on the board. */ |
| 426 | 432 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| | 433 | int r; |
| 427 | 434 | if (!potential_sekis[pos] |
| 428 | 435 | || board[pos] == EMPTY |
| 429 | 436 | || find_origin(pos) != pos) |
| … |
… |
|
| 478 | 485 | if (!potential_sekis[pos] || board[pos] == EMPTY) |
| 479 | 486 | continue; |
| 480 | 487 | /* Play as many liberties as we can. */ |
| 481 | | liberties = findlib(pos, MAXLIBS, libs); |
| 482 | | for (k = 0; k < liberties; k++) |
| 483 | | moves_played += trymove(libs[k], other, "unconditional_life", pos); |
| | 488 | cur_lib = libs; |
| | 489 | last_lib = cur_lib + findlib(pos, MAXLIBS, libs); |
| | 490 | for (; cur_lib < last_lib; cur_lib++) |
| | 491 | moves_played += trymove(*cur_lib, other, "unconditional_life", pos); |
| 484 | 492 | } |
| 485 | 493 | |
| 486 | 494 | /* All opponent strings liberties are now inside opponent territory |
diff -N -r -u -X .ignore gnugo-copy/engine/worm.c gnugo/engine/worm.c
|
old
|
new
|
|
| 102 | 102 | |
| 103 | 103 | gg_assert(stackp == 0); |
| 104 | 104 | |
| 105 | | /* Count liberties of different orders and initialize cutstone fields. */ |
| | 105 | /* Count liberties of different orders. */ |
| 106 | 106 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| | 107 | int lib1; |
| 107 | 108 | if (IS_STONE(board[pos]) && is_worm_origin(pos, pos)) { |
| 108 | | int lib1, lib2, lib3, lib4; |
| 109 | | |
| 110 | | ping_cave(pos, &lib1, &lib2, &lib3, &lib4); |
| | 109 | ping_cave(pos, &lib1, &worm[pos].liberties2, &worm[pos].liberties3, |
| | 110 | &worm[pos].liberties4); |
| 111 | 111 | ASSERT1(worm[pos].liberties == lib1, pos); |
| 112 | | worm[pos].liberties2 = lib2; |
| 113 | | worm[pos].liberties3 = lib3; |
| 114 | | worm[pos].liberties4 = lib4; |
| 115 | | worm[pos].cutstone = 0; |
| 116 | | worm[pos].cutstone2 = 0; |
| 117 | 112 | propagate_worm(pos); |
| 118 | 113 | } |
| 119 | 114 | } |
| … |
… |
|
| 745 | 740 | find_worm_attacks_and_defenses() |
| 746 | 741 | { |
| 747 | 742 | int str; |
| 748 | | int k; |
| 749 | 743 | int acode, dcode; |
| 750 | 744 | int attack_point; |
| 751 | 745 | int defense_point; |
| 752 | 746 | static int libs[MAXLIBS]; |
| 753 | | int liberties; |
| 754 | 747 | int color; |
| 755 | 748 | int other; |
| | 749 | int pos; |
| 756 | 750 | |
| 757 | 751 | /* 1. Start with finding attack points. */ |
| 758 | 752 | for (str = BOARDMIN; str < BOARDMAX; str++) { |
| … |
… |
|
| 779 | 773 | if (!IS_STONE(board[str]) || !is_worm_origin(str, str)) |
| 780 | 774 | continue; |
| 781 | 775 | |
| 782 | | if (worm[str].attack_codes[0] != 0) { |
| | 776 | if (worm[str].attack_codes[0]) { |
| 783 | 777 | |
| 784 | 778 | TRACE("considering defense of %1m\n", str); |
| 785 | 779 | dcode = find_defense(str, &defense_point); |
| 786 | | if (dcode != 0) { |
| | 780 | if (dcode) { |
| 787 | 781 | TRACE("worm at %1m can be defended at %1m\n", str, defense_point); |
| 788 | 782 | if (defense_point != NO_MOVE) |
| 789 | 783 | change_defense(str, defense_point, dcode); |
| … |
… |
|
| 815 | 809 | |
| 816 | 810 | /* |
| 817 | 811 | * 5. Find additional attacks and defenses by testing all immediate |
| 818 | | * liberties. Further attacks and defenses are found by pattern |
| 819 | | * matching and by trying whether each attack or defense point |
| 820 | | * attacks or defends other strings. |
| | 812 | * liberties. |
| 821 | 813 | */ |
| 822 | 814 | for (str = BOARDMIN; str < BOARDMAX; str++) { |
| 823 | | color = board[str]; |
| 824 | | if (!IS_STONE(color) || !is_worm_origin(str, str)) |
| | 815 | int *cur_lib, *last_lib; |
| | 816 | if (!IS_STONE(board[str]) || !is_worm_origin(str, str) |
| | 817 | || !worm[str].attack_codes[0]) |
| 825 | 818 | continue; |
| 826 | | |
| | 819 | |
| | 820 | color = board[str]; |
| 827 | 821 | other = OTHER_COLOR(color); |
| 828 | 822 | |
| 829 | | if (worm[str].attack_codes[0] == 0) |
| 830 | | continue; |
| 831 | | |
| 832 | 823 | /* There is at least one attack on this group. Try the |
| 833 | 824 | * liberties. |
| 834 | 825 | */ |
| 835 | | liberties = findlib(str, MAXLIBS, libs); |
| | 826 | cur_lib = libs; |
| | 827 | last_lib = cur_lib + findlib(str, MAXLIBS, libs); |
| 836 | 828 | |
| 837 | | for (k = 0; k < liberties; k++) { |
| 838 | | int pos = libs[k]; |
| 839 | | if (!attack_move_known(pos, str)) { |
| | 829 | for (; cur_lib < last_lib; cur_lib++) { |
| | 830 | pos = *cur_lib; |
| | 831 | if (!attack_move_known(pos, str) |
| | 832 | && !discarded_move_known(pos, MAX_TACTICAL_POINTS, |
| | 833 | worm[str].discarded_attacks)) { |
| 840 | 834 | /* Try to attack on the liberty. Don't consider |
| 841 | 835 | * send-two-return-one moves. |
| 842 | 836 | */ |
| … |
… |
|
| 855 | 849 | } |
| 856 | 850 | } |
| 857 | 851 | /* Try to defend at the liberty. */ |
| 858 | | if (!defense_move_known(pos, str)) { |
| 859 | | if (worm[str].defense_codes[0] != 0) |
| 860 | | if (trymove(pos, color, "make_worms", NO_MOVE)) { |
| | 852 | if (worm[str].defense_codes[0] && !defense_move_known(pos, str) |
| | 853 | && !discarded_move_known(pos, MAX_TACTICAL_POINTS, |
| | 854 | worm[str].discarded_defenses)) { |
| | 855 | if (trymove(pos, color, "make_worms", NO_MOVE)) { |
| | 856 | if (countlib(pos) > 1) { |
| 861 | 857 | acode = attack(str, NULL); |
| 862 | 858 | if (acode != WIN) |
| 863 | 859 | change_defense(str, pos, REVERSE_RESULT(acode)); |
| 864 | | popgo(); |
| 865 | 860 | } |
| | 861 | popgo(); |
| | 862 | } |
| 866 | 863 | } |
| 867 | 864 | } |
| 868 | 865 | } |
| … |
… |
|
| 1215 | 1212 | void |
| 1216 | 1213 | propagate_worm(int pos) |
| 1217 | 1214 | { |
| 1218 | | int k; |
| 1219 | | int num_stones; |
| | 1215 | int *cur_stone, *last_stone; |
| 1220 | 1216 | int stones[MAX_BOARD * MAX_BOARD]; |
| 1221 | 1217 | gg_assert(stackp == 0); |
| 1222 | 1218 | ASSERT1(IS_STONE(board[pos]), pos); |
| 1223 | 1219 | |
| 1224 | | num_stones = findstones(pos, MAX_BOARD * MAX_BOARD, stones); |
| 1225 | | for (k = 0; k < num_stones; k++) |
| 1226 | | if (stones[k] != pos) |
| 1227 | | memcpy(worm + stones[k], worm + pos, sizeof(struct worm_data)); |
| | 1220 | cur_stone = stones; |
| | 1221 | last_stone = cur_stone + findstones(pos, MAX_BOARD * MAX_BOARD, stones); |
| | 1222 | for (; cur_stone < last_stone; cur_stone++) |
| | 1223 | if (*cur_stone != pos) |
| | 1224 | memcpy(worm + (*cur_stone), worm + pos, sizeof(struct worm_data)); |
| 1228 | 1225 | } |
| 1229 | 1226 | |
| 1230 | 1227 | |
| … |
… |
|
| 1576 | 1573 | void *data) |
| 1577 | 1574 | { |
| 1578 | 1575 | int move; |
| 1579 | | int k; |
| | 1576 | struct patval *cur_el, *last_el; |
| 1580 | 1577 | UNUSED(data); |
| 1581 | 1578 | |
| 1582 | 1579 | gg_assert(stackp==0); |
| … |
… |
|
| 1604 | 1601 | } |
| 1605 | 1602 | |
| 1606 | 1603 | /* Loop through pattern elements in search of X strings to attack. */ |
| 1607 | | for (k = 0; k < pattern->patlen; ++k) { /* match each point */ |
| 1608 | | if (pattern->patn[k].att == ATT_X) { |
| | 1604 | cur_el = pattern->patn; |
| | 1605 | last_el = cur_el + pattern->patlen; |
| | 1606 | for (; cur_el < last_el; ++cur_el) { /* match each point */ |
| | 1607 | if (cur_el->att == ATT_X) { |
| 1609 | 1608 | /* transform pattern real coordinate */ |
| 1610 | | int pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor); |
| | 1609 | int pos = AFFINE_TRANSFORM(cur_el->offset, ll, anchor); |
| 1611 | 1610 | |
| 1612 | 1611 | int str = worm[pos].origin; |
| 1613 | 1612 | |
| … |
… |
|
| 1672 | 1671 | void *data) |
| 1673 | 1672 | { |
| 1674 | 1673 | int move; |
| 1675 | | int k; |
| | 1674 | struct patval *cur_el, *last_el; |
| 1676 | 1675 | UNUSED(data); |
| 1677 | 1676 | |
| 1678 | 1677 | gg_assert(stackp==0); |
| … |
… |
|
| 1700 | 1699 | } |
| 1701 | 1700 | |
| 1702 | 1701 | /* Loop through pattern elements in search for O strings to defend. */ |
| 1703 | | for (k = 0; k < pattern->patlen; ++k) { /* match each point */ |
| 1704 | | if (pattern->patn[k].att == ATT_O) { |
| | 1702 | cur_el = pattern->patn; |
| | 1703 | last_el = cur_el + pattern->patlen; |
| | 1704 | for (; cur_el < last_el; ++cur_el) { /* match each point */ |
| | 1705 | if (cur_el->att == ATT_O) { |
| 1705 | 1706 | /* transform pattern real coordinate */ |
| 1706 | | int pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor); |
| | 1707 | int pos = AFFINE_TRANSFORM(cur_el->offset, ll, anchor); |
| 1707 | 1708 | int str = worm[pos].origin; |
| 1708 | 1709 | |
| 1709 | 1710 | if (worm[str].attack_codes[0] == 0 |