[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] large scale reorganized
From: |
Arend Bayer |
Subject: |
[gnugo-devel] large scale reorganized |
Date: |
Sun, 25 Sep 2005 17:59:57 +0200 (CEST) |
I would like to reorganize the large scale code as below. It gets split
up into 3 smaller functions.
The first one (find_large_scale_owl_attack_moves()) selects the dragons to
attack and calls find_large_scale_owl_attacks_on_dragon(), which selects
the moves to try and in turn calls try_large_scale_owl_attack().
I find the code easier to handle this way. I want to play with it a bit
more and hope that we can make --large-scale the default soon. I will
track what I do in ticket #29.
Arend
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.151
diff -u -p -r1.151 value_moves.c
--- engine/value_moves.c 25 Jun 2005 14:52:46 -0000 1.151
+++ engine/value_moves.c 25 Sep 2005 15:55:33 -0000
@@ -385,182 +385,162 @@ do_find_more_owl_attack_and_defense_move
}
-/* Test all the moves to see whether they can owl-attack on
- * a large scale . Tested moves are
+
+/* Try whether the move at (pos) for (color) is also an owl attack on
+ * (target). (dist) is the distance to the dragon, and is used for a
+ * safety heuristic: distant moves are only accepted if they kill within
+ * few owl nodes.
+ */
+static void
+try_large_scale_owl_attack(int pos, int color, int target, int dist)
+{
+ int owl_nodes_before;
+ int owl_nodes_used;
+ int old_node_limit;
+ int new_node_limit;
+ int kworm = NO_MOVE;
+ int acode;
+ int save_verbose = verbose;
+
+ ASSERT1(board[target] == OTHER_COLOR(color), pos);
+ ASSERT1(!owl_attack_move_reason_known(pos, target), pos);
+ DEBUG(DEBUG_LARGE_SCALE, "Trying large scale move %1m on %1m\n", pos,
target);
+
+ /* To avoid horizon effects, we temporarily increase
+ * the depth values to find the large scale attacks.
+ */
+ increase_depth_values();
+
+ /* To reduce the amount of aji allowed for large scale
+ * attacks, we reduce the owl limit to 350 nodes for
+ * attacks at distance <= 1, and 150 nodes for attacks at
+ * distance >= 2.
+ */
+ if (dist <= 1)
+ new_node_limit = gg_min(350, owl_node_limit);
+ else
+ new_node_limit = gg_min(150, owl_node_limit);
+ change_owl_node_limit(new_node_limit, &old_node_limit);
+
+ if (verbose > 0)
+ verbose--;
+
+ owl_nodes_before = get_owl_node_counter();
+ acode = owl_does_attack(pos, target, &kworm);
+ owl_nodes_used = get_owl_node_counter() - owl_nodes_before;
+
+ if (acode >= DRAGON2(target).owl_attack_code
+ && acode == WIN) {
+ add_owl_attack_move(pos, target, kworm, acode);
+ DEBUG(DEBUG_LARGE_SCALE | DEBUG_MOVE_REASONS,
+ "Move at %1m owl-attacks %1m on a large scale(%s).\n",
+ pos, target, result_to_string(acode));
+ }
+ else
+ DEBUG(DEBUG_LARGE_SCALE,
+ "Move at %1m isn't a clean large scale attack on %1m (%s).\n",
+ pos, target, result_to_string(acode));
+
+ DEBUG(DEBUG_LARGE_SCALE, " owl nodes used = %d, dist = %d\n",
+ owl_nodes_used, dist);
+ /* Restore settings. */
+ verbose = save_verbose;
+ change_owl_node_limit(old_node_limit, NULL);
+ decrease_depth_values();
+}
+
+
+#define MAXIMUM_LARGE_SCALE_DIST 3
+
+/* Test all the moves to see whether they can owl-attack a specific
+ * dragon on a large scale . Tested moves are
* 1. Moves that already have a move reason.
- * 2. Are not too far away from a small critical dragon (<= 6 stones).
- * The distance used is the Manhatan distance, and the maximum
- * distance is currently 3.
+ * 2. Are not too far away.
+ * The distance used is the Manhattan distance, and the maximum
+ * distance is MAXIMUM_LARGE_SCALE_DIST.
*/
static void
-find_large_scale_owl_attack_moves(int color)
+find_large_scale_owl_attacks_on_dragon(int color, int target)
{
- int pos;
- int target;
int x, y;
- int dx, dy;
- int N = 0; /* number of critical dragons found */
- int k;
- int unstable_dragons[MAX_WORMS];
- int x_min_dragon[MAX_WORMS];
- int x_max_dragon[MAX_WORMS];
- int y_min_dragon[MAX_WORMS];
- int y_max_dragon[MAX_WORMS];
- int maximum_distance = 3; /* maximum Manhatan distance tried */
+ int x_min = board_size;
+ int x_max = 0;
+ int y_min = board_size;
+ int y_max = 0;
int dist;
- int other = OTHER_COLOR(color);
+
+ ASSERT1(board[target] == OTHER_COLOR(color), target);
- if (debug & DEBUG_LARGE_SCALE)
- gprintf("\nTrying to find large scale attack moves.\n");
-
- /* Identify the unstable dragons and store them in a list. */
- for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
- if (IS_STONE(board[pos])
- && dragon[pos].origin == pos
- && board[pos] == other)
- if (dragon[pos].status == CRITICAL
- || DRAGON2(pos).owl_status == CRITICAL) {
-
- unstable_dragons[N] = pos;
-
- if (debug & DEBUG_LARGE_SCALE)
- gprintf("Small critical dragon found at %1m\n", pos);
-
- /* Find the physical extension of the dragon, and remember it
- * FIXME : probably there should be a better place to calculate
- * them, maybe a new field in the dragon2 array ?
- */
- x = I(pos);
- y = J(pos);
- x_min_dragon[N] = x_max_dragon[N] = x;
- y_min_dragon[N] = y_max_dragon[N] = y;
- for (dx = 0; dx < board_size; dx++)
- for (dy = 0; dy < board_size; dy++) {
-
- if (ON_BOARD2(dx, dy)
- && is_same_dragon(pos, POS(dx, dy))) {
- if (dx < x_min_dragon[N])
- x_min_dragon[N] = dx;
- if (dx > x_max_dragon[N])
- x_max_dragon[N] = dx;
- if (dy < y_min_dragon[N])
- y_min_dragon[N] = dy;
- if (dy > y_max_dragon[N])
- y_max_dragon[N] = dy;
- }
- }
- N++;
+ /* Find the physical extension of the dragon. */
+ for (x = 0; x < board_size; x++)
+ for (y = 0; y < board_size; y++) {
+ if (is_same_dragon(target, POS(x, y))) {
+ if (x < x_min)
+ x_min = x;
+ if (x > x_max)
+ x_max = x;
+ if (y < y_min)
+ y_min = y;
+ if (y > y_max)
+ y_max = y;
}
- }
-
- /* For each unstable dragon, try to find large scale attacks.
+ }
+ ASSERT1(x_min <= x_max && y_min <= y_max, target);
+
+ /* Try to find large scale attacks.
* We do this by first trying to find attacks at dist = 0, then
- * dist = 1, etc., up to maximum_distance.
+ * dist = 1, etc., up to MAXIMUM_LARGE_SCALE_DIST.
*/
- for (k = 0; k < N; k++)
- for (dist = 0; dist <= maximum_distance; dist++)
- for (x = x_min_dragon[k]-dist; x <= x_max_dragon[k]+dist; x++)
- for (y = y_min_dragon[k]-dist; y <= y_max_dragon[k]+dist; y++) {
- target = unstable_dragons[k];
- pos = POS(x, y);
-
- if (ON_BOARD2(x, y) && ON_BOARD1(pos) && (board[pos] == EMPTY)) {
- int a, b;
- a = abs(x - x_min_dragon[k]);
- b = abs(x - x_max_dragon[k]);
- dx = gg_min(a, b);
- a = abs(y - y_min_dragon[k]);
- b = abs(y - y_max_dragon[k]);
- dy = gg_min(a, b);
-
- if (gg_max(dx, dy) == dist) { /* maximum Manhatan distance */
- int has_move_reasons = 0;
- int worth_trying = 0;
-
- /* See if that move has other move reasons */
- has_move_reasons = 0;
- for (a = 0; a < MAX_REASONS; a++) {
- int r = move[pos].reason[a];
- if (r < 0)
- break;
-
- has_move_reasons = 1;
- }
-
-
- /* We try all large scale attacks on small dragons (and
- * only moves with other move reason).
- */
- if (board[target] == other)
- worth_trying = (dragon[target].size <= 6
- && has_move_reasons);
-
- if (worth_trying) {
- int owl_nodes_before;
- int owl_nodes_used;
- int old_node_limit;
- int new_node_limit;
-
- if (debug & DEBUG_LARGE_SCALE)
- gprintf("Trying large scale move %1m on %1m\n", pos, target);
-
- /* To avoid horizon effects, we temporarily increase
- * the depth values to find the large scale attacks.
- */
- increase_depth_values();
-
- /* To reduce the amount of aji allowed for large scale
- * attacks, we reduce the owl limit to 350 nodes for
- * attacks at distance <= 1, and 150 nodes for attacks at
- * distance >= 2.
- */
- if (dist <= 1)
- new_node_limit = gg_min(350, owl_node_limit);
- else
- new_node_limit = gg_min(150, owl_node_limit);
- change_owl_node_limit(new_node_limit, &old_node_limit);
-
- /* Try large scale killing moves on opponent's stones. */
- owl_nodes_before = get_owl_node_counter();
- if (board[target] == other
- && !owl_attack_move_reason_known(pos, target)) {
- int kworm = NO_MOVE;
- int acode;
- int save_verbose = verbose;
- if (verbose > 0)
- verbose--;
-
- acode = owl_does_attack(pos, target, &kworm);
-
- owl_nodes_used = get_owl_node_counter() - owl_nodes_before;
-
- if (acode >= DRAGON2(target).owl_attack_code
- && acode == WIN) {
- add_owl_attack_move(pos, target, kworm, acode);
- if (debug & DEBUG_LARGE_SCALE)
- gprintf("Move at %1m owl-attacks %1m on a large
scale(%s).\n",
- pos, target, result_to_string(acode));
- }
- else if (debug & DEBUG_LARGE_SCALE)
- gprintf("Move at %1m isn't a clean large scale attack on
%1m (%s).\n", pos, target, result_to_string(acode));
-
- if (debug & DEBUG_LARGE_SCALE)
- gprintf(" owl nodes used = %d, dist = %d\n",
- owl_nodes_used, dist);
- verbose = save_verbose;
- }
-
- /* Restore owl node limit */
- change_owl_node_limit(old_node_limit, NULL);
-
- /* Restore the depth values */
- decrease_depth_values();
- }
- }
- }
- }
+ for (dist = 0; dist <= MAXIMUM_LARGE_SCALE_DIST; dist++)
+ for (x = gg_max(x_min - dist, 0);
+ x <= gg_min(x_max + dist, board_size - 1); x++)
+ for (y = gg_max(y_min - dist, 0);
+ y <= gg_min(y_max + dist, board_size - 1); y++) {
+ int pos = POS(x, y);
+ ASSERT1(ON_BOARD2(x, y), pos);
+
+ if (board[pos] == EMPTY) {
+ int a, b, dx, dy;
+ a = abs(x - x_min);
+ b = abs(x - x_max);
+ dx = gg_min(a, b);
+ a = abs(y - y_min);
+ b = abs(y - y_max);
+ dy = gg_min(a, b);
+
+ if (gg_max(dx, dy) == dist
+ && move[pos].reason[0] >= 0
+ && !owl_attack_move_reason_known(pos, target))
+ /* Maximum Manhatan distance, move reason known but no owl
+ * attack yet.
+ */
+ try_large_scale_owl_attack(pos, color, target, dist);
+
+ }
+ }
}
+
+/* Try large scale owl attacks against all enemy dragons that are
+ * small (size <= 6) and critical.
+ */
+static void
+find_large_scale_owl_attack_moves(int color)
+{
+ int d;
+
+ DEBUG(DEBUG_LARGE_SCALE, "\nTrying to find large scale attack moves.\n");
+ for (d = 0; d < number_of_dragons; d++) {
+ int target = dragon2[d].origin;
+ if (dragon[target].color == OTHER_COLOR(color)
+ && dragon[target].size <= 6
+ && (dragon[target].status == CRITICAL
+ || dragon2[d].owl_status == CRITICAL)) {
+ DEBUG(DEBUG_LARGE_SCALE, "Small critical dragon found at %1m\n", target);
+ find_large_scale_owl_attacks_on_dragon(color, target);
+ }
+ }
+}
/* Test certain moves to see whether they (too) can owl-attack or
* defend an owl critical dragon. Tested moves are
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnugo-devel] large scale reorganized,
Arend Bayer <=