197 |
* size of the smallest of the worms under attack. |
* size of the smallest of the worms under attack. |
198 |
*/ |
*/ |
199 |
|
|
200 |
#define USE_ATARI_ATARI_PATTERNS 0 |
#define USE_ATARI_ATARI_PATTERNS 1 |
201 |
|
|
202 |
static int aa_status[BOARDMAX]; /* ALIVE, DEAD or CRITICAL */ |
static int aa_status[BOARDMAX]; /* ALIVE, DEAD or CRITICAL */ |
203 |
static int forbidden[BOARDMAX]; |
static int forbidden[BOARDMAX]; |
246 |
*/ |
*/ |
247 |
while (1) { |
while (1) { |
248 |
int new_aa_val; |
int new_aa_val; |
249 |
|
|
250 |
|
if (attack_move) |
251 |
|
*attack_move = apos; |
252 |
|
if (defense_move) |
253 |
|
*defense_move = dpos; |
254 |
|
|
255 |
forbidden[apos] = 1; |
forbidden[apos] = 1; |
256 |
new_aa_val = do_atari_atari(color, &apos, &dpos, NO_MOVE, |
new_aa_val = do_atari_atari(color, &apos, &dpos, NO_MOVE, |
257 |
save_verbose, aa_val); |
save_verbose, aa_val); |
260 |
* it does not change the value of (apos), so these correspond |
* it does not change the value of (apos), so these correspond |
261 |
* to a move that works and is necessary. |
* to a move that works and is necessary. |
262 |
*/ |
*/ |
263 |
if (new_aa_val == 0) { |
if (new_aa_val == 0) |
|
if (attack_move) |
|
|
*attack_move = apos; |
|
|
if (defense_move) |
|
|
*defense_move = dpos; |
|
264 |
return aa_val; |
return aa_val; |
265 |
} |
else |
266 |
aa_val = new_aa_val; |
aa_val = new_aa_val; |
267 |
} |
} |
268 |
|
|
269 |
/* We'll never get here, but the compiler may be more happy if it |
/* We'll never get here, but the compiler may be more happy if it |
601 |
last_friendly, save_verbose, minsize); |
last_friendly, save_verbose, minsize); |
602 |
sgf_dumptree = save_sgf_dumptree; |
sgf_dumptree = save_sgf_dumptree; |
603 |
count_variations = save_count_variations; |
count_variations = save_count_variations; |
604 |
if (retval != 0) |
if (retval != 0) { |
605 |
|
if (sgf_dumptree) |
606 |
|
/* FIXME: Better message. */ |
607 |
|
sgftreeAddComment(sgf_dumptree, NULL, "attack found"); |
608 |
return retval; |
return retval; |
609 |
|
} |
610 |
} |
} |
611 |
|
|
612 |
if (stackp > aa_depth) |
if (stackp > aa_depth) |
679 |
continue; |
continue; |
680 |
|
|
681 |
/* atari_atari successful */ |
/* atari_atari successful */ |
682 |
if (num_defense_moves == 0 |
if (num_defense_moves == 0) { |
683 |
&& (save_verbose || (debug & DEBUG_ATARI_ATARI))) { |
if (save_verbose || (debug & DEBUG_ATARI_ATARI)) { |
684 |
gprintf("%oThe worm %1m can be attacked at %1m after ", str, apos); |
gprintf("%oThe worm %1m can be attacked at %1m after ", str, apos); |
685 |
dump_stack(); |
dump_stack(); |
686 |
|
} |
687 |
|
if (sgf_dumptree) |
688 |
|
/* FIXME: Better message. */ |
689 |
|
sgftreeAddComment(sgf_dumptree, NULL, "attack found"); |
690 |
} |
} |
691 |
|
|
692 |
if (attack_point) |
if (attack_point) |
806 |
int mx[BOARDMAX]; |
int mx[BOARDMAX]; |
807 |
|
|
808 |
if (USE_ATARI_ATARI_PATTERNS) |
if (USE_ATARI_ATARI_PATTERNS) |
809 |
return atari_atari_attack_patterns(color, minsize, moves, targets); |
num_moves = atari_atari_attack_patterns(color, minsize, moves, targets); |
810 |
|
else { |
811 |
/* We set mx to 0 for every move added to the moves[] array. */ |
/* We set mx to 0 for every move added to the moves[] array. */ |
812 |
memset(mx, 0, sizeof(mx)); |
memset(mx, 0, sizeof(mx)); |
|
|
|
|
for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
|
|
if (board[pos] != other) |
|
|
continue; |
|
813 |
|
|
814 |
if (pos != find_origin(pos)) |
for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
815 |
continue; |
if (board[pos] != other) |
816 |
|
continue; |
817 |
|
|
818 |
if (minsize > 0 && countstones(pos) < minsize && !is_vital_string(pos)) |
if (pos != find_origin(pos)) |
|
continue; |
|
|
|
|
|
if (get_aa_status(pos) != ALIVE) |
|
|
continue; |
|
|
|
|
|
/* Pick up general threat moves or simple ataris. */ |
|
|
if (stackp < aa_threat_depth) { |
|
|
memset(threat_moves, 0, sizeof(threat_moves)); |
|
|
memset(threat_codes, 0, sizeof(threat_codes)); |
|
|
num_threat_moves = attack_threats(pos, MAX_THREAT_MOVES, |
|
|
threat_moves, threat_codes); |
|
|
if ((debug & DEBUG_ATARI_ATARI) |
|
|
&& num_moves > 0) { |
|
|
int i; |
|
|
gprintf("Threats on %1m: ", pos); |
|
|
for (i = 0; i < num_moves; i++) |
|
|
gprintf("%1m ", moves[i]); |
|
|
gprintf("\n"); |
|
|
} |
|
|
} |
|
|
else { |
|
|
num_threat_moves = findlib(pos, 2, threat_moves); |
|
|
if (num_threat_moves != 2) |
|
819 |
continue; |
continue; |
820 |
} |
|
821 |
|
if (minsize > 0 && countstones(pos) < minsize && !is_vital_string(pos)) |
|
/* Add the threats on (pos) to the moves[] array, unless forbidden |
|
|
* or assumed to be ineffective. |
|
|
*/ |
|
|
for (k = 0; k < num_threat_moves; k++) { |
|
|
int move = threat_moves[k]; |
|
|
|
|
|
if (mx[move] != 0 || forbidden[move]) |
|
822 |
continue; |
continue; |
823 |
|
|
824 |
if ((is_self_atari(move, color) |
if (get_aa_status(pos) != ALIVE) |
|
|| !is_atari(move, color)) |
|
|
&& !safe_move(move, color)) |
|
825 |
continue; |
continue; |
826 |
|
|
827 |
moves[num_moves] = move; |
/* Pick up general threat moves or simple ataris. */ |
828 |
targets[num_moves] = pos; |
if (stackp < aa_threat_depth) { |
829 |
num_moves++; |
memset(threat_moves, 0, sizeof(threat_moves)); |
830 |
mx[move] = 1; |
memset(threat_codes, 0, sizeof(threat_codes)); |
831 |
|
num_threat_moves = attack_threats(pos, MAX_THREAT_MOVES, |
832 |
|
threat_moves, threat_codes); |
833 |
|
if ((debug & DEBUG_ATARI_ATARI) |
834 |
|
&& num_threat_moves > 0) { |
835 |
|
int i; |
836 |
|
gprintf("Threats on %1m: ", pos); |
837 |
|
for (i = 0; i < num_threat_moves; i++) |
838 |
|
gprintf("%1m ", threat_moves[i]); |
839 |
|
gprintf("\n"); |
840 |
|
} |
841 |
|
} |
842 |
|
else { |
843 |
|
num_threat_moves = findlib(pos, 2, threat_moves); |
844 |
|
if (num_threat_moves != 2) |
845 |
|
continue; |
846 |
|
} |
847 |
|
|
848 |
|
/* Add the threats on (pos) to the moves[] array, unless forbidden |
849 |
|
* or assumed to be ineffective. |
850 |
|
*/ |
851 |
|
for (k = 0; k < num_threat_moves; k++) { |
852 |
|
int move = threat_moves[k]; |
853 |
|
|
854 |
|
if (mx[move] != 0 || forbidden[move]) |
855 |
|
continue; |
856 |
|
|
857 |
|
if ((is_self_atari(move, color) |
858 |
|
|| !is_atari(move, color)) |
859 |
|
&& !safe_move(move, color)) |
860 |
|
continue; |
861 |
|
|
862 |
|
moves[num_moves] = move; |
863 |
|
targets[num_moves] = pos; |
864 |
|
num_moves++; |
865 |
|
mx[move] = 1; |
866 |
|
} |
867 |
} |
} |
868 |
} |
} |
869 |
|
|
870 |
|
if (debug & DEBUG_ATARI_ATARI) { |
871 |
|
gprintf("Attack moves:"); |
872 |
|
for (k = 0; k < num_moves; k++) |
873 |
|
gprintf("%o %1m(%1m)", moves[k], targets[k]); |
874 |
|
gprintf("%o\n"); |
875 |
|
} |
876 |
|
|
877 |
return num_moves; |
return num_moves; |
878 |
} |
} |
879 |
|
|
1060 |
} |
} |
1061 |
#endif |
#endif |
1062 |
|
|
1063 |
if (0) { |
if (debug & DEBUG_ATARI_ATARI) { |
1064 |
gprintf("defense moves for %1m:", str); |
gprintf("Defense moves for %1m:", str); |
1065 |
for (k = 0; k < num_moves; k++) |
for (k = 0; k < num_moves; k++) |
1066 |
gprintf("%o %1m", moves[k]); |
gprintf("%o %1m", moves[k]); |
1067 |
gprintf("\n"); |
gprintf("%o\n"); |
1068 |
} |
} |
1069 |
|
|
1070 |
return num_moves; |
return num_moves; |