[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] PATCH: enhanced atari_atari
From: |
Inge Wallin |
Subject: |
[gnugo-devel] PATCH: enhanced atari_atari |
Date: |
Fri, 23 Nov 2001 19:56:09 +0100 (CET) |
Here is the patch that I described in my last mail. Note that it
kind of works, but that it finds bogus sequences. I have not run the
regressions on it yet either.
-Inge
================================================================
Index: engine/combination.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/combination.c,v
retrieving revision 1.5
diff -u -r1.5 combination.c
--- engine/combination.c 2001/11/15 23:54:48 1.5
+++ engine/combination.c 2001/11/23 18:54:11
@@ -37,6 +37,8 @@
/* 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. */
@@ -231,8 +236,121 @@
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.
+ */
+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;
+ }
+}
+
-/* Helper function for computing the aa_status for a string. */
+/* 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,7 @@
* equivalent to a return value of 0.
*/
+#define MAX_THREAT_MOVES 10
static int
do_atari_atari(int color, int *attack_point, int *defense_point,
int last_friendly, int save_verbose, int minsize)
@@ -361,65 +482,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 +502,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,218 +521,198 @@
if (status != ALIVE)
continue;
- if (findlib(pos, 2, libs) != 2)
- continue;
+ if (stackp < aa_threat_depth) {
+ int i;
+ num_moves = attack_threats(pos, MAX_THREAT_MOVES, moves, codes);
+ if (num_moves > 0) {
+ 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])
+ continue;
- if (!forbidden[apos]
- && (accurate_approxlib(apos, color, 2, NULL) > 1
- || safe_move(apos, color))) {
- if (trymove(apos, color, "do_atari_atari-A", pos,
+ if (accurate_approxlib(apos, color, 2, NULL) < 2
+ && !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)) {
- /* try to defend the stone (m,n) which is in atari */
- int aa_val = 0;
+ /* 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);
+ }
- /* 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 (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();
-
- 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;
- }
+ for (m = 0; m < board_size; m++)
+ for (n = 0; n < board_size; n++) {
+ int ii = POS(m, n);
+ int aa;
- 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 (board[ii] != other)
+ continue;
- 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;
- }
-}
+ if (ii != find_origin(ii))
+ continue;
+ if (minsize > 0 && countstones(ii) < minsize)
+ continue;
-/* 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.
- */
+ if (get_aa_status(ii) != ALIVE)
+ continue;
-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 (board[last_friendly] != EMPTY
+ && !adjacent_strings(last_friendly, ii))
+ continue;
- if (aa_depth < 2)
- return 0;
- if (verbose > 0)
- verbose--;
- memset(forbidden, 0, sizeof(forbidden));
+ 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);
- compute_aa_status(color);
+ 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;
+ }
+ }
+ }
- 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();
+ DEBUG(DEBUG_ATARI_ATARI, "%oreturn value:%d (%1m)\n",
+ countstones(ii), ii);
+ return countstones(ii);
+ }
}
- popgo();
- }
- verbose = save_verbose;
- return aa_val;
+
+ return 0;
}
Index: engine/dragon.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/dragon.c,v
retrieving revision 1.29
diff -u -r1.29 dragon.c
--- engine/dragon.c 2001/11/23 14:08:42 1.29
+++ engine/dragon.c 2001/11/23 18:54:11
@@ -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);
Index: engine/globals.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/globals.c,v
retrieving revision 1.11
diff -u -r1.11 globals.c
--- engine/globals.c 2001/10/16 19:53:01 1.11
+++ engine/globals.c 2001/11/23 18:54:11
@@ -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;
Index: engine/gnugo.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/gnugo.h,v
retrieving revision 1.23
diff -u -r1.23 gnugo.h
--- engine/gnugo.h 2001/11/23 03:06:22 1.23
+++ engine/gnugo.h 2001/11/23 18:54:11
@@ -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;
Index: engine/influence.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/influence.c,v
retrieving revision 1.20
diff -u -r1.20 influence.c
--- engine/influence.c 2001/11/14 19:16:28 1.20
+++ engine/influence.c 2001/11/23 18:54:11
@@ -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) {
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.47
diff -u -r1.47 liberty.h
--- engine/liberty.h 2001/11/23 03:06:22 1.47
+++ engine/liberty.h 2001/11/23 18:54:11
@@ -229,6 +229,7 @@
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 max_threats, int moves[], int codes[]);
int restricted_defend1(int str, int *move, int komaster, int kom_pos,
int num_forbidden_moves, int *forbidden_moves);
@@ -516,6 +517,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 */
@@ -586,8 +588,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];
@@ -615,7 +617,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 */
Index: engine/move_reasons.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.c,v
retrieving revision 1.40
diff -u -r1.40 move_reasons.c
--- engine/move_reasons.c 2001/11/22 15:58:03 1.40
+++ engine/move_reasons.c 2001/11/23 18:54:12
@@ -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];
Index: engine/reading.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/reading.c,v
retrieving revision 1.31
diff -u -r1.31 reading.c
--- engine/reading.c 2001/11/15 16:18:40 1.31
+++ engine/reading.c 2001/11/23 18:54:13
@@ -134,6 +134,8 @@
/* ================================================================ */
+/* Persistent reading cache */
+/* ================================================================ */
/* Persistent reading cache to reuse read results between moves and
@@ -758,6 +760,94 @@
}
+/* ---------------------------------------------------------------- */
+/* 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 max_threats, int moves[], int codes[])
+{
+ 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_threats; 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) {
+ moves[num_threats] = aa;
+ codes[num_threats] = acode;
+ num_threats++;
+ }
+ popgo();
+ }
+ if (num_threats == max_threats)
+ 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) {
+ 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 +1007,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 +4587,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;
Index: engine/utils.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/utils.c,v
retrieving revision 1.24
diff -u -r1.24 utils.c
--- engine/utils.c 2001/10/26 07:21:11 1.24
+++ engine/utils.c 2001/11/23 18:54:14
@@ -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)
Index: regression/niki.tst
===================================================================
RCS file: /cvsroot/gnugo/gnugo/regression/niki.tst,v
retrieving revision 1.10
diff -u -r1.10 niki.tst
--- regression/niki.tst 2001/11/18 05:33:02 1.10
+++ regression/niki.tst 2001/11/23 18:54:14
@@ -66,10 +66,9 @@
#DESCRIPTION=Very tough position
#SEVERITY=3
#Note: G16 is still very very big. See niki.tst#8 & nikit.tst#9
-# FIXME: Same move listed twice.
loadsgf games/niki.sgf 158
11 gg_genmove white
-#? [M6|M6|P7]*
+#? [M6|P6|P7]*
#CATEGORY=OWL_TUNING
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnugo-devel] PATCH: enhanced atari_atari,
Inge Wallin <=