[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] PATCH: atari-atari enhanced; now working
From: |
Inge Wallin |
Subject: |
[gnugo-devel] PATCH: atari-atari enhanced; now working |
Date: |
Sun, 25 Nov 2001 11:12:22 +0100 (MET) |
Here is a new version of the atari-atari enhancements. This time it
seems to work. I have run all the regression tests and here are the
results:
./regress.sh . neurogo.tst
16 unexpected PASS!
./regress.sh . strategy2.tst
100 unexpected PASS!
./regress.sh . nicklas2.tst
102 unexpected FAIL: Correct 'D4', got 'G2'
./regress.sh . nicklas4.tst
812 unexpected FAIL: Correct 'J12', got 'K14'
./regress.sh . trevor.tst
590 unexpected FAIL: Correct '0', got '1 B19'
./regress.sh . strategy3.tst
108 unexpected FAIL: Correct 'C15', got 'A10'
./regress.sh . global.tst
36 unexpected FAIL: Correct 'B6', got 'C5'
./regress.sh . arend.tst
17 unexpected PASS!
41 unexpected FAIL: Correct 'B6', got 'B7'
./regress.sh . trevora.tst
280 unexpected PASS!
./regress.sh . strategy4.tst
151 unexpected FAIL: Correct '!(Q1|T5)', got 'T5'
Most of the failures are problems with the interaction between
atari-atari and owl valuations in move-reasons.c. arend:41 is an error
on the test file which my patch corrects. strategy4:151 is an owl
problem. All the passes are due to the improvements, so this is a big
encouragement.
I will continue to work on this and see if the valuation problems can
be solved. Owl knowledgeable people might want to look at
strategy4:151.
Btw, I found a possible bug on line 339 in owl.c and marked it with a
FIXME. There are four calls to owl_determine_life all looking the
same except for one where a parameter has another value. Is this
correct?
Summary:
- atari_atari now considers general threat the first moves
- new depth parameter aa_threat_depth
- new function: atari_atari_succeeded
- cleanup in atari_atari functions
- compute_escape_influence now 1D
- new function in reading.c: attack_threats
- handling of tactical moves in worm.c no longer static
-Inge
================================================================
diff -ur gnugo-sync/engine/combination.c gnugo-iw2/engine/combination.c
--- gnugo-sync/engine/combination.c Fri Nov 16 18:48:58 2001
+++ gnugo-iw2/engine/combination.c Sun Nov 25 11:55:26 2001
@@ -33,10 +33,12 @@
static void find_double_threats(int color);
-
+static int is_atari(int pos, int color);
/* Generate move reasons for combination attacks and defenses against
* them.
+ *
+ * This is one of the move generators called from genmove().
*/
void
@@ -175,8 +177,11 @@
static void compute_aa_status(int color);
static int get_aa_status(int pos);
static int do_atari_atari(int color, int *attack_point,
- int *defense_point, int cpos,
+ int *defense_point, int last_friendly,
int save_verbose, int minsize);
+static int atari_atari_succeeded(int color, int *attack_point,
+ int *defense_point, int last_friendly,
+ int save_verbose, int minsize);
/* Set to 1 if you want verbose traces from this function. */
@@ -232,7 +237,120 @@
}
-/* Helper function for computing the aa_status for a string. */
+/* Ask the atari_atari code whether there appears any combination
+ * attack which would capture at least minsize stones after playing at
+ * (tpos). If this happens, (*move) points to a move which prevents
+ * this blunder.
+ */
+int
+atari_atari_confirm_safety(int color, int tpos, int *move, int minsize)
+{
+ int fpos;
+ int defense_point = NO_MOVE, after_defense_point = NO_MOVE;
+ int aa_val, after_aa_val;
+ int other = OTHER_COLOR(color);
+
+ /* If aa_depth is too small, we can't see any combination attacks,
+ * so in this respect the move is safe enough.
+ */
+ if (aa_depth < 2)
+ return 1;
+
+ memset(forbidden, 0, sizeof(forbidden));
+
+ compute_aa_status(other);
+
+ /* Accept illegal ko capture here. */
+ if (!tryko(tpos, color, NULL, EMPTY, NO_MOVE))
+ /* Really shouldn't happen. */
+ abortgo(__FILE__, __LINE__, "trymove", I(tpos), J(tpos));
+ increase_depth_values();
+
+ aa_val = do_atari_atari(other, &fpos, &defense_point,
+ NO_MOVE, 0, minsize);
+ after_aa_val = aa_val;
+
+ if (aa_val == 0 || defense_point == NO_MOVE) {
+
+ /* No sufficiently large combination attack, so the move is safe from
+ * this danger.
+ *
+ * On rare occasions do_atari_atari might find a combination
+ * but no defense. In this case we assume that the combination
+ * is illusory.
+ */
+
+ popgo();
+ decrease_depth_values();
+ return 1;
+ }
+
+ while (aa_val >= after_aa_val) {
+ /* Try dropping moves from the combination and see if it still
+ * works. What we really want is to get the proper defense move
+ * into (*move).
+ */
+ after_defense_point = defense_point;
+ forbidden[fpos] = 1;
+ aa_val = do_atari_atari(other, &fpos, &defense_point,
+ NO_MOVE, 0, aa_val);
+ }
+
+ popgo();
+ decrease_depth_values();
+ /* We know that a combination exists, but we don't know if
+ * the original move at (aa) was really relevant. So we
+ * try omitting it and see if a combination is still found.
+ */
+ if (do_atari_atari(other, NULL, NULL, NO_MOVE, 0, minsize) >= after_aa_val)
+ return 1;
+ else {
+ if (move) *move = after_defense_point;
+ return 0;
+ }
+}
+
+
+/* Ask the atari_atari code if after color plays at (apos)
+ * and other plays at (bpos) there appears any combination
+ * attack. Returns the size of the combination.
+ */
+
+int
+atari_atari_try_combination(int color, int apos, int bpos)
+{
+ int other = OTHER_COLOR(color);
+ int aa_val = 0;
+ int save_verbose = verbose;
+
+ if (aa_depth < 2)
+ return 0;
+ if (verbose > 0)
+ verbose--;
+ memset(forbidden, 0, sizeof(forbidden));
+
+ compute_aa_status(color);
+
+ if (trymove(apos, color, NULL, NO_MOVE, EMPTY, NO_MOVE)) {
+ if (trymove(bpos, other, NULL, NO_MOVE, EMPTY, NO_MOVE)) {
+ aa_val = do_atari_atari(color, NULL, NULL, apos, 0, 0);
+ popgo();
+ }
+ popgo();
+ }
+ verbose = save_verbose;
+ return aa_val;
+}
+
+
+/* ---------------------------------------------------------------- */
+/* Helper functions for atari_atari. */
+/* ---------------------------------------------------------------- */
+
+
+/* Helper function for computing the aa_status for a string.
+ */
+
static void
compute_aa_status(int color)
{
@@ -298,6 +416,7 @@
}
}
+
/* Helper function for retrieving the aa_status for a string. We can't
* reliably do this simply by looking up aa_status[pos] since this is
* only valid at vertices which were non-empty at the start of the
@@ -305,6 +424,7 @@
* locating a part of the string which was a worm at the beginning of
* the reading.
*/
+
static int
get_aa_status(int pos)
{
@@ -338,6 +458,8 @@
* equivalent to a return value of 0.
*/
+#define MAX_THREAT_MOVES MAX_TACTICAL_POINTS
+
static int
do_atari_atari(int color, int *attack_point, int *defense_point,
int last_friendly, int save_verbose, int minsize)
@@ -361,65 +483,15 @@
/* First look for strings adjacent to the last friendly move played
* (or to another stone in the same string) which can be
- * unexpectedly attacked.
+ * unexpectedly attacked. If so, the combination attack
+ * has succeeded.
*/
- if (last_friendly != NO_MOVE)
- for (m = 0; m < board_size; m++)
- for (n = 0; n < board_size; n++) {
- int pos = POS(m, n);
- int apos;
-
- if (board[pos] != other)
- continue;
-
- if (pos != find_origin(pos))
- continue;
-
- if (minsize > 0 && countstones(pos) < minsize)
- continue;
-
- if (get_aa_status(pos) != ALIVE)
- continue;
-
- if (board[last_friendly] != EMPTY
- && !adjacent_strings(last_friendly, pos))
- continue;
-
- if (board[last_friendly] == EMPTY
- && !liberty_of_string(last_friendly, pos))
- continue;
-
- if (debug & DEBUG_ATARI_ATARI)
- gprintf("Considering attack of %1m. depth = %d.\n", pos, depth);
- if (attack(pos, &apos)) {
- if (save_verbose || (debug & DEBUG_ATARI_ATARI)) {
- gprintf("%oThe worm %1m can be attacked at %1m after ", pos, apos);
- dump_stack();
- }
- if (attack_point) *attack_point = apos;
-
- /* We look for a move defending the combination.
- * Normally this is found by find_defense but failing
- * that, if the attacking move is a safe move for color,
- * it probably defends.
- */
- if (defense_point) {
- if (!find_defense(pos, defense_point)) {
- if (safe_move(apos, other)) {
- *defense_point = apos;
- }
- /* No defense is found */
- else {
- *defense_point = NO_MOVE;
- }
- }
- }
-
- DEBUG(DEBUG_ATARI_ATARI, "%oreturn value:%d (%1m)\n",
- countstones(pos), pos);
- return countstones(pos);
- }
- }
+ if (last_friendly != NO_MOVE) {
+ int retval = atari_atari_succeeded(color, attack_point, defense_point,
+ last_friendly, save_verbose, minsize);
+ if (retval != 0)
+ return retval;
+ }
if (stackp > aa_depth)
return 0;
@@ -431,8 +503,11 @@
for (m = 0; m < board_size; m++)
for (n = 0; n < board_size; n++) {
int pos = POS(m, n);
- int libs[2];
+ int num_moves;
+ int moves[MAX_THREAT_MOVES];
+ int codes[MAX_THREAT_MOVES];
int status;
+ int aa_val;
if (board[pos] != other)
continue;
@@ -447,219 +522,229 @@
if (status != ALIVE)
continue;
- if (findlib(pos, 2, libs) != 2)
- continue;
+ if (stackp < aa_threat_depth) {
+ num_moves = attack_threats(pos, moves, codes);
+ if ((debug & DEBUG_ATARI_ATARI)
+ && (num_moves > 0)) {
+ int i;
+ gprintf("Threats on %1m: ", pos);
+ for (i = 0; i < num_moves; i++)
+ gprintf("%1m ", moves[i]);
+ gprintf("\n");
+ }
+ }
+ else {
+ num_moves = findlib(pos, 2, moves);
+ if (num_moves != 2)
+ continue;
+ }
- for (k = 0; k < 2; k++) {
- int apos = libs[k];
+ for (k = 0; k < num_moves; k++) {
+ int apos = moves[k];
int bpos;
- if (!forbidden[apos]
- && (accurate_approxlib(apos, color, 2, NULL) > 1
- || safe_move(apos, color))) {
- if (trymove(apos, color, "do_atari_atari-A", pos,
- EMPTY, NO_MOVE)) {
- /* try to defend the stone (m,n) which is in atari */
- int aa_val = 0;
+ if (forbidden[apos])
+ continue;
- /* Because we know (m, n) is in atari there is a trivial
- * attack and we can be sure find_defense() will give a
- * useful defense point if it returns non-zero. Usually we
- * would need to call attack_and_defend() to be certain of
- * this.
- *
- * On the other hand, if there is no defense we have
- * already been successful.
- */
- if (find_defense(pos, &bpos)
- && trymove(bpos, other, "do_atari_atari-B", pos,
- EMPTY, NO_MOVE)) {
- /* These moves may have been irrelevant for later
- * reading, so in order to avoid horizon problems, we
- * need to temporarily increase the depth values.
- */
- increase_depth_values();
- increase_depth_values();
- aa_val = do_atari_atari(color, NULL, defense_point,
- apos, save_verbose, minsize);
- decrease_depth_values();
- decrease_depth_values();
- popgo();
- }
- else {
- /* No way to save the ataried stone. We have been successful. */
+ if ((accurate_approxlib(apos, color, 2, NULL) < 2
+ || !is_atari(apos, color))
+ && !safe_move(apos, color))
+ continue;
+
+ if (!trymove(apos, color, "do_atari_atari-A", pos,
+ EMPTY, NO_MOVE))
+ continue;
+
+ /* try to defend the stone (m,n) which is in atari */
+ aa_val = 0;
+
+ /* Because we know (pos) is threatened there is a trivial
+ * attack and we can be sure find_defense() will give a
+ * useful defense point if it returns non-zero. Usually we
+ * would need to call attack_and_defend() to be certain of
+ * this.
+ *
+ * On the other hand, if there is no defense we have
+ * already been successful.
+ */
+ if (find_defense(pos, &bpos)
+ && trymove(bpos, other, "do_atari_atari-B", pos,
+ EMPTY, NO_MOVE)) {
+ /* These moves may have been irrelevant for later
+ * reading, so in order to avoid horizon problems, we
+ * need to temporarily increase the depth values.
+ */
+ modify_depth_values(2);
+ aa_val = do_atari_atari(color, NULL, defense_point,
+ apos, save_verbose, minsize);
+ modify_depth_values(-2);
+ popgo();
+ }
+ else {
+ /* No way to save the ataried stone. We have been successful. */
+ popgo();
+ if (save_verbose || (debug & DEBUG_ATARI_ATARI)) {
+ gprintf("%oThe worm %m can be attacked at %1m after ", m, n,
+ apos);
+ dump_stack();
+ }
+ if (attack_point) *attack_point = apos;
+ if (defense_point && !find_defense(pos, defense_point))
+ *defense_point = NO_MOVE;
+
+ DEBUG(DEBUG_ATARI_ATARI, "%oreturn value:%d (%m)\n",
+ countstones(pos), m, n);
+ return countstones(pos);
+ }
+
+ if (aa_val) {
+ /* The atari at (apos) seems to work but we still
+ * must check if there is not a better defense.
+ */
+ int cpos;
+ int res;
+
+ if (countlib(pos) == 1)
+ res = restricted_defend1(pos, &cpos, EMPTY, 0, 1, &bpos);
+ else
+ res = 0; /* FIXME: Find other defense points. */
+
+ if (res) {
+ if (trymove(cpos, other, "do_atari_atari-C",
+ pos, EMPTY, NO_MOVE)) {
+ modify_depth_values(2);
+ if (!do_atari_atari(color, NULL, defense_point,
+ apos, save_verbose, minsize))
+ aa_val = 0;
+ modify_depth_values(-2);
popgo();
- if (save_verbose || (debug & DEBUG_ATARI_ATARI)) {
- gprintf("%oThe worm %m can be attacked at %1m after ", m, n,
- apos);
- dump_stack();
- }
- if (attack_point) *attack_point = apos;
- if (defense_point && !find_defense(pos, defense_point))
- *defense_point = NO_MOVE;
-
- DEBUG(DEBUG_ATARI_ATARI, "%oreturn value:%d (%m)\n",
- countstones(pos), m, n);
- return countstones(pos);
}
+ }
- if (aa_val) {
- /* The atari at (ai,aj) seems to work but we still
- * must check there is not a better defense.
- */
- int cpos;
- int res = restricted_defend1(pos, &cpos, EMPTY, 0,
- 1, &bpos);
- if (res) {
- if (trymove(cpos, other, "do_atari_atari-C",
- pos, EMPTY, NO_MOVE)) {
- increase_depth_values();
- increase_depth_values();
- if (!do_atari_atari(color, NULL, defense_point,
- apos, save_verbose, minsize))
- aa_val = 0;
- decrease_depth_values();
- decrease_depth_values();
- popgo();
- }
- }
- if (aa_val) {
- if (attack_point) *attack_point = apos;
- popgo();
- DEBUG(DEBUG_ATARI_ATARI,
- "%oreturn value:%d (min %d, %d (%m))\n",
- gg_min(aa_val, countstones(pos)), aa_val,
- countstones(pos), m, n);
- /* If no defense point is known and (ai,aj) is a safe
- * move for other, it probably defends the combination.
- */
- if (defense_point
- && (*defense_point == NO_MOVE
- || !safe_move(*defense_point, other))
- && safe_move(apos, other)) {
- *defense_point = apos;
- }
- return gg_min(aa_val, countstones(pos));
- }
- }
+ if (aa_val) {
+ if (attack_point) *attack_point = apos;
popgo();
+ DEBUG(DEBUG_ATARI_ATARI,
+ "%oreturn value:%d (min %d, %d (%m))\n",
+ gg_min(aa_val, countstones(pos)), aa_val,
+ countstones(pos), m, n);
+ /* If no defense point is known and (ai,aj) is a safe
+ * move for other, it probably defends the combination.
+ */
+ if (defense_point
+ && (*defense_point == NO_MOVE
+ || !safe_move(*defense_point, other))
+ && safe_move(apos, other)) {
+ *defense_point = apos;
+ }
+ return gg_min(aa_val, countstones(pos));
}
}
+
+ popgo();
}
}
+
return 0;
}
-/* Ask the atari_atari code whether there appears any combination
- * attack which would capture at least minsize stones after playing at
- * (tpos). If this happens, (*move) points to a move which prevents
- * this blunder.
- *
- * FIXME: Most of the code below is common with atari_atari() and
- * should be broken out of both functions.
- */
-int
-atari_atari_confirm_safety(int color, int tpos, int *move, int minsize)
+
+static int
+atari_atari_succeeded(int color, int *attack_point, int *defense_point,
+ int last_friendly, int save_verbose, int minsize)
{
- int fpos;
- int defense_point = NO_MOVE, after_defense_point = NO_MOVE;
- int aa_val, after_aa_val;
+ int m, n;
int other = OTHER_COLOR(color);
- /* If aa_depth is too small, we can't see any combination attacks,
- * so in this respect the move is safe enough.
- */
- if (aa_depth < 2)
- return 1;
-
- memset(forbidden, 0, sizeof(forbidden));
-
- compute_aa_status(other);
-
- /* Accept illegal ko capture here. */
- if (!tryko(tpos, color, NULL, EMPTY, NO_MOVE))
- /* Really shouldn't happen. */
- abortgo(__FILE__, __LINE__, "trymove", I(tpos), J(tpos));
- increase_depth_values();
+ for (m = 0; m < board_size; m++)
+ for (n = 0; n < board_size; n++) {
+ int ii = POS(m, n);
+ int aa;
- aa_val = do_atari_atari(other, &fpos, &defense_point,
- NO_MOVE, 0, minsize);
- after_aa_val = aa_val;
+ if (board[ii] != other)
+ continue;
- if (aa_val == 0 || defense_point == NO_MOVE) {
+ if (ii != find_origin(ii))
+ continue;
- /* No sufficiently large combination attack, so the move is safe from
- * this danger.
- *
- * On rare occasions do_atari_atari might find a combination
- * but no defense. In this case we assume that the combination
- * is illusory.
- */
-
- popgo();
- decrease_depth_values();
- return 1;
- }
-
- while (aa_val >= after_aa_val) {
- /* Try dropping moves from the combination and see if it still
- * works. What we really want is to get the proper defense move
- * into (*move).
- */
- after_defense_point = defense_point;
- forbidden[fpos] = 1;
- aa_val = do_atari_atari(other, &fpos, &defense_point,
- NO_MOVE, 0, aa_val);
- }
+ if (minsize > 0 && countstones(ii) < minsize)
+ continue;
+
+ if (get_aa_status(ii) != ALIVE)
+ continue;
+
+ if (board[last_friendly] != EMPTY
+ && !adjacent_strings(last_friendly, ii))
+ continue;
+
+ if (board[last_friendly] == EMPTY
+ && !liberty_of_string(last_friendly, ii))
+ continue;
+
+ if (debug & DEBUG_ATARI_ATARI)
+ gprintf("Considering attack of %1m. depth = %d.\n", ii, depth);
+
+ if (attack(ii, &aa)) {
+ if (save_verbose || (debug & DEBUG_ATARI_ATARI)) {
+ gprintf("%oThe worm %1m can be attacked at %1m after ", ii, aa);
+ dump_stack();
+ }
+ if (attack_point) *attack_point = aa;
+
+ /* We look for a move defending the combination.
+ * Normally this is found by find_defense but failing
+ * that, if the attacking move is a safe move for color,
+ * it probably defends.
+ */
+ if (defense_point) {
+ if (!find_defense(ii, defense_point)) {
+ if (safe_move(aa, other)) {
+ *defense_point = aa;
+ }
+ /* No defense is found */
+ else {
+ *defense_point = NO_MOVE;
+ }
+ }
+ }
+
+ DEBUG(DEBUG_ATARI_ATARI, "%oreturn value:%d (%1m)\n",
+ countstones(ii), ii);
+ return countstones(ii);
+ }
+ }
- popgo();
- decrease_depth_values();
- /* We know that a combination exists, but we don't know if
- * the original move at (aa) was really relevant. So we
- * try omitting it and see if a combination is still found.
- */
- if (do_atari_atari(other, NULL, NULL, NO_MOVE, 0, minsize) >= after_aa_val)
- return 1;
- else {
- if (move) *move = after_defense_point;
- return 0;
- }
+ return 0;
}
-/* Ask the atari_atari code if after color plays at (apos)
- * and other plays at (bpos) there appears any combination
- * attack. Returns the size of the combination.
- *
- * FIXME: Most of the code below is common with atari_atari() and
- * should be broken out of both functions.
+/* Returns true of a move by (color) at (pos) is atari on something
+ * FIXME: Move this to an appropriate location.
*/
-int
-atari_atari_try_combination(int color, int apos, int bpos)
+static int
+is_atari(int pos, int color)
{
int other = OTHER_COLOR(color);
- int aa_val = 0;
- int save_verbose = verbose;
- if (aa_depth < 2)
+ if (!is_legal(pos, color))
return 0;
- if (verbose > 0)
- verbose--;
- memset(forbidden, 0, sizeof(forbidden));
+ if (board[NORTH(pos)] == other
+ && countlib(NORTH(pos)) == 2)
+ return 1;
+ if (board[EAST(pos)] == other
+ && countlib(EAST(pos)) == 2)
+ return 1;
+ if (board[SOUTH(pos)] == other
+ && countlib(SOUTH(pos)) == 2)
+ return 1;
+ if (board[WEST(pos)] == other
+ && countlib(WEST(pos)) == 2)
+ return 1;
+ return 0;
+}
- compute_aa_status(color);
- if (trymove(apos, color, NULL, NO_MOVE, EMPTY, NO_MOVE)) {
- if (trymove(bpos, other, NULL, NO_MOVE, EMPTY, NO_MOVE)) {
- aa_val = do_atari_atari(color, NULL, NULL, apos, 0, 0);
- popgo();
- }
- popgo();
- }
- verbose = save_verbose;
- return aa_val;
-}
/*
diff -ur gnugo-sync/engine/dragon.c gnugo-iw2/engine/dragon.c
--- gnugo-sync/engine/dragon.c Sun Nov 11 17:18:12 2001
+++ gnugo-iw2/engine/dragon.c Sat Nov 24 19:40:58 2001
@@ -78,12 +78,19 @@
dragon[ii].effective_size = worm[ii].effective_size;
dragon[ii].color = worm[ii].color;
dragon[ii].origin = worm[ii].origin;
+#if 0
+ for (i = 0; i < MAX_TACTICAL_POINTS; ++i) {
+ dragon[ii].owl_attack_points[i] = NO_MOVE;
+ dragon[ii].owl_attack_codes[i] = 0;
+ }
+#else
dragon[ii].owl_attack_point = NO_MOVE;
dragon[ii].owl_attack_code = 0;
- dragon[ii].owl_attack_certain = 1;
+#endif
+ dragon[ii].owl_attack_certain = 1;
dragon[ii].owl_defense_point = NO_MOVE;
dragon[ii].owl_defense_code = 0;
- dragon[ii].owl_defend_certain = 1;
+ dragon[ii].owl_defend_certain = 1;
dragon[ii].owl_status = UNCHECKED;
dragon[ii].status = UNKNOWN;
dragon[ii].matcher_status = UNKNOWN;
@@ -395,8 +402,9 @@
if (stop_before_owl)
return;
- /* Determine owl status of each dragon. */
-
+ /* Determine life and death status of each dragon using the owl code
+ * if necessary.
+ */
purge_persistent_owl_cache();
for (m = 0; m < board_size; m++)
@@ -1452,7 +1460,7 @@
}
/* Wrapper to call the function above and compute the escape potential
- * for the dragon at (m, n).
+ * for the dragon at (pos).
*/
static int
compute_escape(int pos, int dragon_status_known)
@@ -1471,9 +1479,13 @@
goal[ii] = is_same_dragon(ii, pos);
}
+ /* Compute escape_value array. Points are awarded for moyo (4),
+ * area (2) or EMPTY (1). Values may change without notice.
+ */
compute_escape_influence(goal, board[pos], escape_value,
dragon_status_known);
+ /* If we can reach a live group, award 6 points. */
for (i = 0; i < board_size; i++)
for (j = 0; j < board_size; j++) {
ii = POS(i, j);
diff -ur gnugo-sync/engine/globals.c gnugo-iw2/engine/globals.c
--- gnugo-sync/engine/globals.c Tue Oct 16 22:41:41 2001
+++ gnugo-iw2/engine/globals.c Sat Nov 24 19:40:58 2001
@@ -61,6 +61,7 @@
int ko_depth; /* deep reading cut off */
int branch_depth; /* deep reading cut off */
int aa_depth;
+int aa_threat_depth;
int owl_distrust_depth; /* below this owl trusts the optics code */
int owl_branch_depth; /* below this owl tries only one variation */
int owl_reading_depth; /* owl does not read below this depth */
@@ -73,6 +74,7 @@
int mandated_ko_depth; /* deep reading cut off, mandated value */
int mandated_branch_depth; /* deep reading cut off, mandated value */
int mandated_aa_depth;
+int mandated_aa_threat_depth = -1;
int mandated_owl_distrust_depth;
int mandated_owl_branch_depth;
int mandated_owl_reading_depth;
diff -ur gnugo-sync/engine/gnugo.h gnugo-iw2/engine/gnugo.h
--- gnugo-sync/engine/gnugo.h Sat Nov 10 23:52:43 2001
+++ gnugo-iw2/engine/gnugo.h Sat Nov 24 19:40:58 2001
@@ -284,6 +284,7 @@
extern int mandated_ko_depth;
extern int mandated_branch_depth;
extern int mandated_aa_depth;
+extern int mandated_aa_threat_depth;
extern int mandated_owl_distrust_depth;
extern int mandated_owl_branch_depth;
extern int mandated_owl_reading_depth;
diff -ur gnugo-sync/engine/influence.c gnugo-iw2/engine/influence.c
--- gnugo-sync/engine/influence.c Fri Nov 16 18:48:59 2001
+++ gnugo-iw2/engine/influence.c Sat Nov 24 19:40:58 2001
@@ -1171,18 +1171,22 @@
int dragons_known)
{
int i, j;
+ int ii;
+
compute_influence(&escape_influence, OTHER_COLOR(color), -1, -1,
dragons_known, goal, NULL);
for (i = 0; i < board_size; i++)
for (j = 0; j < board_size; j++) {
+ ii = POS(i, j);
+
if (whose_moyo(&escape_influence, i, j) == color)
- escape_value[POS(i, j)] = 4;
+ escape_value[ii] = 4;
else if (whose_area(&escape_influence, i, j) == color)
- escape_value[POS(i, j)] = 2;
+ escape_value[ii] = 2;
else if (whose_area(&escape_influence, i, j) == EMPTY)
- escape_value[POS(i, j)] = 1;
+ escape_value[ii] = 1;
else
- escape_value[POS(i, j)] = 0;
+ escape_value[ii] = 0;
}
if (0 && (debug & DEBUG_ESCAPE) && verbose > 0) {
diff -ur gnugo-sync/engine/liberty.h gnugo-iw2/engine/liberty.h
--- gnugo-sync/engine/liberty.h Fri Nov 16 18:49:00 2001
+++ gnugo-iw2/engine/liberty.h Sat Nov 24 20:17:48 2001
@@ -219,6 +219,8 @@
void reading_cache_init(int bytes);
void reading_cache_clear(void);
+/* FIXME: Remove it from here and put it back near worm.c */
+#define MAX_TACTICAL_POINTS 10
/* reading.c */
int attack(int str, int *move);
@@ -229,6 +231,8 @@
int attack_either(int astr, int bstr);
int defend_both(int astr, int bstr);
int break_through(int apos, int bpos, int cpos);
+int attack_threats(int pos, int moves[MAX_TACTICAL_POINTS],
+ int codes[MAX_TACTICAL_POINTS]);
int restricted_defend1(int str, int *move, int komaster, int kom_pos,
int num_forbidden_moves, int *forbidden_moves);
@@ -289,6 +293,16 @@
void find_connections(void);
void modify_eye_spaces(void);
+/* FIXME: Move these from worm.c */
+int tactical_move_known(int move, int points[MAX_TACTICAL_POINTS],
+ int codes[MAX_TACTICAL_POINTS]);
+void change_tactical_point(int str, int move, int code,
+ int points[MAX_TACTICAL_POINTS],
+ int codes[MAX_TACTICAL_POINTS]);
+void sort_tactical_points(int points[MAX_TACTICAL_POINTS],
+ int codes[MAX_TACTICAL_POINTS]);
+
+
/* functions to add (or remove) move reasons */
void clear_move_reasons(void);
void add_lunch(int eater, int food);
@@ -515,6 +529,7 @@
extern int fourlib_depth; /* deep reading cutoff */
extern int ko_depth; /* deep ko reading cutoff */
extern int aa_depth; /* deep global reading cutoff */
+extern int aa_threat_depth;
extern int owl_distrust_depth; /* below this owl trusts the optics code */
extern int owl_branch_depth; /* below this owl tries only one variation */
extern int owl_reading_depth; /* owl does not read below this depth */
@@ -557,7 +572,11 @@
* data concerning a worm. A copy is kept at each vertex of the worm.
*/
+#if 0
+FIXME: Reinstate it here once the functions handling these arrays
+ are moved to their own file.
#define MAX_TACTICAL_POINTS 10
+#endif
struct worm_data {
int color; /* its color */
@@ -585,8 +604,8 @@
* respect to the codes so that the first element contains the best
* result.
*/
- int attack_codes[MAX_TACTICAL_POINTS];
int attack_points[MAX_TACTICAL_POINTS];
+ int attack_codes[MAX_TACTICAL_POINTS];
int defend_codes[MAX_TACTICAL_POINTS];
int defense_points[MAX_TACTICAL_POINTS];
int attack_threat_codes[MAX_TACTICAL_POINTS];
@@ -614,7 +633,12 @@
int owl_status; /* (ALIVE, DEAD, UNKNOWN, CRITICAL, UNCHECKED) */
int owl_attack_point; /* vital point for attack */
int owl_attack_code; /* ko result code */
+#if 0
+ int owl_attack_points[MAX_TACTICAL_POINTS];
+ int owl_attack_codes[MAX_TACTICAL_POINTS];
+#endif
int owl_attack_certain; /* 0 if owl reading node limit is reached */
+
int owl_second_attack_point;/* if attacker gets both attack points, wins */
int owl_defense_point; /* vital point for defense */
int owl_defense_code; /* ko result code */
diff -ur gnugo-sync/engine/move_reasons.c gnugo-iw2/engine/move_reasons.c
--- gnugo-sync/engine/move_reasons.c Wed Nov 21 20:44:18 2001
+++ gnugo-iw2/engine/move_reasons.c Sat Nov 24 19:40:58 2001
@@ -3186,10 +3186,10 @@
}
#if 0
- if (dragon[POS(bi, bj)].status == CRITICAL) {
+ if (dragon[bb].matcher_status == CRITICAL) {
this_value = ???
- TRACE(" %m: %f - vital for %m\n",
- m, n, this_value, bi, bj);
+ TRACE(" %1m: %f - vital for %1m\n",
+ pos, this_value, bb);
tot_value += this_value;
}
#endif
@@ -3333,7 +3333,7 @@
continue;
}
-
+
TRACE(" %1m: %f - strategic effect on %1m\n",
pos, dragon_value[k], dragons[k]);
tot_value += dragon_value[k];
diff -ur gnugo-sync/engine/owl.c gnugo-iw2/engine/owl.c
--- gnugo-sync/engine/owl.c Wed Nov 21 20:44:20 2001
+++ gnugo-iw2/engine/owl.c Sat Nov 24 19:49:16 2001
@@ -339,7 +339,7 @@
if (other == BLACK)
owl_determine_life(owlb, owlb->black_eye,
- BLACK, komaster, 0,
+ BLACK, komaster, 0, /* FIXME: Why 0? */
vital_offensive_moves,
&probable_minb, &probable_maxb);
else
diff -ur gnugo-sync/engine/reading.c gnugo-iw2/engine/reading.c
--- gnugo-sync/engine/reading.c Fri Nov 16 18:49:04 2001
+++ gnugo-iw2/engine/reading.c Sat Nov 24 20:18:20 2001
@@ -134,6 +134,8 @@
/* ================================================================ */
+/* Persistent reading cache */
+/* ================================================================ */
/* Persistent reading cache to reuse read results between moves and
@@ -758,6 +760,95 @@
}
+/* ---------------------------------------------------------------- */
+/* Threats */
+/* ---------------------------------------------------------------- */
+
+
+/* Return up to max_threats threats to capture the string at pos.
+ * If the string is directly attackable the number of threats
+ * is reported to be 0.
+ *
+ * FIXME: Shall we report upgrades, like we can capture in ko but
+ * have a threat to capture unconditionally.
+ */
+
+int
+attack_threats(int pos, int moves[MAX_TACTICAL_POINTS],
+ int codes[MAX_TACTICAL_POINTS])
+{
+ int other;
+ int num_threats;
+ int liberties;
+ int libs[MAXLIBS];
+ int k;
+ int l;
+
+ ASSERT1(IS_STONE(board[pos]), pos);
+ other = OTHER_COLOR(board[pos]);
+
+ /* Only handle strings with no way to capture immediately.
+ * For now, we treat ko the same as unconditionally. */
+ if (attack(pos, NULL) != 0)
+ return 0;
+
+ num_threats = 0;
+
+ /* This test would seem to be unnecessary since we only attack
+ * strings with attack_code == 0, but it turns out that single
+ * stones with one liberty that can be captured, but come to
+ * live again in a snap-back get attack_code == 0.
+ *
+ * The test against 6 liberties is just an optimization.
+ */
+ liberties = findlib(pos, MAXLIBS, libs);
+ if (liberties > 1 && liberties < 6) {
+ for (k = 0; k < liberties && num_threats < MAX_TACTICAL_POINTS; k++) {
+ int aa = libs[k];
+
+ /* Try to threaten on the liberty. */
+ if (trymove(aa, other, "threaten attack", pos, EMPTY, NO_MOVE)) {
+ int acode = attack(pos, NULL);
+ if (acode != 0 && !tactical_move_known(aa, moves, codes)) {
+ moves[num_threats] = aa;
+ codes[num_threats] = acode;
+ num_threats++;
+ }
+ popgo();
+ }
+ if (num_threats == MAX_TACTICAL_POINTS)
+ break;
+
+ /* Try to threaten on second order liberties. */
+ for (l = 0; l < 4; l++) {
+ int bb = libs[k] + delta[l];
+
+ if (!ON_BOARD(bb)
+ || IS_STONE(board[bb])
+ || liberty_of_string(bb, pos))
+ continue;
+
+ if (trymove(bb, other, "threaten attack", pos, EMPTY, NO_MOVE)) {
+ int acode = attack(pos, NULL);
+ if (acode != 0 && !tactical_move_known(bb, moves, codes)) {
+ moves[num_threats] = bb;
+ codes[num_threats] = acode;
+ num_threats++;
+ }
+ popgo();
+ }
+ }
+ }
+ }
+
+
+ /* FIXME: Threaten to attack by saving weak neighbors.
+ * Get it from worm.c. */
+
+ return num_threats;
+}
+
+
/* ================================================================ */
/* Defensive functions */
/* ================================================================ */
@@ -917,7 +1008,6 @@
num_moves = 1;
break_chain_moves(str, moves, scores, &num_moves);
-
order_moves(str, num_moves, moves, scores, color, read_function_name);
for (k = 0; k < num_moves; k++) {
@@ -4498,6 +4588,7 @@
break_chain_moves(str, moves, scores, &num_moves);
order_moves(str, num_moves, moves, scores, color, read_function_name);
+
for (k = 0; k < num_moves; k++) {
int ko_capture;
diff -ur gnugo-sync/engine/utils.c gnugo-iw2/engine/utils.c
--- gnugo-sync/engine/utils.c Fri Oct 26 21:07:13 2001
+++ gnugo-iw2/engine/utils.c Sat Nov 24 19:40:58 2001
@@ -465,6 +465,7 @@
#define KO_DEPTH 8
#define AA_DEPTH 6
+#define AA_THREAT_DEPTH 1
/* Pattern based reading */
#define OWL_DISTRUST_DEPTH 6
@@ -493,6 +494,7 @@
branch_depth = gg_max(3, BRANCH_DEPTH - 10 + level);
fourlib_depth = gg_max(1, FOURLIB_DEPTH - 10 + level);
aa_depth = gg_max(0, AA_DEPTH - 10 + level);
+ aa_threat_depth = gg_max(0, AA_THREAT_DEPTH - 10 + level);
owl_distrust_depth = gg_max(1, OWL_DISTRUST_DEPTH - 5 + level/2);
owl_branch_depth = gg_max(2, OWL_BRANCH_DEPTH - 5 + level/2);
owl_reading_depth = gg_max(5, OWL_READING_DEPTH - 5 + level/2);
@@ -514,6 +516,7 @@
else
fourlib_depth = gg_max(1, FOURLIB_DEPTH - 9 + level);
aa_depth = gg_max(0, AA_DEPTH - 10 + level);
+ aa_threat_depth = gg_max(0, AA_THREAT_DEPTH - 10 + level);
owl_distrust_depth = gg_max(1, OWL_DISTRUST_DEPTH - 5
+ (level+1)/2);
owl_branch_depth = gg_max(2, OWL_BRANCH_DEPTH - 5 + (level+1)/2);
@@ -535,6 +538,7 @@
else
fourlib_depth = gg_max(1, FOURLIB_DEPTH - 1);
aa_depth = gg_max(0, AA_DEPTH - 2);
+ aa_threat_depth = gg_max(0, AA_THREAT_DEPTH - 2);
owl_distrust_depth = gg_max(1, OWL_DISTRUST_DEPTH - 1);
owl_branch_depth = gg_max(2, OWL_BRANCH_DEPTH - 5 + (level+1)/2);
owl_reading_depth = gg_max(5, OWL_READING_DEPTH - 5 + (level+1)/2);
@@ -555,6 +559,7 @@
else
fourlib_depth = gg_max(1, FOURLIB_DEPTH - 8 + level);
aa_depth = gg_max(0, AA_DEPTH - 9 + level);
+ aa_threat_depth = gg_max(0, AA_THREAT_DEPTH - 9 + level);
owl_distrust_depth = gg_max(1, OWL_DISTRUST_DEPTH - 5
+ (level+1)/2);
owl_branch_depth = gg_max(2, OWL_BRANCH_DEPTH - 4 + level/2);
@@ -582,6 +587,8 @@
branch_depth = mandated_branch_depth;
if (mandated_aa_depth != -1)
aa_depth = mandated_aa_depth;
+ if (mandated_aa_threat_depth != -1)
+ aa_threat_depth = mandated_aa_threat_depth;
if (mandated_owl_distrust_depth != -1)
owl_distrust_depth = mandated_owl_distrust_depth;
if (mandated_owl_branch_depth != -1)
diff -ur gnugo-sync/engine/worm.c gnugo-iw2/engine/worm.c
--- gnugo-sync/engine/worm.c Sat Nov 10 23:52:50 2001
+++ gnugo-iw2/engine/worm.c Sat Nov 24 20:23:51 2001
@@ -33,6 +33,7 @@
static void find_worm_attacks_and_defenses(void);
static void find_worm_threats(void);
static int find_lunch(int str, int *lunch);
+#if 0
static int tactical_move_known(int move, int points[MAX_TACTICAL_POINTS],
int codes[MAX_TACTICAL_POINTS]);
static void change_tactical_point(int str, int move, int code,
@@ -40,6 +41,7 @@
int codes[MAX_TACTICAL_POINTS]);
static void sort_tactical_points(int points[MAX_TACTICAL_POINTS],
int codes[MAX_TACTICAL_POINTS]);
+#endif
static void swap_points_and_codes(int points[MAX_TACTICAL_POINTS],
int codes[MAX_TACTICAL_POINTS],
int m, int n);
@@ -1265,7 +1267,8 @@
* and return the attack threat code. If (move) is not listed, return
* 0.
*/
-int attack_threat_move_known(int move, int str)
+int
+attack_threat_move_known(int move, int str)
{
return tactical_move_known(move, worm[str].attack_threat_points,
worm[str].attack_threat_codes);
@@ -1275,14 +1278,15 @@
* and return the defense threat code. If (move) is not listed, return
* 0.
*/
-int defense_threat_move_known(int move, int str)
+int
+defense_threat_move_known(int move, int str)
{
return tactical_move_known(move, worm[str].defense_threat_points,
worm[str].defense_threat_codes);
}
/* Do the real work for the functions above. */
-static int
+int
tactical_move_known(int move, int points[MAX_TACTICAL_POINTS],
int codes[MAX_TACTICAL_POINTS])
{
@@ -1303,7 +1307,7 @@
* change_defense_threat().
*/
-static void
+void
change_tactical_point(int str, int move, int code,
int points[MAX_TACTICAL_POINTS],
int codes[MAX_TACTICAL_POINTS])
@@ -1347,7 +1351,7 @@
* loop.
*/
-static void
+void
sort_tactical_points(int points[MAX_TACTICAL_POINTS],
int codes[MAX_TACTICAL_POINTS])
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnugo-devel] PATCH: atari-atari enhanced; now working,
Inge Wallin <=