[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] (finally) arend_1_23.1: ko threats check
From: |
Arend Bayer |
Subject: |
[gnugo-devel] (finally) arend_1_23.1: ko threats check |
Date: |
Sun, 27 Jan 2002 14:39:08 +0100 (CET) |
- reevaluate_ko_threats now makes checks
- pattern removed
I've spent a lot of time this week trying to figure out whether there
is a good way of dealing with the FAILs caused by --owl-threats. (Locally,
this is patch arend_1_23.h :-) ) I wasn't successful there, and so I
only submit a small patch with some probably uncontroversial changes
(although reevaluate ko threats definitely needs some more intelligent
handling of owl threats; I only took care of tactical threats).
The mode --owl-threats has two consequences (unless I missed s.th.):
It adds followup values for owl_attack threats, and it changes dragon
safety values. I tried to tweak with both of these evaluations (the first
one often has overlaps with strategic attacks, the second is a bit coarse
as a criterion). But all the changes I tried in dragon.c and
dragon_safety (in move_reasons.c) did not really produce a net gain.
However, both problems might be treated better with a more intelligent
evaluation of strategic effects of moves on dragons, which is on the
to-do-list as I understand.
Although I am not disagreeing with the decision to turn off --owl-threats
as default, I may point out that there are some quite urgent moves
missed in this mode, and which are really directly related to the
missing knowledge of OWL_ATTACK_THREATs; 13x3:37 is a typical example,
and there were a few (maybe 2 or 3) others in the regression; as usually
only bad moves make it into the regression test suites, I would expect a
little more in "real life" (where as in other situations the followup
values/change dragon safeties just shuffle a less-than-perfect valuation
a bit, sometimes producing better and sometimes worse moves).
So it might be worth trying to find a way to produce this useful
information at less time cost.
Arend
Index: engine/move_reasons.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.c,v
retrieving revision 1.64
diff -u -r1.64 move_reasons.c
--- engine/move_reasons.c 22 Jan 2002 14:57:04 -0000 1.64
+++ engine/move_reasons.c 27 Jan 2002 13:20:48 -0000
@@ -781,6 +781,40 @@
return num_strings;
}
+/* Report the biggest dragon that is owl-affected (possibily with ko)
+ * by a move at (pos).
+ */
+int
+get_biggest_owl_target(int pos)
+{
+ int k;
+ int biggest_target = -1;
+ float target_size = 0.0;
+ for (k = 0; k < MAX_REASONS; k++) {
+ int r = move[pos].reason[k];
+ if (r < 0)
+ break;
+
+ switch (move_reasons[r].type) {
+ case OWL_ATTACK_MOVE:
+ case OWL_ATTACK_MOVE_GOOD_KO:
+ case OWL_ATTACK_MOVE_BAD_KO:
+ case OWL_ATTACK_THREAT:
+ case OWL_DEFEND_MOVE:
+ case OWL_DEFEND_MOVE_GOOD_KO:
+ case OWL_DEFEND_MOVE_BAD_KO:
+ case OWL_DEFEND_THREAT:
+ case OWL_PREVENT_THREAT:
+ if (dragon[dragons[move_reasons[r].what]].effective_size
+ > target_size) {
+ biggest_target = move_reasons[r].what;
+ target_size = dragon[dragons[move_reasons[r].what]].effective_size;
+ }
+ }
+ }
+ return biggest_target;
+}
+
/*
* Add to the reasons for the move at (pos) that it connects the
* dragons at (dr1) and (dr2). Require that the dragons are
Index: engine/move_reasons.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.h,v
retrieving revision 1.13
diff -u -r1.13 move_reasons.h
--- engine/move_reasons.h 22 Jan 2002 14:57:04 -0000 1.13
+++ engine/move_reasons.h 27 Jan 2002 13:20:49 -0000
@@ -198,6 +198,7 @@
int defense_move_reason_known(int pos, int what);
int owl_attack_move_reason_known(int pos, int what);
int owl_defense_move_reason_known(int pos, int what);
+int get_biggest_owl_target(int pos);
int is_antisuji_move(int pos);
int move_connects_strings(int pos, int color);
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.8
diff -u -r1.8 value_moves.c
--- engine/value_moves.c 25 Jan 2002 07:36:54 -0000 1.8
+++ engine/value_moves.c 27 Jan 2002 13:21:00 -0000
@@ -2331,22 +2331,123 @@
* the opponent fills in the ko (or resolves it in another way.)
*/
static void
-reevaluate_ko_threats(void)
+reevaluate_ko_threats(int ko_move, int color)
{
+ int ko_stone;
+ int opp_ko_move;
int m, n;
int pos;
+ int k;
+ int type, what;
+ int threat_does_work = 0;
+ int ko_move_target;
+ float threat_size;
+ ko_move_target = get_biggest_owl_target(ko_move);
+
+ /* Find the ko stone. */
+ for (k = 0; k <= 3; k++) {
+ ko_stone = ko_move + delta[k];
+ if (ON_BOARD(ko_stone) && countlib(ko_stone))
+ break;
+ }
+
TRACE("Reevaluating ko threats.\n");
for (m = 0; m < board_size; m++)
for (n = 0; n < board_size; n++) {
pos = POS(m, n);
-
- if (move[pos].additional_ko_value > 0.0) {
+ if (pos == ko_move)
+ continue;
+ if (move[pos].additional_ko_value <= 0.0)
+ continue;
+
+ /* Otherwise we look for the biggest threat, and then check whether
+ * it still works after ko has been resolved.
+ */
+ threat_size = 0.0;
+ type = -1;
+ what = -1;
+ for (k = 0; k < MAX_REASONS; k++) {
+ int r = move[pos].reason[k];
+ if (r < 0)
+ break;
+ if (! (move_reasons[r].type & THREAT_BIT))
+ continue;
+ switch (move_reasons[r].type) {
+ case ATTACK_THREAT:
+ case DEFEND_THREAT:
+ if (worm[worms[move_reasons[r].what]].effective_size
+ > threat_size) {
+ threat_size = worm[worms[move_reasons[r].what]].effective_size;
+ type = move_reasons[r].type;
+ what = move_reasons[r].what;
+ }
+ break;
+ case OWL_ATTACK_THREAT:
+ case OWL_DEFEND_THREAT:
+ case SEMEAI_THREAT:
+ if (dragon[dragons[move_reasons[r].what]].effective_size
+ > threat_size) {
+ threat_size = dragon[dragons[move_reasons[r].what]]\
+ .effective_size;
+ type = move_reasons[r].type;
+ what = move_reasons[r].what;
+ }
+ break;
+ default:
+ /* This means probably someone has introduced a new threat type
+ * without adding the corresponding case above.
+ */
+ gg_assert(0);
+ break;
+ }
+ }
+ /* If there is no threat recorded, the followup value is probably
+ * contributed by a pattern. We can do nothing but accept this value.
+ * (although this does cause problems).
+ */
+ if (type == -1)
+ threat_does_work = 1;
+ else
+ if (trymove(pos, color, "reevaluate_ko_threats", ko_move,
+ EMPTY, ko_move)) {
+ if (!find_defense(ko_stone, &opp_ko_move))
+ threat_does_work = 1;
+ else {
+ if (trymove(opp_ko_move, OTHER_COLOR(color),
+ "reevaluate_ko_threats", ko_move, EMPTY, NO_MOVE)) {
+ switch (type) {
+ case ATTACK_THREAT:
+ threat_does_work = attack(worms[what], NULL);
+ break;
+ case DEFEND_THREAT:
+ threat_does_work = (board[worms[what]] != EMPTY
+ && find_defense(worms[what], NULL));
+ break;
+ case OWL_ATTACK_THREAT:
+ case OWL_DEFEND_THREAT:
+ /* Should we call do_owl_attack/defense here?
+ * Maybe too expensive? For the moment we just assume
+ * that the attack does not work if it concerns the
+ * same dragon as ko_move. (Can this really happen?)
+ */
+ threat_does_work = (ko_move_target != what);
+ }
+ popgo();
+ }
+ }
+ popgo();
+ }
+
+ if (threat_does_work) {
TRACE("%1m: %f + %f = %f\n", pos, move[pos].value,
move[pos].additional_ko_value,
move[pos].value + move[pos].additional_ko_value);
move[pos].value += move[pos].additional_ko_value;
}
+ else
+ DEBUG(DEBUG_MOVE_REASONS,
+ "%1m: no additional ko value (threat does not work as ko
threat)\n", pos);
}
}
@@ -2491,7 +2592,7 @@
*/
if (bestval > 0.0 && is_illegal_ko_capture(best_move, color)) {
TRACE("Move at %1m would be an illegal ko capture.\n", best_move);
- reevaluate_ko_threats();
+ reevaluate_ko_threats(best_move, color);
redistribute_points();
time_report(2, " reevaluate_ko_threats", NO_MOVE, 1.0);
ko_values_have_been_added = 1;
Index: patterns/patterns.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/patterns.db,v
retrieving revision 1.49
diff -u -r1.49 patterns.db
--- patterns/patterns.db 23 Jan 2002 19:12:36 -0000 1.49
+++ patterns/patterns.db 27 Jan 2002 13:21:17 -0000
@@ -12939,27 +12939,28 @@
#
######################################################################
-
-Pattern Reinforce101
-#FIXME: This should at least be contingent on being ahead.
-# see trevorc:1170
-
-oO? Eliminate aji
-.*X
-...
-...
----
-
-:8,O,value(5)
-
-oO?
-.*A
-...
-...
----
-
-; has_aji(A)
-
+# ab: I think this is well treated by our "attack dragon XX, although
+# it seems dead, as we are ahead"-policy.
+# Pattern Reinforce101
+# #FIXME: This should at least be contingent on being ahead.
+# # see trevorc:1170
+#
+# oO? Eliminate aji
+# .*X
+# ...
+# ...
+# ---
+#
+# :8,O,value(5)
+#
+# oO?
+# .*A
+# ...
+# ...
+# ---
+#
+# ; has_aji(A)
+#
Pattern Reinforce102
# This pattern should be contingent on being clearly ahead.
- [gnugo-devel] (finally) arend_1_23.1: ko threats check,
Arend Bayer <=