gnugo-devel
[Top][All Lists]
Advanced

[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? */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]