gnugo-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnugo-devel] provide loops over all worms in a dragon


From: Arend Bayer
Subject: [gnugo-devel] provide loops over all worms in a dragon
Date: Mon, 16 Sep 2002 23:57:33 +0200 (CEST)

This patch provides an interface to make loops over all worms in a dragon:

  for (ii = first_worm_in_dragon(pos); ii != NO_MOVE;
       ii = next_worm_in_dragon(ii)) {
    ...
  }

Arend

- new private dragon.c variable next_worm_list[] links worms in each dragon
- new functions first_worm_in_dragon(), next_worm_in_dragon()
- mark_changed_dragon() revised

Index: engine/dragon.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/dragon.c,v
retrieving revision 1.76
diff -u -r1.76 dragon.c
--- engine/dragon.c     16 Sep 2002 08:30:28 -0000      1.76
+++ engine/dragon.c     16 Sep 2002 19:00:58 -0000
@@ -65,6 +65,12 @@
 static int lively_white_dragons;
 static int lively_black_dragons;

+/* This is a private array to obtain a list of worms belonging to each
+ * dragon. Public access is via first_worm_in_dragon() and
+ * next_worm_in_dragon().
+ */
+static int next_worm_list[BOARDMAX];
+
 /* Alternative for DRAGON2 macro with asserts. */
 struct dragon_data2 *
 dragon2_func(int pos)
@@ -700,6 +706,7 @@
              "Initializing dragon from worm at %1m, size %d\n",
              str, worm[str].size);
     }
+  memset(next_worm_list, 0, sizeof(next_worm_list));
 }


@@ -1272,6 +1279,10 @@
   /* Normalize dragon coordinates. */
   d1 = dragon[d1].origin;
   d2 = dragon[d2].origin;
+
+  /* If d1 and d2 are the same dragon, we do nothing. */
+  if (d1 == d2)
+    return;

   gg_assert(board[d1] == board[d2]);
   gg_assert(dragon2_initialized == 0);
@@ -1296,6 +1307,17 @@
   dragon[origin].effective_size  = (dragon[d2].effective_size
                                    + dragon[d1].effective_size);

+  /* Join the second next_worm_in_dragon chain at the end of the first one. */
+  {
+    int last_worm_origin_dragon = origin;
+    while (next_worm_list[last_worm_origin_dragon] != NO_MOVE)
+      last_worm_origin_dragon = next_worm_list[last_worm_origin_dragon];
+    if (origin == d1)
+      next_worm_list[last_worm_origin_dragon] = d2;
+    else
+      next_worm_list[last_worm_origin_dragon] = d1;
+  }
+
   for (ii = BOARDMIN; ii < BOARDMAX; ii++) {
     if (ON_BOARD(ii)
        && (dragon[ii].origin == d1 || dragon[ii].origin == d2))
@@ -1883,6 +1905,26 @@

   return 0;
 }
+
+
+/* The following two functions allow to traverse all worms in a dragon:
+ * for (ii = first_worm_in_dragon(pos); ii != NO_MOVE;
+ *      ii = next_worm_in_dragon(ii);)
+ *   ...
+ * At the moment first_worm(pos) will always be the origin of the dragon,
+ * but you should not rely on that.
+ */
+int first_worm_in_dragon(int w)
+{
+  return dragon[w].origin;
+}
+
+int next_worm_in_dragon(int w)
+{
+  gg_assert(worm[w].origin == w);
+  return next_worm_list[w];
+}
+

 /* ================================================================ */
 /*                       A few status functions                     */
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.113
diff -u -r1.113 liberty.h
--- engine/liberty.h    16 Sep 2002 07:27:48 -0000      1.113
+++ engine/liberty.h    16 Sep 2002 19:01:03 -0000
@@ -339,6 +339,8 @@
 int dragon_escape(char goal[BOARDMAX], int color, int escape_value[BOARDMAX]);
 int is_same_dragon(int d1, int d2);
 int are_neighbor_dragons(int d1, int d2);
+int first_worm_in_dragon(int w);
+int next_worm_in_dragon(int w);
 int lively_dragon_exists(int color);
 int is_same_worm(int w1, int w2);
 int is_worm_origin(int w, int pos);
Index: engine/move_reasons.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.c,v
retrieving revision 1.92
diff -u -r1.92 move_reasons.c
--- engine/move_reasons.c       4 Sep 2002 07:23:45 -0000       1.92
+++ engine/move_reasons.c       16 Sep 2002 19:01:10 -0000
@@ -1471,30 +1471,28 @@
       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;
+  for (ii = first_worm_in_dragon(affected_dragon); ii != NO_MOVE;
+       ii = next_worm_in_dragon(ii)) {
+    if (new_status == INFLUENCE_CAPTURED_STONE)
+      mark_string(ii, changed_stones, new_status);
+    else {
+      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;
       }
     }
   }





reply via email to

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