[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [gnugo-devel] Eye pattern 304
From: |
Paul Pogonyshev |
Subject: |
Re: [gnugo-devel] Eye pattern 304 |
Date: |
Mon, 5 May 2003 23:45:28 -0400 |
User-agent: |
KMail/1.5.9 |
here is the patch rediffed with comments in.
Paul
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.167
diff -u -p -r1.167 liberty.h
--- engine/liberty.h 4 May 2003 11:20:00 -0000 1.167
+++ engine/liberty.h 5 May 2003 20:35:03 -0000
@@ -51,9 +51,10 @@ extern Hash_data hashdata;
/* ================================================================ */
-#define FALSE_EYE 1
-#define HALF_EYE 2
-#define INHIBIT_CONNECTION 4
+#define FALSE_EYE 1
+#define HALF_EYE 2
+#define INHIBIT_CONNECTION 4
+#define INESSENTIAL_MARGINAL 8
/* A string with n stones can have at most 2(n+1) liberties. From this
Index: engine/optics.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/optics.c,v
retrieving revision 1.73
diff -u -p -r1.73 optics.c
--- engine/optics.c 4 May 2003 11:20:00 -0000 1.73
+++ engine/optics.c 5 May 2003 20:35:10 -0000
@@ -1123,48 +1123,49 @@ recognize_eye(int pos, int *attack_point
if (eye[pos].msize > MAXEYE)
return 0;
- /* Create list of eye vertices */
+ /* Create list of eye vertices. Ignore inessential marginals. */
for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++) {
- if (!ON_BOARD(pos2))
+ if (!ON_BOARD(pos2)
+ || eye[pos2].origin != pos
+ || (heye[pos2].type & INESSENTIAL_MARGINAL))
continue;
- if (eye[pos2].origin == pos) {
- vpos[eye_size] = pos2;
- marginal[eye_size] = eye[pos2].marginal;
+
+ vpos[eye_size] = pos2;
+ marginal[eye_size] = eye[pos2].marginal;
+ if (marginal[eye_size])
+ num_marginals++;
+ neighbors[eye_size] = eye[pos2].neighbors;
+ if (0) {
if (marginal[eye_size])
- num_marginals++;
- neighbors[eye_size] = eye[pos2].neighbors;
- if (0) {
- if (marginal[eye_size])
- TRACE("(%1m)", vpos[eye_size]);
- else
- TRACE(" %1m ", vpos[eye_size]);
- TRACE("\n");
- }
-
- if (is_corner_vertex(pos2))
- edge[eye_size] = 2;
- else if (is_edge_vertex(pos2))
- edge[eye_size] = 1;
- else
- edge[eye_size] = 0;
-
- if (is_halfeye(heye, pos2)) {
- neighbors[eye_size]++; /* Increase neighbors of half eye. */
- eye_size++;
- /* Use a virtual marginal vertex for mapping purposes. We set it
- * to be at NO_MOVE so it won't accidentally count as a
- * neighbor for another vertex. Note that the half eye precedes
- * the virtual marginal vertex in the list.
- */
- vpos[eye_size] = NO_MOVE;
- marginal[eye_size] = 1;
- num_marginals++;
- edge[eye_size] = 0;
- neighbors[eye_size] = 1;
- }
-
+ TRACE("(%1m)", vpos[eye_size]);
+ else
+ TRACE(" %1m ", vpos[eye_size]);
+ TRACE("\n");
+ }
+
+ if (is_corner_vertex(pos2))
+ edge[eye_size] = 2;
+ else if (is_edge_vertex(pos2))
+ edge[eye_size] = 1;
+ else
+ edge[eye_size] = 0;
+
+ if (is_halfeye(heye, pos2)) {
+ neighbors[eye_size]++; /* Increase neighbors of half eye. */
eye_size++;
+ /* Use a virtual marginal vertex for mapping purposes. We set it
+ * to be at NO_MOVE so it won't accidentally count as a
+ * neighbor for another vertex. Note that the half eye precedes
+ * the virtual marginal vertex in the list.
+ */
+ vpos[eye_size] = NO_MOVE;
+ marginal[eye_size] = 1;
+ num_marginals++;
+ edge[eye_size] = 0;
+ neighbors[eye_size] = 1;
}
+
+ eye_size++;
}
/* We attempt to construct a map from the graph to the eyespace
@@ -1488,25 +1489,50 @@ next_map(int *q, int map[MAXEYE])
}
-/* add_false_eye() turns a proper eyespace into a margin. */
-
+/* add_false_eye() turns a proper eyespace into a margin. It also turns
+ * neighbor marginals into inessential when some conditions are met.
+ * Consider this example:
+ *
+ * ...O.
+ * XXXOX
+ * X....
+ *
+ * When the topological algorithm does its job, the eye is turned from
+ * '..!' to '.!!'. Since we prohibit such eyespaces, the easiest way to
+ * work it around is to ignore the right marginal vertex at graph matching
+ * stage. We mark it as "inessential" here and recognize_eye() ignores
+ * such marginals.
+ */
void
add_false_eye(int pos, struct eye_data eye[BOARDMAX],
struct half_eye_data heye[BOARDMAX])
{
int k;
+ int detach_neighbor_marginals;
ASSERT1(heye[pos].type == FALSE_EYE, pos);
DEBUG(DEBUG_EYES, "false eye found at %1m\n", pos);
if (eye[pos].color == GRAY || eye[pos].marginal != 0)
return;
-
+
eye[pos].marginal = 1;
eye[eye[pos].origin].msize++;
- for (k = 0; k < 4; k++)
- if (ON_BOARD(pos + delta[k])
- && eye[pos + delta[k]].origin == eye[pos].origin)
- eye[pos + delta[k]].marginal_neighbors++;
+ detach_neighbor_marginals = (eye[pos].neighbors > 1 && is_edge_vertex(pos));
+
+ for (k = 0; k < 4; k++) {
+ int neighbor = pos + delta[k];
+ if (ON_BOARD(neighbor) && eye[neighbor].origin == eye[pos].origin) {
+ eye[neighbor].marginal_neighbors++;
+ if (detach_neighbor_marginals
+ && eye[neighbor].marginal
+ && eye[neighbor].neighbors == 1) {
+ heye[neighbor].type |= INESSENTIAL_MARGINAL;
+ eye[pos].neighbors--;
+ eye[pos].marginal_neighbors--;
+ }
+ }
+ }
+
propagate_eye(eye[pos].origin, eye);
}
@@ -1589,8 +1615,12 @@ find_half_and_false_eyes(int color, stru
/* skip every vertex which can't be a false or half eye */
if (eye[pos].color != eye_color
- || eye[pos].marginal
- || eye[pos].neighbors > 1)
+ || eye[pos].marginal
+#if 0
+ || (eye[pos].neighbors > 1 && !is_edge_vertex(pos)))
+#else
+ || eye[pos].neighbors > 1)
+#endif
continue;
sum = topological_eye(pos, color, eye, heye);
Index: engine/owl.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v
retrieving revision 1.156
diff -u -p -r1.156 owl.c
--- engine/owl.c 4 May 2003 11:39:48 -0000 1.156
+++ engine/owl.c 5 May 2003 20:35:22 -0000
@@ -4479,18 +4479,19 @@ owl_find_lunches(struct local_owl_data *
}
-/* Try to improve the move to attack a lunch. Essentially we try to
- * avoid unsafe moves when there are less risky ways to attack.
+/* Try to improve the move to attack a lunch. Essentially we try to avoid
+ * unsafe moves when there are less risky ways to attack.
*
- * This function also improves lunch attack point in this special case:
+ * This function also improves lunch attack point in a special case when
+ * we capture a one- or two-stone lunch on the first line. If we eat it
+ * with a first line move, there is a huge risk we'll end up with a false
+ * eye. Therefore, we move the attack to the second line when it works.
*
- * |.XXX In this case it is better to play A2 rather than A1 since
- * |XXOO it saves an eye in the corner. We replace attack point if
- * |XO.. three conditions are satisfied:
- * |.O.O a) lunch is a single stone
- * |.XO. b) it's attack point is a corner point
- * +---- c) it has no neighbors in atari
+ * .*OO .*OOO .*OOOO
+ * .,XO .,X.O .,XX.O
+ * ---- ----- ------
*
+ * In all these position the attack point is moved from ',' to '*'.
*/
static int
improve_lunch_attack(int lunch, int attack_point)
@@ -4501,19 +4502,28 @@ improve_lunch_attack(int lunch, int atta
int adj[MAXCHAIN];
if (safe_move(attack_point, color)) {
- if (countstones(lunch) == 1 && is_corner_vertex(attack_point)
- && chainlinks2(lunch, adj, 1) == 0) {
- for (k = 0; k < 4; k++) {
- int apos = attack_point + delta[k];
+ if (is_edge_vertex(lunch)
+ && is_edge_vertex(attack_point)
+ && neighbor_of_string(attack_point, lunch)) {
+ int stones = countstones(lunch);
+ int libs[2];
- if (board[apos] == EMPTY) {
- if (safe_move(apos, color))
- return apos;
- break;
+ if (stones == 1
+ || (stones == 2
+ && findlib(lunch, 2, libs) == 2
+ && is_edge_vertex(libs[0])
+ && is_edge_vertex(libs[1]))) {
+ for (k = 0; k < 4; k++) {
+ int apos = attack_point + delta[k];
+ if (!ON_BOARD(attack_point - delta[k]) && board[apos] == EMPTY) {
+ if (does_attack(apos, lunch) && safe_move(apos, color))
+ return apos;
+ break;
+ }
}
}
}
-
+
return attack_point;
}
Index: patterns/owl_defendpats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_defendpats.db,v
retrieving revision 1.92
diff -u -p -r1.92 owl_defendpats.db
--- patterns/owl_defendpats.db 2 May 2003 15:04:59 -0000 1.92
+++ patterns/owl_defendpats.db 5 May 2003 20:35:33 -0000
@@ -824,20 +824,21 @@ xx...X. slide (usually inferior t
:8,-,value(70)
-Pattern D219
-# tm Modified (3.1.17)
-
-OO* capture edge stone to maybe make eye
-.X.
----
-
-:8,-,value(50)
-
-OO*
-aA.
----
-
-;does_attack(*,A) && !obvious_false_oeye(a)
+# pp Removed (3.3.20). This job is now done by improve_lunch_attack().
+#Pattern D219
+## tm Modified (3.1.17)
+#
+#OO* capture edge stone to maybe make eye
+#.X.
+#---
+#
+#:8,-,value(50)
+#
+#OO*
+#aA.
+#---
+#
+#;does_attack(*,A) && !obvious_false_oeye(a)
Pattern D220