Commit | Line | Data |
---|---|---|
7eeb782e AT |
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ |
2 | * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see * | |
3 | * http://www.gnu.org/software/gnugo/ for more information. * | |
4 | * * | |
5 | * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * | |
6 | * 2008 and 2009 by the Free Software Foundation. * | |
7 | * * | |
8 | * This program is free software; you can redistribute it and/or * | |
9 | * modify it under the terms of the GNU General Public License as * | |
10 | * published by the Free Software Foundation - version 3 or * | |
11 | * (at your option) any later version. * | |
12 | * * | |
13 | * This program is distributed in the hope that it will be useful, * | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
16 | * GNU General Public License in file COPYING for more details. * | |
17 | * * | |
18 | * You should have received a copy of the GNU General Public * | |
19 | * License along with this program; if not, write to the Free * | |
20 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * | |
21 | * Boston, MA 02111, USA. * | |
22 | \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
23 | ||
24 | /* ================================================================ */ | |
25 | /* Show status for a string, a dragon, etc in an SGF file. */ | |
26 | /* ================================================================ */ | |
27 | ||
28 | #include "gnugo.h" | |
29 | ||
30 | #include <stdio.h> | |
31 | #include <string.h> | |
32 | ||
33 | #include "liberty.h" | |
34 | #include "sgftree.h" | |
35 | ||
36 | ||
37 | /* | |
38 | * decide_string tries to attack and defend the string at (pos), | |
39 | * and then writes the number of variations considered in the attack | |
40 | * and defence to the sgf file. | |
41 | */ | |
42 | ||
43 | void | |
44 | decide_string(int pos) | |
45 | { | |
46 | int aa, dd; | |
47 | int acode, dcode; | |
48 | SGFTree tree; | |
49 | ||
50 | if (board[pos] == EMPTY) { | |
51 | fprintf(stderr, "gnugo: --decide-string called on an empty vertex\n"); | |
52 | return; | |
53 | } | |
54 | ||
55 | if (*outfilename) | |
56 | sgffile_begindump(&tree); | |
57 | ||
58 | /* Prepare pattern matcher and reading code. */ | |
59 | reset_engine(); | |
60 | ||
61 | count_variations = 1; | |
62 | acode = attack(pos, &aa); | |
63 | if (acode) { | |
64 | if (acode == WIN) | |
65 | gprintf("%1m can be attacked at %1m (%d variations)\n", | |
66 | pos, aa, count_variations); | |
67 | else if (acode == KO_A) | |
68 | gprintf("%1m can be attacked with ko (good) at %1m (%d variations)\n", | |
69 | pos, aa, count_variations); | |
70 | else if (acode == KO_B) | |
71 | gprintf("%1m can be attacked with ko (bad) at %1m (%d variations)\n", | |
72 | pos, aa, count_variations); | |
73 | ||
74 | if (debug & DEBUG_READING_PERFORMANCE) { | |
75 | gprintf("Reading shadow: \n"); | |
76 | draw_reading_shadow(); | |
77 | } | |
78 | ||
79 | count_variations = 1; | |
80 | dcode = find_defense(pos, &dd); | |
81 | if (dcode) { | |
82 | if (dcode == WIN) | |
83 | gprintf("%1m can be defended at %1m (%d variations)\n", | |
84 | pos, dd, count_variations); | |
85 | else if (dcode == KO_A) | |
86 | gprintf("%1m can be defended with ko (good) at %1m (%d variations)\n", | |
87 | pos, dd, count_variations); | |
88 | else if (dcode == KO_B) | |
89 | gprintf("%1m can be defended with ko (bad) at %1m (%d variations)\n", | |
90 | pos, dd, count_variations); | |
91 | } | |
92 | else | |
93 | gprintf("%1m cannot be defended (%d variations)\n", | |
94 | pos, count_variations); | |
95 | if (debug & DEBUG_READING_PERFORMANCE) { | |
96 | gprintf("Reading shadow: \n"); | |
97 | draw_reading_shadow(); | |
98 | } | |
99 | ||
100 | } | |
101 | else { | |
102 | gprintf("%1m cannot be attacked (%d variations)\n", | |
103 | pos, count_variations); | |
104 | if (debug & DEBUG_READING_PERFORMANCE) { | |
105 | gprintf("Reading shadow: \n"); | |
106 | draw_reading_shadow(); | |
107 | } | |
108 | } | |
109 | ||
110 | sgffile_enddump(outfilename); | |
111 | count_variations = 0; | |
112 | } | |
113 | ||
114 | ||
115 | /* | |
116 | * decide_connection tries to connect and disconnect the strings at | |
117 | * (apos) and (bpos), and then writes the number of variations | |
118 | * considered in the attack and defence to the sgf file. | |
119 | */ | |
120 | ||
121 | void | |
122 | decide_connection(int apos, int bpos) | |
123 | { | |
124 | int move; | |
125 | int result; | |
126 | SGFTree tree; | |
127 | ||
128 | ASSERT_ON_BOARD1(apos); | |
129 | ASSERT_ON_BOARD1(bpos); | |
130 | ||
131 | if (board[apos] == EMPTY || board[bpos] == EMPTY) { | |
132 | fprintf(stderr, "gnugo: --decide-connection called on an empty vertex\n"); | |
133 | return; | |
134 | } | |
135 | ||
136 | if (board[apos] != board[bpos]) { | |
137 | fprintf(stderr, "gnugo: --decide-connection called for strings of different colors\n"); | |
138 | return; | |
139 | } | |
140 | ||
141 | if (*outfilename) | |
142 | sgffile_begindump(&tree); | |
143 | ||
144 | /* Prepare pattern matcher and reading code. */ | |
145 | reset_engine(); | |
146 | ||
147 | count_variations = 1; | |
148 | result = string_connect(apos, bpos, &move); | |
149 | if (result == WIN) { | |
150 | if (move == NO_MOVE) | |
151 | gprintf("%1m and %1m are connected as it stands (%d variations)\n", | |
152 | apos, bpos, count_variations); | |
153 | else | |
154 | gprintf("%1m and %1m can be connected at %1m (%d variations)\n", | |
155 | apos, bpos, move, count_variations); | |
156 | } | |
157 | else if (result == KO_A) | |
158 | gprintf("%1m and %1m can be connected with ko (good) at %1m (%d variations)\n", | |
159 | apos, bpos, move, count_variations); | |
160 | else if (result == KO_B) | |
161 | gprintf("%1m and %1m can be connected with ko (bad) at %1m (%d variations)\n", | |
162 | apos, bpos, move, count_variations); | |
163 | else | |
164 | gprintf("%1m and %1m cannot be connected (%d variations)\n", | |
165 | apos, bpos, count_variations); | |
166 | ||
167 | count_variations = 1; | |
168 | result = disconnect(apos, bpos, &move); | |
169 | if (result == WIN) { | |
170 | if (move == NO_MOVE) | |
171 | gprintf("%1m and %1m are disconnected as it stands (%d variations)\n", | |
172 | apos, bpos, count_variations); | |
173 | else | |
174 | gprintf("%1m and %1m can be disconnected at %1m (%d variations)\n", | |
175 | apos, bpos, move, count_variations); | |
176 | } | |
177 | else if (result == KO_A) | |
178 | gprintf("%1m and %1m can be disconnected with ko (good) at %1m (%d variations)\n", | |
179 | apos, bpos, move, count_variations); | |
180 | else if (result == KO_B) | |
181 | gprintf("%1m and %1m can be disconnected with ko (bad) at %1m (%d variations)\n", | |
182 | apos, bpos, move, count_variations); | |
183 | else | |
184 | gprintf("%1m and %1m cannot be disconnected (%d variations)\n", | |
185 | apos, bpos, count_variations); | |
186 | ||
187 | sgffile_enddump(outfilename); | |
188 | count_variations = 0; | |
189 | } | |
190 | ||
191 | ||
192 | /* | |
193 | * decide_owl (formerly called decide_dragon) tries to attack and defend | |
194 | * the dragon at (pos), and then writes the number of variations considered | |
195 | * in the attack and defence to the sgf file. | |
196 | */ | |
197 | ||
198 | void | |
199 | decide_owl(int pos) | |
200 | { | |
201 | int move = NO_MOVE; | |
202 | int acode, dcode; | |
203 | SGFTree tree; | |
204 | int result_certain; | |
205 | int kworm; | |
206 | ||
207 | if (board[pos] == EMPTY) { | |
208 | fprintf(stderr, "gnugo: --decide-dragon called on an empty vertex\n"); | |
209 | return; | |
210 | } | |
211 | ||
212 | /* Prepare pattern matcher and reading code. */ | |
213 | reset_engine(); | |
214 | ||
215 | silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); | |
216 | gprintf("finished examine_position\n"); | |
217 | ||
218 | /* We want to see the reading performed, not just a result picked | |
219 | * from the cache. Thus we clear the cache here. | |
220 | */ | |
221 | reading_cache_clear(); | |
222 | ||
223 | if (*outfilename) | |
224 | sgffile_begindump(&tree); | |
225 | ||
226 | count_variations = 1; | |
227 | acode = owl_attack(pos, &move, &result_certain, &kworm); | |
228 | if (acode) { | |
229 | if (acode == WIN) { | |
230 | if (move == NO_MOVE) | |
231 | gprintf("%1m is dead as it stands", pos); | |
232 | else | |
233 | gprintf("%1m can be attacked at %1m (%d variations)", | |
234 | pos, move, count_variations); | |
235 | } | |
236 | else if (acode == KO_A) | |
237 | gprintf("%1m can be attacked with ko (good) at %1m (%d variations)", | |
238 | pos, move, count_variations); | |
239 | else if (acode == KO_B) | |
240 | gprintf("%1m can be attacked with ko (bad) at %1m (%d variations)", | |
241 | pos, move, count_variations); | |
242 | else if (acode == GAIN) | |
243 | gprintf("%1m can be attacked with gain (captures %1m) at %1m (%d variations)", | |
244 | pos, kworm, move, count_variations); | |
245 | } | |
246 | else | |
247 | gprintf("%1m cannot be attacked (%d variations)", pos, count_variations); | |
248 | ||
249 | if (result_certain) | |
250 | gprintf("\n"); | |
251 | else | |
252 | gprintf(" result uncertain\n"); | |
253 | ||
254 | reading_cache_clear(); | |
255 | count_variations = 1; | |
256 | dcode = owl_defend(pos, &move, &result_certain, &kworm); | |
257 | ||
258 | if (dcode) { | |
259 | if (dcode == WIN) { | |
260 | if (move == NO_MOVE) | |
261 | gprintf("%1m is alive as it stands", pos); | |
262 | else | |
263 | gprintf("%1m can be defended at %1m (%d variations)", | |
264 | pos, move, count_variations); | |
265 | } | |
266 | else if (dcode == KO_A) | |
267 | gprintf("%1m can be defended with ko (good) at %1m (%d variations)", | |
268 | pos, move, count_variations); | |
269 | else if (dcode == KO_B) | |
270 | gprintf("%1m can be defended with ko (bad) at %1m (%d variations)", | |
271 | pos, move, count_variations); | |
272 | else if (dcode == LOSS) | |
273 | gprintf("%1m can be defended with loss (loses %1m) at %1m (%d variations)", | |
274 | pos, kworm, move, count_variations); | |
275 | } | |
276 | else | |
277 | gprintf("%1m cannot be defended (%d variations)", | |
278 | pos, count_variations); | |
279 | ||
280 | if (result_certain) | |
281 | gprintf("\n"); | |
282 | else | |
283 | gprintf(" result uncertain\n"); | |
284 | ||
285 | sgffile_enddump(outfilename); | |
286 | count_variations = 0; | |
287 | } | |
288 | ||
289 | ||
290 | /* | |
291 | * decide_dragon_data prints the dragon data at (pos). | |
292 | */ | |
293 | ||
294 | void | |
295 | decide_dragon_data(int pos) | |
296 | { | |
297 | if (board[pos] == EMPTY) { | |
298 | fprintf(stderr, "gnugo: --decide-dragon-data called on an empty vertex\n"); | |
299 | return; | |
300 | } | |
301 | reset_engine(); | |
302 | silent_examine_position(FULL_EXAMINE_DRAGONS); | |
303 | ||
304 | gprintf("Dragon at %1m:\n", pos); | |
305 | report_dragon(stderr, pos); | |
306 | } | |
307 | ||
308 | ||
309 | /* Print the result of the semeai code on the semeai at apos/bpos, | |
310 | * optionally writing an sgf file. | |
311 | */ | |
312 | ||
313 | void | |
314 | decide_semeai(int apos, int bpos) | |
315 | { | |
316 | SGFTree tree; | |
317 | int resulta, resultb, move, result_certain; | |
318 | int color = board[apos]; | |
319 | ||
320 | if (color == EMPTY || board[bpos] != OTHER_COLOR(color)) { | |
321 | gprintf("gnugo: --decide-semeai called on invalid data\n"); | |
322 | return; | |
323 | } | |
324 | ||
325 | /* Prepare pattern matcher and reading code. */ | |
326 | reset_engine(); | |
327 | ||
328 | silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); | |
329 | gprintf("finished examine_position\n"); | |
330 | count_variations = 1; | |
331 | ||
332 | /* We want to see the reading performed, not just a result picked | |
333 | * from the cache. Thus we clear the cache here. */ | |
334 | reading_cache_clear(); | |
335 | ||
336 | if (*outfilename) | |
337 | sgffile_begindump(&tree); | |
338 | ||
339 | gprintf("Analyzing semeai between %1m and %1m, %C moves first\n", | |
340 | apos, bpos, board[apos]); | |
341 | owl_analyze_semeai(apos, bpos, &resulta, &resultb, &move, 1, | |
342 | &result_certain); | |
343 | gprintf("Semeai defense of %1m: result %s %1m\n", | |
344 | apos, result_to_string(resulta), move); | |
345 | gprintf("Semeai attack of %1m: result %s %1m\n", | |
346 | bpos, result_to_string(resultb), move); | |
347 | gprintf("%d nodes%s\n\n", count_variations, | |
348 | result_certain ? "" : ", uncertain result"); | |
349 | ||
350 | gprintf("Analyzing semeai between %1m and %1m, %C moves first\n", | |
351 | bpos, apos, board[bpos]); | |
352 | owl_analyze_semeai(bpos, apos, &resultb, &resulta, &move, 1, | |
353 | &result_certain); | |
354 | gprintf("Semeai defense of %1m: result %s %1m\n", | |
355 | bpos, result_to_string(resultb), move); | |
356 | gprintf("Semeai attack of %1m: result %s %1m\n", | |
357 | apos, result_to_string(resulta), move); | |
358 | gprintf("%d nodes%s\n", count_variations, | |
359 | result_certain ? "" : ", uncertain result"); | |
360 | ||
361 | sgffile_enddump(outfilename); | |
362 | count_variations = 0; | |
363 | } | |
364 | ||
365 | ||
366 | void | |
367 | decide_tactical_semeai(int apos, int bpos) | |
368 | { | |
369 | SGFTree tree; | |
370 | int resulta, resultb, move, dummy; | |
371 | int color = board[apos]; | |
372 | ||
373 | if (color == EMPTY || board[bpos] != OTHER_COLOR(color)) { | |
374 | gprintf("gnugo: --decide-semeai called on invalid data\n"); | |
375 | return; | |
376 | } | |
377 | ||
378 | /* Prepare pattern matcher and reading code. */ | |
379 | reset_engine(); | |
380 | ||
381 | silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); | |
382 | gprintf("finished examine_position\n"); | |
383 | count_variations = 1; | |
384 | ||
385 | /* We want to see the reading performed, not just a result picked | |
386 | * from the cache. Thus we clear the cache here. */ | |
387 | reading_cache_clear(); | |
388 | ||
389 | if (*outfilename) | |
390 | sgffile_begindump(&tree); | |
391 | ||
392 | /* FIXME: Calling status_to_string() with a result code as argument | |
393 | * doesn't make sense. It could be changed to result_to_string() but | |
394 | * the overall formatting needs change as well. | |
395 | */ | |
396 | owl_analyze_semeai(apos, bpos, &resulta, &resultb, &move, 0, &dummy); | |
397 | gprintf("After %s at %1m, %1m is %s, %1m is %s (%d nodes)\n", | |
398 | color_to_string(color), | |
399 | move, | |
400 | apos, status_to_string(resulta), | |
401 | bpos, status_to_string(resultb), | |
402 | count_variations); | |
403 | owl_analyze_semeai(bpos, apos, &resultb, &resulta, &move, 0, &dummy); | |
404 | gprintf("After %s at %1m, %1m is %s, %1m is %s (%d nodes)\n", | |
405 | color_to_string(color), | |
406 | move, | |
407 | apos, status_to_string(resulta), | |
408 | bpos, status_to_string(resultb), | |
409 | count_variations); | |
410 | ||
411 | sgffile_enddump(outfilename); | |
412 | count_variations = 0; | |
413 | } | |
414 | ||
415 | ||
416 | /* | |
417 | * decide_position tries to attack and defend every dragon with | |
418 | * dragon.escape<6 and writes the variations to an sgf file. | |
419 | */ | |
420 | ||
421 | void | |
422 | decide_position() | |
423 | { | |
424 | int pos; | |
425 | int move = NO_MOVE; | |
426 | int acode = 0, dcode = 0; | |
427 | int kworm; | |
428 | static const char *snames[] = {"dead", "alive", "critical", "unknown"}; | |
429 | SGFTree tree; | |
430 | ||
431 | /* Prepare pattern matcher and reading code. */ | |
432 | reset_engine(); | |
433 | ||
434 | silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); | |
435 | ||
436 | /* We want to see the reading performed, not just a result picked | |
437 | * from the cache. Thus we clear the cache here. */ | |
438 | reading_cache_clear(); | |
439 | ||
440 | if (*outfilename) | |
441 | sgffile_begindump(&tree); | |
442 | ||
443 | count_variations = 1; | |
444 | ||
445 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { | |
446 | if (!ON_BOARD(pos) | |
447 | || dragon[pos].origin != pos | |
448 | || board[pos] == EMPTY | |
449 | || DRAGON2(pos).escape_route >= 6) | |
450 | continue; | |
451 | ||
452 | gprintf("\nanalyzing %1m\n", pos); | |
453 | gprintf("status=%s, escape=%d\n", | |
454 | snames[dragon[pos].crude_status], DRAGON2(pos).escape_route); | |
455 | acode = owl_attack(pos, &move, NULL, &kworm); | |
456 | if (acode) { | |
457 | if (acode == WIN) { | |
458 | if (move == NO_MOVE) | |
459 | gprintf("%1m is dead as it stands\n", pos); | |
460 | else | |
461 | gprintf("%1m can be attacked at %1m (%d variations)\n", | |
462 | pos, move, count_variations); | |
463 | } | |
464 | else if (acode == KO_A) | |
465 | gprintf("%1m can be attacked with ko (good) at %1m (%d variations)\n", | |
466 | pos, move, count_variations); | |
467 | else if (acode == KO_B) | |
468 | gprintf("%1m can be attacked with ko (bad) at %1m (%d variations)\n", | |
469 | pos, move, count_variations); | |
470 | else if (acode == GAIN) | |
471 | gprintf("%1m can be attacked with gain (captures %1m) at %1m (%d variations)", | |
472 | pos, kworm, move, count_variations); | |
473 | ||
474 | count_variations = 1; | |
475 | dcode = owl_defend(pos, &move, NULL, &kworm); | |
476 | if (dcode) { | |
477 | if (dcode == WIN) { | |
478 | if (move == NO_MOVE) | |
479 | gprintf("%1m is alive as it stands\n", pos); | |
480 | else | |
481 | gprintf("%1m can be defended at %1m (%d variations)\n", | |
482 | pos, move, count_variations); | |
483 | } | |
484 | else if (dcode == KO_A) | |
485 | gprintf("%1m can be defended with ko (good) at %1m (%d variations)\n", | |
486 | pos, move, count_variations); | |
487 | else if (dcode == KO_B) | |
488 | gprintf("%1m can be defended with ko (bad) at %1m (%d variations)\n", | |
489 | pos, move, count_variations); | |
490 | else if (dcode == LOSS) | |
491 | gprintf("%1m can be defended with loss (loses %1m) at %1m (%d variations)", | |
492 | pos, kworm, move, count_variations); | |
493 | } | |
494 | else | |
495 | gprintf("%1m cannot be defended (%d variations)\n", | |
496 | pos, count_variations); | |
497 | } | |
498 | else | |
499 | gprintf("%1m cannot be attacked (%d variations)\n", | |
500 | pos, count_variations); | |
501 | ||
502 | if (acode) { | |
503 | if (dcode) | |
504 | gprintf("status of %1m revised to CRITICAL\n", pos); | |
505 | else | |
506 | gprintf("status of %1m revised to DEAD\n", pos); | |
507 | } | |
508 | else | |
509 | gprintf("status of %1m revised to ALIVE\n", pos); | |
510 | } | |
511 | ||
512 | sgffile_enddump(outfilename); | |
513 | count_variations = 0; | |
514 | } | |
515 | ||
516 | ||
517 | /* | |
518 | * Evaluates the eyespace at (pos) and prints a report. You can get | |
519 | * more information by adding -d0x02 to the command line. | |
520 | */ | |
521 | ||
522 | void | |
523 | decide_eye(int pos) | |
524 | { | |
525 | int color; | |
526 | struct eyevalue value; | |
527 | int attack_point; | |
528 | int defense_point; | |
529 | int eyepos; | |
530 | SGFTree tree; | |
531 | ||
532 | reset_engine(); | |
533 | silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); | |
534 | ||
535 | color = black_eye[pos].color; | |
536 | if (!IS_STONE(color)) { | |
537 | gprintf("The eye at %1m is not of a single color.\n", pos); | |
538 | return; | |
539 | } | |
540 | ||
541 | if (printboard) | |
542 | showboard(0); | |
543 | ||
544 | /* Enable sgf output. */ | |
545 | if (*outfilename) | |
546 | sgffile_begindump(&tree); | |
547 | count_variations = 1; | |
548 | ||
549 | if (black_eye[pos].color == BLACK) { | |
550 | eyepos = black_eye[pos].origin; | |
551 | compute_eyes(eyepos, &value, &attack_point, &defense_point, | |
552 | black_eye, half_eye, 0); | |
553 | gprintf("Black eyespace at %1m: %s\n", eyepos, eyevalue_to_string(&value)); | |
554 | if (eye_move_urgency(&value) > 0) { | |
555 | gprintf(" vital points: %1m (attack) %1m (defense)\n", attack_point, | |
556 | defense_point); | |
557 | } | |
558 | } | |
559 | ||
560 | if (white_eye[pos].color == WHITE) { | |
561 | eyepos = white_eye[pos].origin; | |
562 | compute_eyes(eyepos, &value, &attack_point, &defense_point, | |
563 | white_eye, half_eye, 0); | |
564 | gprintf("White eyespace at %1m: %s\n", eyepos, eyevalue_to_string(&value)); | |
565 | if (eye_move_urgency(&value) > 0) { | |
566 | gprintf(" vital points: %1m (attack) %1m (defense)\n", attack_point, | |
567 | defense_point); | |
568 | } | |
569 | } | |
570 | ||
571 | /* Finish sgf output. */ | |
572 | sgffile_enddump(outfilename); | |
573 | count_variations = 0; | |
574 | } | |
575 | ||
576 | ||
577 | /* | |
578 | * decide_combination tries to find a combination attack for (color) by | |
579 | * calling atari_atari(). | |
580 | */ | |
581 | ||
582 | void | |
583 | decide_combination(int color) | |
584 | { | |
585 | int attack_move; | |
586 | signed char defense_moves[BOARDMAX]; | |
587 | SGFTree tree; | |
588 | int first = 1; | |
589 | int pos; | |
590 | ||
591 | /* Prepare pattern matcher and reading code. */ | |
592 | reset_engine(); | |
593 | ||
594 | silent_examine_position(EXAMINE_ALL); | |
595 | ||
596 | if (*outfilename) | |
597 | sgffile_begindump(&tree); | |
598 | count_variations = 1; | |
599 | ||
600 | if (atari_atari(color, &attack_move, defense_moves, verbose)) { | |
601 | gprintf("Combination attack for %C at %1m, defense at ", color, | |
602 | attack_move); | |
603 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { | |
604 | if (ON_BOARD(pos) && defense_moves[pos]) { | |
605 | if (first) | |
606 | first = 0; | |
607 | else | |
608 | gprintf(", "); | |
609 | gprintf("%1m", pos); | |
610 | } | |
611 | } | |
612 | gprintf("\n"); | |
613 | } | |
614 | else | |
615 | gprintf("No Combination attack for %C\n", color); | |
616 | ||
617 | sgffile_enddump(outfilename); | |
618 | count_variations = 0; | |
619 | } | |
620 | ||
621 | ||
622 | void | |
623 | decide_surrounded(int pos) | |
624 | { | |
625 | int surround_status; | |
626 | ||
627 | if (board[pos] == EMPTY) { | |
628 | fprintf(stderr, "location must not be empty!\n"); | |
629 | return; | |
630 | } | |
631 | ||
632 | /* Prepare pattern matcher and reading code. */ | |
633 | reset_engine(); | |
634 | ||
635 | silent_examine_position(EXAMINE_ALL); | |
636 | surround_status = compute_surroundings(pos, NO_MOVE, 1, NULL); | |
637 | if (surround_status == 1) | |
638 | gprintf("the dragon at %1m is SURROUNDED!\n", pos); | |
639 | else if (surround_status == 2) | |
640 | gprintf("the dragon at %1m is WEAKLY SURROUNDED!\n", pos); | |
641 | else | |
642 | gprintf("the dragon at %1m is not surrounded.\n", pos); | |
643 | } | |
644 | ||
645 | ||
646 | #if ORACLE | |
647 | ||
648 | void | |
649 | decide_oracle(Gameinfo *gameinfo, char *infilename, char *untilstring) | |
650 | { | |
651 | SGFTree tree; | |
652 | ||
653 | reset_engine(); | |
654 | if (*outfilename) | |
655 | sgffile_begindump(&tree); | |
656 | ||
657 | count_variations = 1; | |
658 | summon_oracle(); | |
659 | oracle_loadsgf(infilename, untilstring); | |
660 | consult_oracle(gameinfo->to_move); | |
661 | sgffile_enddump(outfilename); | |
662 | dismiss_oracle(); | |
663 | count_variations = 0; | |
664 | } | |
665 | ||
666 | #endif | |
667 | ||
668 | ||
669 | /* | |
670 | * Local Variables: | |
671 | * tab-width: 8 | |
672 | * c-basic-offset: 2 | |
673 | * End: | |
674 | */ | |
675 |