[Top][All Lists]
[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;
}
}
}
- [gnugo-devel] provide loops over all worms in a dragon,
Arend Bayer <=