[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] owl goal dragon gets cut
From: |
Arend Bayer |
Subject: |
[gnugo-devel] owl goal dragon gets cut |
Date: |
Mon, 23 Aug 2004 01:27:22 +0200 (CEST) |
- infrastructure to split goal dragon in owl
- new pattern class "C" in owl attack patterns to designate possible cuts
This tries to address one of the well-known problem of the owl code. So far
it does not notice at all when the goal dragon gets split.
This patch is a very hands-down approach to try to teach it about splitting
dragons. The idea is to mark all attack moves that threaten a cut (peep etc.)
with class "C" in the pattern database. If such a move gets played, it is
analyzed whether the goal strings that belong to the pattern area are
still connected (explicitly ignoring intransitivity for now).
Say there were two strings, and they can be cut now. Then we compute the
distance map from both strings (using the readconnect code), and build two
components of the goal by assigning each stone to the string to which it is
closer. The new goal is then the bigger of the two components.
I would very much appreciate comments/ideas on this approach.
What this patch does not (yet?) do:
- Consider cuts that arise from saving an owl lunch.
- Make a difference in the result when only a part of the dragon lives.
(I hope to merge this with Nando's experimental-owl stuff.)
Arend
16 PASS, 9 FAIL (not much analyzed yet):
blunder:21 PASS L9 [L9]
strategy:8 FAIL F1 [N2|N1]
arb:210 PASS D8 [D8]
strategy2:73 PASS P15 [F7|R17|P15]
trevor:630 PASS 1 H13 [1 H13]
nngs:510 PASS G14 [G14]
nngs:875 FAIL E7 [C5]
global:34 FAIL F3 [N6]
vie:8 PASS 1 S9 [1 (R8|S9)]
arend:9 FAIL S2 [S17]
13x13:36 PASS C5 [C5]
strategy4:182 FAIL S11 [E7|F8]
strategy4:188 PASS C4 [B6|C4]
strategy4:206 FAIL K6 [L8]
owl1:311 PASS 1 E2 [1 E2]
owl1:324 PASS 0 [0]
nngs3:230 PASS E12 [!L12]
nngs3:250 FAIL G13 [G11]
nngs3:350 PASS E12 [E12]
nngs4:230 PASS Q18 [Q18]
nngs4:650 FAIL G12 [Q2]
ninestones:630 PASS F5 [F5|H7]
ninestones:650 PASS Q5 [Q5]
gunnar:39 FAIL N1 [N4]
kgs:320 PASS K12 [K12]
Total nodes: 1528118224 2902051 11769770
Index: engine/gnugo.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/gnugo.h,v
retrieving revision 1.112
diff -u -p -r1.112 gnugo.h
--- engine/gnugo.h 19 Jul 2004 12:23:08 -0000 1.112
+++ engine/gnugo.h 22 Aug 2004 23:16:16 -0000
@@ -188,6 +188,7 @@ extern int output_flags; /* amount
#define DEBUG_MISCELLANEOUS 0x800000
#define DEBUG_ORACLE_STREAM 0x1000000
#define DEBUG_LARGE_SCALE 0x1000000
+#define DEBUG_SPLIT_OWL 0x2000000
/* hash flag bits
*
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.222
diff -u -p -r1.222 liberty.h
--- engine/liberty.h 21 Aug 2004 09:05:04 -0000 1.222
+++ engine/liberty.h 22 Aug 2004 23:16:16 -0000
@@ -286,6 +286,7 @@ void store_persistent_semeai_cache(enum
/* readconnect.c */
int string_connect(int str1, int str2, int *move);
int disconnect(int str1, int str2, int *move);
+int fast_disconnect(int str1, int str2, int *move);
int non_transitivity(int str1, int str2, int str3, int *move);
int break_in(int str, const char goal[BOARDMAX], int *move);
Index: engine/owl.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v
retrieving revision 1.218
diff -u -p -r1.218 owl.c
--- engine/owl.c 21 Aug 2004 09:05:04 -0000 1.218
+++ engine/owl.c 22 Aug 2004 23:16:18 -0000
@@ -51,6 +51,7 @@
#include <stdlib.h>
#include <string.h>
#include "liberty.h"
+#include "readconnect.h"
#include "patterns.h"
#include "cache.h"
#include "sgftree.h"
@@ -113,6 +114,8 @@ static int goal_worms_computed = 0;
static int owl_goal_worm[MAX_GOAL_WORMS];
+#define MAX_CUTS 5
+
struct owl_move_data {
int pos; /* move coordinate */
int value; /* value */
@@ -121,6 +124,7 @@ struct owl_move_data {
int lunch; /* Position of a lunch, if applicable.*/
int escape; /* true if an escape pattern is matched */
int defense_pos; /* defense coordinate for vital owl attack patterns. */
+ int cuts[MAX_CUTS]; /* strings of the goal that might get cut off */
};
#define USE_BDIST 1
@@ -129,6 +133,7 @@ struct matched_pattern_data {
int move;
int value;
int ll;
+ int anchor;
#if USE_BDIST
int bdist;
#endif
@@ -172,7 +177,7 @@ static void pattern_list_sink_heap_top_e
static int get_next_move_from_list(struct matched_patterns_list_data *list,
int color, struct owl_move_data *moves,
- int cutoff);
+ int cutoff, struct local_owl_data *owl);
static void init_pattern_list(struct matched_patterns_list_data *list);
static void close_pattern_list(int color,
struct matched_patterns_list_data *list);
@@ -208,6 +213,8 @@ static void owl_mark_worm(int apos, int
static void owl_mark_boundary(struct local_owl_data *owl);
static void owl_update_goal(int pos, int same_dragon, int lunch,
struct local_owl_data *owl, int semeai_call);
+static void owl_test_cuts(char goal[BOARDMAX], int color, int cuts[MAX_CUTS]);
+static void componentdump(const char goal[BOARDMAX]);
static void owl_update_boundary_marks(int pos, struct local_owl_data *owl);
static void owl_find_lunches(struct local_owl_data *owl);
static int improve_lunch_attack(int lunch, int attack_point);
@@ -314,6 +321,17 @@ static int prefer_ko;
static int include_semeai_worms_in_eyespace = 0;
+
+static void
+clear_cut_list(int cuts[MAX_CUTS])
+{
+ int i;
+ for (i = 0; i < MAX_CUTS; i++)
+ cuts[i] = NO_MOVE;
+}
+
+
+
/* Called when (apos) and (bpos) point to adjacent dragons
* of the opposite color, both with matcher_status DEAD or
* CRITICAL, analyzes the semeai, assuming that the player
@@ -672,6 +690,7 @@ do_owl_analyze_semeai(int apos, int bpos
moves[k].name = NULL;
moves[k].same_dragon = 2;
moves[k].lunch = NO_MOVE;
+ clear_cut_list(moves[k].cuts);
}
ASSERT1(other == board[bpos], bpos);
memset(mw, 0, sizeof(mw));
@@ -831,14 +850,14 @@ do_owl_analyze_semeai(int apos, int bpos
owla, &owl_defendpat_db);
for (k = 0; k < MAX_MOVES-1; k++)
if (!get_next_move_from_list(&shape_defensive_patterns, color,
- shape_defensive_moves, 1))
+ shape_defensive_moves, 1, owla))
break;
}
owl_shapes(&shape_offensive_patterns, shape_offensive_moves, color, owlb,
&owl_attackpat_db);
for (k = 0; k < MAX_MOVES-1; k++)
if (!get_next_move_from_list(&shape_offensive_patterns, color,
- shape_offensive_moves, 1))
+ shape_offensive_moves, 1, owla))
break;
/* Now we review the moves already considered, while collecting
@@ -1623,6 +1642,7 @@ clear_owl_move_data(struct owl_move_data
moves[k].same_dragon = 2;
moves[k].escape = 0;
moves[k].lunch = NO_MOVE;
+ clear_cut_list(moves[k].cuts);
}
}
@@ -1636,6 +1656,7 @@ set_single_owl_move(struct owl_move_data
moves[0].same_dragon = 1;
moves[0].escape = 0;
moves[0].lunch = NO_MOVE;
+ clear_cut_list(moves[0].cuts);
moves[1].value = 0;
}
@@ -2010,7 +2031,7 @@ do_owl_attack(int str, int *move, int *w
/* Shape moves are selected on demand. */
if (pass == 1) {
if (!get_next_move_from_list(&shape_patterns, other,
- shape_moves, move_cutoff))
+ shape_moves, move_cutoff, owl))
break;
}
else
@@ -2056,12 +2077,15 @@ do_owl_attack(int str, int *move, int *w
origin = NO_MOVE;
for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
if (board[pos] == color && owl->goal[pos] == 1) {
- origin = find_origin(pos);
- break;
+ origin = find_origin(pos);
+ break;
}
}
}
+ if (moves[k].cuts[0] != NO_MOVE)
+ owl_test_cuts(owl->goal, owl->color, moves[k].cuts);
+
if (origin == NO_MOVE)
dcode = 0;
else
@@ -2220,7 +2244,7 @@ owl_threaten_attack(int target, int *att
owl_shapes(&shape_patterns, moves, other, owl, &owl_attackpat_db);
for (k = 0; k < MAX_MOVES; k++) {
current_owl_data = owl;
- if (!get_next_move_from_list(&shape_patterns, other, moves, 1))
+ if (!get_next_move_from_list(&shape_patterns, other, moves, 1, owl))
break;
else {
int mpos = moves[k].pos;
@@ -2374,7 +2398,7 @@ owl_defend(int target, int *defense_poin
static int
do_owl_defend(int str, int *move, int *wormid,
struct local_owl_data *owl,
- int escape)
+ int escape)
{
int color = board[str];
struct owl_move_data shape_moves[MAX_MOVES];
@@ -2597,7 +2621,7 @@ do_owl_defend(int str, int *move, int *w
if (pass == 1) {
if (!get_next_move_from_list(&shape_patterns, color, shape_moves,
- move_cutoff))
+ move_cutoff, owl))
break;
}
else
@@ -2741,7 +2765,7 @@ owl_threaten_defense(int target, int *de
owl_shapes(&shape_patterns, moves, color, owl, &owl_defendpat_db);
for (k = 0; k < MAX_MOVES; k++) {
current_owl_data = owl;
- if (!get_next_move_from_list(&shape_patterns, color, moves, 1))
+ if (!get_next_move_from_list(&shape_patterns, color, moves, 1, owl))
break;
else {
if (moves[k].pos != NO_MOVE && moves[k].value > 0)
@@ -3631,6 +3655,7 @@ collect_owl_shapes_callbacks(int anchor,
next_pattern->move = AFFINE_TRANSFORM(pattern->move_offset, ll, anchor);
next_pattern->value = pattern->value;
next_pattern->ll = ll;
+ next_pattern->anchor = anchor;
next_pattern->pattern = pattern;
next_pattern->next_pattern_index = -1;
@@ -3944,6 +3969,37 @@ pattern_list_sink_heap_top_element(struc
}
+/* Adds all goal strings in the pattern area to the cuts[] list, if there
+ * is more than one.
+ */
+static void
+generate_cut_list(struct pattern *pattern, int ll, int anchor,
+ int cuts[MAX_CUTS], struct local_owl_data *owl)
+{
+ int k;
+ int num = 0;
+ char mark[BOARDMAX];
+
+ memset(mark, 0, BOARDMAX);
+ for (k = 0; k < pattern->patlen; k++) {
+ int pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor);
+ if (!IS_STONE(board[pos]))
+ continue;
+ pos = find_origin(pos);
+ if (!mark[pos] && board[pos] == owl->color && owl->goal[pos]) {
+ cuts[num++] = pos;
+ mark[pos] = 1;
+ if (num == MAX_CUTS)
+ return;
+ }
+ }
+ if (num == 1)
+ cuts[0] = NO_MOVE;
+ else if ((debug & DEBUG_SPLIT_OWL) && num > 1)
+ gprintf("Move provokes %d cuts, among them %1m and %1m.\n", num,
+ cuts[0], cuts[1]);
+}
+
/* This function searches in the previously stored list of matched
* patterns for the highest valued unused patterns that have a valid
* constraint. It returns the moves at the next empty positions in
@@ -3965,7 +4021,8 @@ pattern_list_sink_heap_top_element(struc
static int
get_next_move_from_list(struct matched_patterns_list_data *list, int color,
- struct owl_move_data *moves, int cutoff)
+ struct owl_move_data *moves, int cutoff,
+ struct local_owl_data *owl)
{
int move_found = 0;
SGFTree *save_sgf_dumptree = sgf_dumptree;
@@ -3984,6 +4041,7 @@ get_next_move_from_list(struct matched_p
int move;
int value;
int ll;
+ int anchor;
int next_pattern_index;
/* Peek top element of heap associated with pattern list. */
@@ -3994,6 +4052,7 @@ get_next_move_from_list(struct matched_p
move = list->pattern_heap[0]->move;
value = list->pattern_heap[0]->value;
ll = list->pattern_heap[0]->ll;
+ anchor = list->pattern_heap[0]->anchor;
next_pattern_index = list->pattern_heap[0]->next_pattern_index;
list->used++;
@@ -4037,6 +4096,7 @@ get_next_move_from_list(struct matched_p
moves[k].pos = move;
moves[k].value = value;
+ clear_cut_list(moves[k].cuts);
move_found = 1;
if (pattern && !(pattern->class & CLASS_c)) {
@@ -4044,6 +4104,16 @@ get_next_move_from_list(struct matched_p
TRACE("Pattern %s found at %1m with value %d\n",
pattern->name, move, moves[k].value);
+ if (pattern->class & CLASS_C) {
+ /* Cut possible. (Only used in attack patterns). Try to find
+ * goal strings in the pattern area and store them in the cut list
+ * if there is more than one.
+ */
+ DEBUG(DEBUG_SPLIT_OWL,
+ "Generating cut list for move at %1m.\n", move);
+ generate_cut_list(pattern, ll, anchor, moves[k].cuts, owl);
+ }
+
if (pattern->class & CLASS_B)
moves[k].same_dragon = 0;
else if (pattern->class & CLASS_b) {
@@ -4534,6 +4604,196 @@ owl_update_goal(int pos, int same_dragon
goaldump(owl->goal);
}
+
+/* Computes the connected components of a the graph that is given by
+ * having graph[i][j] = 1 if i and j are connected, and that has size
+ * graph_size.
+ *
+ * This function is generic, but without having the fixed MAX_CUTS
+ * array size it is ugly to write in ANSI C89 (no variably sized arrays),
+ * so we leave it here for now.
+ */
+static int
+connected_components(char graph[MAX_CUTS][MAX_CUTS], int graph_size,
+ char component[MAX_CUTS])
+{
+ int num_components = 0;
+ int k, j;
+
+ if (graph_size <= 0)
+ return 0;
+
+ memset(component, -1, MAX_CUTS);
+ for (;;) {
+ int found_one;
+ /* Find unidentified string. */
+ for (k = 0; k < graph_size; k++)
+ if (component[k] == -1)
+ break;
+ if (k == graph_size)
+ break; /* All are identified. */
+ component[k] = num_components; /* Start new component. */
+ do { /* Spread new component. */
+ found_one = 0;
+ for (j = k+1; j < graph_size; j++)
+ if (graph[k][j] && component[j] == -1) {
+ component[j] = num_components;
+ found_one = 1;
+ }
+ } while (found_one);
+ num_components++;
+ }
+ gg_assert(num_components > 0);
+ return num_components;
+}
+
+/* This functions gets called after a move has been made that threatens
+ * to cut the owl goal dragon. It cuts the goal if necessary, and sets it
+ * to the biggest remaining component.
+ */
+static void
+owl_test_cuts(char goal[BOARDMAX], int color, int cuts[MAX_CUTS])
+{
+ int k, j;
+ char connected[MAX_CUTS][MAX_CUTS];
+ /* int connect_move[MAX_CUTS][MAX_CUTS]; */
+ int num_cuts;
+ int found_cut = 0;
+ SGFTree *save_sgf_dumptree = sgf_dumptree;
+ int save_count_variations = count_variations;
+
+ sgf_dumptree = NULL;
+ count_variations = 0;
+
+ memset(connected, 1, MAX_CUTS*MAX_CUTS);
+ if (debug & DEBUG_SPLIT_OWL) {
+ gprintf("Called for this goal: ");
+ goaldump(goal);
+ gprintf("At this position:\n");
+ showboard(0);
+ }
+
+ /* Delete captured strings from list. */
+ for (k = 0; k < MAX_CUTS; k++) {
+ if (cuts[k] == NO_MOVE)
+ break;
+ if (board[cuts[k]] == EMPTY) {
+ for (j = k + 1; j < MAX_CUTS; j++) {
+ if (cuts[j] == NO_MOVE)
+ break;
+ cuts[j-1] = cuts[j];
+ }
+ cuts[k] = NO_MOVE;
+ k--;
+ }
+ }
+ num_cuts = k;
+
+ /* Test for each pair of strings in cuts[] whether it can now be
+ * disconnected.
+ */
+ for (k = 0; k < num_cuts; k++) {
+ ASSERT1(board[cuts[k]] == color, cuts[k]);
+ for (j = k + 1; j < num_cuts; j++)
+ if (fast_disconnect(cuts[k], cuts[j], NULL) == WIN) {
+ found_cut = 1;
+ connected[k][j] = 0;
+ connected[j][k] = 0;
+ }
+ }
+
+ if (found_cut) {
+ char component[MAX_CUTS];
+ char component2[BOARDMAX];
+ int component_size[MAX_CUTS];
+ int num_components;
+ int biggest_component = -1;
+ struct connection_data* conn_data;
+ int c_id;
+ int pos;
+
+ /* Start by computing the connected components among the strings
+ * listed in cuts[].
+ */
+ num_components = connected_components(connected, num_cuts, component);
+ if (num_components <= 1) {
+ sgf_dumptree = save_sgf_dumptree;
+ count_variations = save_count_variations;
+ return;
+ }
+
+ /* Now break up the goal by associating each goal stone to one of
+ * the connected components.
+ *
+ * First we compute the connection distances from each of the
+ * partial goals we have found.
+ */
+ memset(component2, -1, BOARDMAX);
+ memset(component_size, 0, sizeof(int) * num_components);
+ conn_data = malloc(sizeof(struct connection_data) * num_components);
+ for (c_id = 0; c_id < num_components; c_id++) {
+ char this_goal[BOARDMAX];
+ memset(this_goal, 0, BOARDMAX);
+
+ for (k = 0; k < num_cuts; k++)
+ if (component[k] == c_id) {
+ mark_string(cuts[k], this_goal, 1);
+ mark_string(cuts[k], component2, c_id);
+ }
+ init_connection_data(color, this_goal, NO_MOVE, 3.01,
+ conn_data + c_id, 1);
+ spread_connection_distances(color, conn_data + c_id);
+ }
+
+ /* Now put each goal string to the component to which it has the
+ * smallest distance.
+ */
+ for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+ float closest_dist = HUGE_CONNECTION_DISTANCE;
+ int closest_component = -1;
+ if (!goal[pos] || board[pos] != color)
+ continue;
+ if (pos != find_origin(pos))
+ continue;
+ for (c_id = 0; c_id < num_components; c_id++) {
+ if (conn_data[c_id].distances[pos] < closest_dist) {
+ closest_dist = conn_data[c_id].distances[pos];
+ closest_component = c_id;
+ }
+ }
+ /* FIXME: What to do if no close component found? */
+ if (closest_component != -1) {
+ mark_string(pos, component2, closest_component);
+ component_size[closest_component] += countstones(pos);
+ }
+ }
+
+ /* Now find the biggest_component. */
+ {
+ int biggest_size = 0;
+ for (c_id = 0; c_id < num_components; c_id++)
+ if (component_size[c_id] > biggest_size) {
+ biggest_size = component_size[c_id];
+ biggest_component = c_id;
+ }
+ gg_assert(biggest_component != -1);
+ }
+
+ /* Now delete everything except the biggest component from the goal. */
+ for (pos = BOARDMIN; pos < BOARDMAX; pos++)
+ if (component2[pos] != biggest_component)
+ goal[pos] = 0;
+ if (debug & DEBUG_SPLIT_OWL) {
+ gprintf("Split dragon. Biggest component is %d (of %d).\n",
+ biggest_component, num_components);
+ showboard(0);
+ componentdump(component2);
+ }
+ }
+ sgf_dumptree = save_sgf_dumptree;
+ count_variations = save_count_variations;
+}
+
/* We update the boundary marks. The boundary mark must be
* constant on each string. It is nonzero if the string
* adjoins the goal dragon, or if the string includes a
@@ -4577,6 +4837,16 @@ goaldump(const char goal[BOARDMAX])
gprintf("\n");
}
+void
+componentdump(const char goal[BOARDMAX])
+{
+ int pos;
+ for (pos = BOARDMIN; pos < BOARDMAX; pos++)
+ if (ON_BOARD(pos) && goal[pos] != -1)
+ gprintf("%o%1m (%d) ", pos, (int) goal[pos]);
+ gprintf("\n");
+}
+
/*
* Owl attack moves are ineffective when the dragon can still live in a
* semeai. This function tests whether an owl attack move has this problem.
Index: engine/readconnect.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/readconnect.c,v
retrieving revision 1.82
diff -u -p -r1.82 readconnect.c
--- engine/readconnect.c 19 Jul 2004 12:23:08 -0000 1.82
+++ engine/readconnect.c 22 Aug 2004 23:16:19 -0000
@@ -1365,6 +1365,43 @@ disconnect(int str1, int str2, int *move
return res;
}
+/* Externally callable frontend to recursive_disconnect().
+ * Returns WIN if str1 and str2 can be disconnected.
+ *
+ * Uses much lower node and depths limits.
+ */
+int
+fast_disconnect(int str1, int str2, int *move)
+{
+ int result;
+ int save_limit = connection_node_limit;
+ int save_verbose = verbose;
+
+ if (board[str1] == EMPTY || board[str2] == EMPTY)
+ return WIN;
+ str1 = find_origin(str1);
+ str2 = find_origin(str2);
+ if (str1 > str2) {
+ int tmp = str1;
+ str1 = str2;
+ str2 = tmp;
+ }
+
+ modify_depth_values(-3);
+ connection_node_limit /= 4;
+
+ if (verbose > 0)
+ verbose--;
+ result = recursive_disconnect2(str1, str2, move, 0);
+ verbose = save_verbose;
+
+ connection_node_limit = save_limit;
+ modify_depth_values(3);
+
+ return result;
+}
+
+
/* Returns WIN if str1 and str2 can be disconnected. */
@@ -1893,8 +1930,6 @@ get_connection_node_counter()
} while (0)
-#define HUGE_CONNECTION_DISTANCE 100.0
-
static int find_string_connection_moves(int str1, int str2, int color_to_move,
int moves[MAX_MOVES],
float *total_distance);
Index: engine/readconnect.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/readconnect.h,v
retrieving revision 1.5
diff -u -p -r1.5 readconnect.h
--- engine/readconnect.h 3 Feb 2004 21:12:07 -0000 1.5
+++ engine/readconnect.h 22 Aug 2004 23:16:19 -0000
@@ -42,6 +42,8 @@ struct heap_entry {
connection_helper_fn_ptr helper;
};
+#define HUGE_CONNECTION_DISTANCE 100.0
+
struct connection_data {
float distances[BOARDMAX];
float deltas[BOARDMAX];
Index: patterns/owl_attackpats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_attackpats.db,v
retrieving revision 1.113
diff -u -p -r1.113 owl_attackpats.db
--- patterns/owl_attackpats.db 8 Jun 2004 05:52:26 -0000 1.113
+++ patterns/owl_attackpats.db 22 Aug 2004 23:16:20 -0000
@@ -332,7 +332,7 @@ Pattern A113
|..*O
|..Y?
-:8,-,value(99)
+:8,C,value(99)
Pattern A114
@@ -343,7 +343,7 @@ Pattern A114
|..*O
|..Y?
-:8,-,value(99)
+:8,C,value(99)
Pattern A115
@@ -412,7 +412,7 @@ x*Yx
...X
----
-:8,-,value(60)
+:8,C,value(60)
Pattern A204
@@ -517,7 +517,7 @@ X.*.xx
?...??
------
-:8,-,value(60)
+:8,C,value(60)
?O.Yxx
a.*.xx
@@ -627,7 +627,7 @@ xY*.x second line block
x....
-----
-:8,-,value(85)
+:8,C,value(85)
?OO?x
xY*.a
@@ -673,7 +673,7 @@ x*..
....
----
-:8,-,value(80)
+:8,C,value(80)
Pattern A216
@@ -908,7 +908,7 @@ Pattern A227
X.Y..
-----
-:8,-,value(35)
+:8,C,value(35)
?XOxx
?XO*a
@@ -926,7 +926,7 @@ X.*. stop escape
xY..
----
-:8,-,value(65)
+:8,C,value(65)
?O.x
X.*a
@@ -958,7 +958,7 @@ x.*OX
...Y.
-----
-:8,-,value(80)
+:8,C,value(80)
ac.O?
b.*OX
@@ -975,7 +975,7 @@ xxx? stop escape
...Y
----
-:8,-,value(79)
+:8,C,value(79)
abx?
..*O
@@ -1009,7 +1009,7 @@ X? stop escape
.Y
--
-:8,-,value(79)
+:8,C,value(79)
a?
*O
@@ -1054,7 +1054,7 @@ Y..?
....
----
-:8,-,value(80)
+:8,C,value(80)
?OO?
Yab?
@@ -1109,7 +1109,7 @@ YO
..
--
-:8,-,value(20)
+:8,C,value(20)
Pattern A235
@@ -1193,7 +1193,7 @@ o*XO capture one stone and limiting eye
o... maybe gote
----
-:8,-,value(50)
+:8,C,value(50)
Pattern A241
@@ -1310,7 +1310,7 @@ x...O
.*..o
-----
-:8,-,value(45)
+:8,C,value(45)
#########################################################
@@ -1552,7 +1552,7 @@ oO*.. try to contain
O.Y.O
?X.Oo
-:8,-,value(80)
+:8,C,value(80)
??abc
oO*..
@@ -1569,7 +1569,7 @@ xxx try to block
OYO
?X?
-:|,-,value(90)
+:|,B,value(90)
xax
.*.
@@ -1723,7 +1723,7 @@ o.. cut off escape
.*Y
X.O
-:8,-,value(80)
+:8,C,value(80)
o..
.*Y
@@ -1782,7 +1782,7 @@ Pattern A419
Y.O
.*X cut to stop escape
-:8,-,value(68)
+:8,C,value(68)
Ycd
.*A
@@ -1797,7 +1797,7 @@ Pattern A419b
X.O
.*Y cut to stop escape
-:8,-,value(68)
+:8,C,value(68)
Acd
.*Y
@@ -1884,7 +1884,7 @@ X..? try to cut
Y.*X
??O?
-:8,-,value(61)
+:8,C,value(61)
X..?
Y.*a
@@ -1949,7 +1949,7 @@ x.Y? jump under
....
----
-:8,-,value(75)
+:8,C,value(75)
Pattern A502
@@ -1959,7 +1959,7 @@ O*Y
X.X
---
-:8,n,value(45)
+:8,Cn,value(45)
?Xo
a*Y
@@ -1976,7 +1976,7 @@ Y*O
X.X
---
-:8,s,value(45)
+:8,Cs,value(45)
Pattern A503b
@@ -2003,7 +2003,7 @@ Y* cut off one stone
OX
--
-:8,-,value(35)
+:8,C,value(35)
Pattern A505
@@ -2033,7 +2033,7 @@ Y*X
...
---
-:8,-,value(80)
+:8,C,value(80)
Pattern A508
@@ -2043,7 +2043,7 @@ O.*.Y
....x
-----
-:8,-,value(65)
+:8,C,value(65)
Pattern A509
@@ -2070,7 +2070,7 @@ OXO*.
.O...
-----
-:8,-,value(55)
+:8,C,value(55)
Pattern A511
@@ -2688,7 +2688,7 @@ Pattern A704
OXOX
.*.?
-:8,-,value(80)
+:8,C,value(80)
#Pattern A705
@@ -2714,7 +2714,7 @@ Pattern A705b
X*Y
?.?
-:8,-,value(61)
+:8,C,value(61)
?b?
X*Y
@@ -2729,7 +2729,7 @@ Pattern A706
X.X
?Y.
-:8,-,value(70)
+:8,C,value(70)
?*?
XaA
@@ -2744,7 +2744,7 @@ Pattern A707
X*X
.Y.
-:8,-,value(70)
+:8,C,value(70)
?O?
X*A
@@ -2775,7 +2775,7 @@ xX. half eye sometimes missed
Y.*
?x?
-:8,-,value(45)
+:8,C,value(45)
xXb
Aa*
@@ -2806,7 +2806,7 @@ O*.X destroy eye
X..X
xXY?
-:8,-,value(35)
+:8,C,value(35)
Pattern A712
@@ -2816,7 +2816,7 @@ Pattern A712
.*.X
oo.?
-:8,-,value(60)
+:8,C,value(60)
Pattern A713
@@ -2843,7 +2843,7 @@ O..X
X*.x
OX.x
-:8,-,value(82)
+:8,C,value(82)
?XY?
O..X
@@ -2877,7 +2877,7 @@ O*x destroy eye in reverse sent
X.X
xYx
-:8,-,value(50)
+:8,C,value(50)
a*x
X.X
@@ -2893,7 +2893,7 @@ Pattern A717
XO*Y
?X.X
-:8,s,value(75)
+:8,Cs,value(75)
?.??
XO*Y
@@ -2911,7 +2911,7 @@ xYx? reduce eye space
x.*O
xXx?
-:8,-,value(50)
+:8,C,value(50)
xYx?
x.*A
@@ -2962,7 +2962,7 @@ X*Ox
?...
?OO?
-:8,-,value(40)
+:8,C,value(40)
?c??
Ya.x
@@ -3075,7 +3075,7 @@ OX*.
....
----
-:8,-,value(75)
+:8,C,value(75)
Pattern A807
@@ -3115,6 +3115,7 @@ A.*..
Pattern A810
+# This looks a little weird. /ab
?O?
X.Y safe invasion into eye
@@ -3155,7 +3156,7 @@ Pattern A812
..o
---
-:8,-,value(40)
+:8,C,value(40)
.Y?
..O
@@ -3175,7 +3176,7 @@ OXO sacrifice to eliminate eye
.X.
---
-:8,s,value(85)
+:8,Cs,value(85)
X*.
aXb
@@ -3522,7 +3523,7 @@ Pattern A1001
YO cut if safe
*X
-:8,n,value(80)
+:8,Cn,value(80)
Ba
*C
@@ -3538,7 +3539,7 @@ Pattern A1001b
YO cut if safe
*X
-:8,n,value(50)
+:8,Cn,value(50)
Ya
*X
@@ -3552,7 +3553,7 @@ Pattern A1002
?*.X threaten to cut
??YO
-:8,-,value(75)
+:8,C,value(75)
????
?*aX
@@ -3567,7 +3568,7 @@ Pattern A1003
?*.X threaten to cut
??YO
-:8,-,value(55)
+:8,C,value(55)
????
?*aX
@@ -3583,7 +3584,7 @@ Pattern A1003
#?*.X threaten to cut
#??XO
#
-#:8,-,value(50)
+#:8,B,value(50)
#
#----
#?*aX
@@ -3598,7 +3599,7 @@ Y? cut!
*O
.X
-:8,-,value(90)
+:8,C,value(90)
Y?
*b
@@ -3614,7 +3615,7 @@ X? cut!
*O
.Y
-:8,-,value(90)
+:8,C,value(90)
C?
*b
@@ -3629,7 +3630,7 @@ XOY push out
.*.
?.?
-:8,-,value(70)
+:8,C,value(70)
Pattern A1006b
@@ -3639,7 +3640,7 @@ XOY push out in reverse sente
.*.
?.?
-:8,-,value(75)
+:8,C,value(75)
XaY
.*.
@@ -3669,7 +3670,7 @@ Pattern A1008
X*Y stop connection
?O?
-:8,-,value(80)
+:8,C,value(80)
a*b
?O?
@@ -3684,7 +3685,7 @@ ooo
X*Y stop connection
O.?
-:8,-,value(80)
+:8,C,value(80)
ooo
a*b
@@ -3700,7 +3701,7 @@ XO*Y stop connection underneath
....
----
-:8,-,value(55)
+:8,C,value(55)
XO*Y
.a..
@@ -3716,7 +3717,7 @@ Y.O cut and capture to destroy ey
...
---
-:8,-,value(75)
+:8,C,value(75)
YaO
.*B
@@ -3732,7 +3733,7 @@ XOY stop connection underneath
x*x
---
-:8,-,value(80)
+:8,C,value(80)
aOb
x*x
@@ -3747,7 +3748,7 @@ X.?? cut
OY*O
oOX?
-:8,-,value(45)
+:8,C,value(45)
Xa??
OY*O
@@ -3782,7 +3783,7 @@ xx..Ox stop connection underneath
...*Y.
------
-:8,-,value(55)
+:8,C,value(55)
AB..Ox
...*Y.
@@ -3796,7 +3797,7 @@ Pattern A1015
X.*Y cut!
X..X
-:8,-,value(75)
+:8,C,value(75)
Ae*B
AfgB
@@ -3810,7 +3811,7 @@ Pattern A1015a
Y.*X cut!
X..X
-:8,-,value(75)
+:8,C,value(75)
Ae*B
AfgB
@@ -3827,7 +3828,7 @@ YxO?
o.*X
----
-:8,-,value(75)
+:8,C,value(75)
Bde?
oc*A
@@ -3846,7 +3847,7 @@ XxO?
o.*Y
----
-:8,-,value(75)
+:8,C,value(75)
Bde?
oc*A
@@ -3863,7 +3864,7 @@ Pattern A1017
X.*o threaten to cut and mess up opponent's shape
xY.X
-:8,-,value(65)
+:8,C,value(65)
X.*b
xYaX
@@ -3879,7 +3880,7 @@ O.Y separate
.*.
X.o
-:8,-,value(35)
+:8,C,value(35)
Pattern A1019
@@ -3889,7 +3890,7 @@ Pattern A1019
X...
.*.Y
-:8,-,value(65)
+:8,C,value(65)
.fgO
Xbde
@@ -3948,7 +3949,7 @@ oY.O
.X.X
...o
-:8,-,value(55)
+:8,C,value(55)
oA.O
..*.
@@ -3966,7 +3967,7 @@ O*.?
?..?
xYxx
-:8,-,value(45)
+:8,C,value(45)
?Bx?
O*a?
@@ -3984,7 +3985,7 @@ YO.o connect along edge to strong
x*.X
----
-:8,Eb,value(90)
+:8,CEb,value(90)
AO.o
x*.B
@@ -4093,7 +4094,7 @@ Pattern A1102
O*O
?Y?
-:8,-,value(95)
+:8,C,value(95)
baX
c*O
@@ -4119,7 +4120,7 @@ OYO connect to prevent double ata
XO*
...
-:8,-,value(85)
+:8,C,value(85)
OYB
AO*
@@ -4137,7 +4138,7 @@ xYO
x..
---
-:8,n,value(85)
+:8,Cn,value(85)
Oa.
XO*
@@ -4156,7 +4157,7 @@ xYO.
xx..
----
-:8,-,value(70)
+:8,C,value(70)
OO.?
XOB*
@@ -4249,7 +4250,7 @@ O.*..
.....
-----
-:8,-,value(65)
+:8,C,value(65)
?Xx??
?cYab
@@ -4358,7 +4359,7 @@ OYO
*OX
xxx
-:8,-,value(90)
+:8,C,value(90)
?X?
aDO
@@ -4374,7 +4375,7 @@ Pattern A1117
X*O don't let defender cut and capture to escape
?OY
-:8,n,value(80)
+:8,Cn,value(80)
X*b
?aY
@@ -4388,7 +4389,7 @@ Pattern A1117a
Y*O don't let defender cut and capture to escape
?OX
-:8,n,value(80)
+:8,Cn,value(80)
Y*b
?aX
@@ -4423,7 +4424,7 @@ Pattern A1119
Y*? cut off escape route.
o.X
-:8,n,value(36)
+:8,Cn,value(36)
a*E
Dcb
@@ -4471,7 +4472,7 @@ O.O block to protect weakness
Y*.
?O?
-:8,-,value(35)
+:8,C,value(35)
a.b
Y*.
@@ -4488,7 +4489,7 @@ Y.
*.
.X
-:8,-,value(75)
+:8,C,value(75)
a.
*.
@@ -4597,7 +4598,7 @@ Pattern A1124b
x.*
xx?
-:8,-,value(70)
+:8,C,value(70)
?OA
be*
@@ -4618,7 +4619,7 @@ O*O?
XOYo
?X.?
-:8,-,value(76)
+:8,C,value(76)
Pattern A1126
@@ -4676,7 +4677,7 @@ Pattern A1128
OY*X cut off from home
X.X.
-:8,-,value(80)
+:8,C,value(80)
Ob*a
XcXd
@@ -4694,7 +4695,7 @@ XYO.
XO..
O..?
-:8,-,value(86)
+:8,C,value(86)
xB*x
XYOa
@@ -4714,7 +4715,7 @@ Pattern A1130
..XYO
...o?
-:8,-,value(65)
+:8,C,value(65)
Pattern A1131
@@ -4796,7 +4797,7 @@ XOY prevent escaping by capturing
.*O
---
-:8,-,value(75)
+:8,C,value(75)
BOY
.*a
@@ -4812,7 +4813,7 @@ YOX prevent escaping by capturing
.*O
---
-:8,-,value(75)
+:8,C,value(75)
YOB
.*a
@@ -4828,7 +4829,7 @@ XOY prevent escaping by capturing
.*O
---
-:8,-,value(40)
+:8,C,value(40)
XOY
.*a
@@ -4845,7 +4846,7 @@ YOX prevent escaping by capturing
.*O
---
-:8,-,value(40)
+:8,C,value(40)
YOX
.*a
@@ -5002,7 +5003,7 @@ Pattern A1206
*Y kill one string, possibly with ko!
XO
-:8,s,value(30)
+:8,Cs,value(30)
*Y
AO
@@ -5017,7 +5018,7 @@ Pattern A1207
.*Y
.XO
-:8,-,value(45)
+:8,C,value(45)
..X
.*Y
@@ -5034,7 +5035,7 @@ Y..o
....
----
-:8,-,value(40)
+:8,C,value(40)
Pattern A1209
@@ -5485,7 +5486,7 @@ Pattern A1327
|oo???
|oo???
-:8,s,value(85)
+:8,Cs,value(85)
Pattern A1328
@@ -5712,7 +5713,7 @@ Pattern A1342
|.YX
|.O?
-:8,s,value(50)
+:8,Cs,value(50)
Pattern A1343
@@ -5968,7 +5969,7 @@ Y*X
OXO
?O?
-:8,s,value(75)
+:8,Cs,value(75)
OX?
A*B
@@ -5986,7 +5987,7 @@ X*Y
OXO
?O?
-:8,s,value(75)
+:8,Cs,value(75)
OX?
A*B
@@ -6046,7 +6047,7 @@ Pattern A1602
.X.?
----
-:8,s,value(55)
+:8,Cs,value(55)
aYO?
*bCO
@@ -6063,7 +6064,7 @@ Pattern A1603
..X?
----
-:8,s,value(55)
+:8,Cs,value(55)
aYO?
*bCO
@@ -6080,7 +6081,7 @@ O*.XO
..X.?
-----
-:8,s,value(55)
+:8,Cs,value(55)
?XYO?
O*aBO
@@ -6097,7 +6098,7 @@ O*.XO
...X?
-----
-:8,s,value(55)
+:8,Cs,value(55)
?XYO?
O*aBO
@@ -6114,7 +6115,7 @@ XYO? peep to destroy eyeshape
.X.?
----
-:8,s,value(35)
+:8,Cs,value(35)
XYO?
*aBO
- [gnugo-devel] owl goal dragon gets cut,
Arend Bayer <=
leak? Re: [gnugo-devel] owl goal dragon gets cut, Douglas Ridgway, 2004/08/30