[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] arend_3_7.2b: Don't trust owl defense more than tactical a
From: |
Arend Bayer |
Subject: |
[gnugo-devel] arend_3_7.2b: Don't trust owl defense more than tactical analysis |
Date: |
Sat, 24 Aug 2002 14:13:38 +0200 (CEST) |
On Sat, 17 Aug 2002, Gunnar Farneback wrote:
> Arend wrote:
> > This patch changes the policy for OWL_DEFEND_MOVE(...) move reasons. Now
> > only those parts of the affected dragon are marked saved which are either
> > tactically stable or tactically defended by this move.
>
> Sounds like a good workaround for the owl weakness of not
> understanding the concept of losing tails. Of course not all such
> tails are lost tactically, but this should help reduce the effects. It
> may also help with certain cases of incorrect amalgamation of
> tactically unstable strings.
Yes, it's just a workaround. Once we teach the owl code to properly
handle connections, we will most likely also teach it about loosing
tails. Maybe this patch then becomes unnecessary.
> There may be some issues with owl and tactical results involving ko.
That's right and I try to address that in the revision of the patch
below. Basically, each worm either has to be
* tactically safe from the beginning, or
* has to have a defense move reason recorded, or
* has to be as least as safe tactically (taking ko results into account)
as the owl move reason claims.
This is still not 100% correct, but I don't think the remaining cases
are frequent enough to be worth worrying about.
> > Finally, I feel it would help to have a list of worms belonging to each
> > dragon.
>
> Also a good idea. I think we want to hide the data structure though,
> having an interface similar to
>
> for (w = first_dragon_worm(pos); w != NO_MOVE; w = next_dragon_worm(w)) {
> ...
> }
I agree.
Arend
Current breakage (CVS + patch):
No changes compared to arend_3_7.2 + gunnar_3_7.3
./regress.sh . reading.tst
171 unexpected PASS!
./regress.sh . rosebud.tst
1 unexpected PASS!
./regress.sh . lazarus.tst
5 unexpected FAIL: Correct 'R13', got 'N11'
14 unexpected FAIL: Correct 'Q15|T5|H5', got 'Q14'
./regress.sh . nicklas2.tst
2401 unexpected PASS!
./regress.sh . nicklas4.tst
1201 unexpected PASS!
./regress.sh . nngs.tst
600 unexpected PASS!
1910 unexpected PASS!
./regress.sh . global.tst
34 unexpected FAIL: Correct 'N6', got 'L6'
38 unexpected PASS!
./regress.sh . nngs2.tst
1 unexpected PASS!
60 unexpected PASS!
./regress.sh . century2002.tst
150 unexpected PASS!
./regress.sh . auto04.tst
7 unexpected PASS!
- new function mark_changed_dragon() in move_reasons.c
- only mark owl defended stones as safe if also sufficiently tactically safe
Index: engine/move_reasons.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.c,v
retrieving revision 1.89
diff -u -r1.89 move_reasons.c
--- engine/move_reasons.c 3 Jun 2002 15:00:59 -0000 1.89
+++ engine/move_reasons.c 24 Aug 2002 11:57:22 -0000
@@ -1427,6 +1427,87 @@
}
}
+/* This function marks all stones whose status is changed by an owl move
+ * reason according to the following rules:
+ * 1. For an owl attack, all stones belonging to the attacked dragon are
+ * marked as INFLUENCE_CAPTURED_STONE
+ * 2. For an owl defense, all stones belonging to the defended dragon are
+ * markes as INFLUENCE_SAVED_STONE if they are also sufficiently
+ * tactically stable.
+ *
+ * In effective_size, the sum of the effective size of the changed worms
+ * is returned (unless it is a NULL pointer).
+ */
+void
+mark_changed_dragon(int pos, int color, int affected_dragon,
+ int move_reason_type, char changed_stones[BOARDMAX],
+ float *effective_size)
+{
+ int ii;
+ char new_status = INFLUENCE_SAVED_STONE;
+ int result_to_beat = 0;
+
+ ASSERT1(board[pos] == EMPTY, pos);
+ ASSERT1(IS_STONE(board[affected_dragon]), pos);
+
+ if (effective_size != NULL)
+ *effective_size = 0.0;
+
+ switch (move_reason_type) {
+ case OWL_ATTACK_MOVE:
+ case OWL_ATTACK_MOVE_GOOD_KO:
+ case OWL_ATTACK_MOVE_BAD_KO:
+ ASSERT1(board[affected_dragon] == OTHER_COLOR(color), pos);
+ new_status = INFLUENCE_CAPTURED_STONE;
+ if (effective_size != NULL)
+ *effective_size = dragon[affected_dragon].effective_size;
+ break;
+ case OWL_DEFEND_MOVE:
+ ASSERT1(board[affected_dragon] == color, pos);
+ result_to_beat = WIN;
+ break;
+ case OWL_DEFEND_MOVE_GOOD_KO:
+ ASSERT1(board[affected_dragon] == color, pos);
+ result_to_beat = KO_A;
+ break;
+ case OWL_DEFEND_MOVE_BAD_KO:
+ ASSERT1(board[affected_dragon] == color, pos);
+ result_to_beat = KO_B;
+ break;
+ default:
+ /* mark_changed_dragon() called with invalid move reason. */
+ ASSERT1(0, pos);
+ }
+
+ for (ii = BOARDMIN; ii < BOARDMAX; ii++) {
+ if (board[ii] == board[affected_dragon]
+ && is_same_dragon(ii, affected_dragon)) {
+ if (new_status == INFLUENCE_CAPTURED_STONE)
+ changed_stones[ii] = new_status;
+ else if (worm[ii].origin == ii) {
+ int worm_is_safe = 0;
+ if (worm[ii].attack_codes[0] == NO_MOVE
+ || defense_move_reason_known(pos, find_worm(ii)))
+ worm_is_safe = 1;
+ else if (trymove(pos, color, "mark-changed-dragon", ii,
+ EMPTY, NO_MOVE)) {
+ if (REVERSE_RESULT(attack(ii, NULL)) >= result_to_beat)
+ worm_is_safe = 1;
+ popgo();
+ }
+ if (worm_is_safe) {
+ /* This string can now be considered safe. Hence we mark the
+ * whole string as such:
+ */
+ mark_string(ii, changed_stones, new_status);
+ if (effective_size != NULL)
+ *effective_size += worm[ii].effective_size;
+ }
+ }
+ }
+ }
+}
+
/* Find dragons rescued by a move at (pos). */
void
Index: engine/move_reasons.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.h,v
retrieving revision 1.21
diff -u -r1.21 move_reasons.h
--- engine/move_reasons.h 11 Aug 2002 12:13:02 -0000 1.21
+++ engine/move_reasons.h 24 Aug 2002 11:57:23 -0000
@@ -195,6 +195,9 @@
void discard_redundant_move_reasons(int pos);
void list_move_reasons(int color);
+void mark_changed_dragon(int pos, int color, int affected_dragon,
+ int move_reason_type, char changed_stones[BOARDMAX],
+ float *effective_size);
/*
* Local Variables:
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.48
diff -u -r1.48 value_moves.c
--- engine/value_moves.c 15 Aug 2002 19:59:39 -0000 1.48
+++ engine/value_moves.c 24 Aug 2002 11:57:35 -0000
@@ -585,6 +585,9 @@
case OWL_DEFEND_MOVE:
case OWL_DEFEND_MOVE_GOOD_KO:
case OWL_DEFEND_MOVE_BAD_KO:
+ /* FIXME: The above imply not necessarily a safe move, if the
+ * defending move is not connected to the dragon defended.
+ */
case MY_ATARI_ATARI_MOVE:
case EITHER_MOVE: /* FIXME: More advanced handling? */
case ALL_MOVE: /* FIXME: More advanced handling? */
@@ -1544,19 +1547,11 @@
break;
}
- {
- int ii;
- for (ii = BOARDMIN; ii < BOARDMAX; ii++) {
- if (IS_STONE(board[ii]) && is_same_dragon(ii, aa)) {
- if (move_reasons[r].type == OWL_ATTACK_MOVE
- || move_reasons[r].type == OWL_ATTACK_MOVE_GOOD_KO
- || move_reasons[r].type == OWL_ATTACK_MOVE_BAD_KO)
- saved_stones[ii] = INFLUENCE_CAPTURED_STONE;
- else
- saved_stones[ii] = INFLUENCE_SAVED_STONE;
- }
- }
- }
+ /* Mark the affected dragon for use in the territory analysis. */
+ mark_changed_dragon(pos, color, aa, move_reasons[r].type,
+ saved_stones, &this_value);
+ this_value *= 2.0;
+
TRACE(" %1m: owl attack/defend for %1m\n", pos, aa);
/* FIXME: How much should we reduce the value for ko attacks? */