[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] saving lunch can split owl dragon
From: |
Arend Bayer |
Subject: |
[gnugo-devel] saving lunch can split owl dragon |
Date: |
Sun, 12 Sep 2004 17:13:41 +0200 (CEST) |
- test for owl cuts after saving lunch
This time the breakage is not as clear, because 3 owl tests uncovered a
latent problem. Still I think it is an improvement overall.
Arend
owl:18 FAIL 1 B2 [1 A2]
This one currently works for a bad reason IMHO; the cut is right. See FIXME
in sniff_lunch().
owl:45 FAIL 1 A2 [1 (E3|F1)]
owl:47 FAIL 1 A2 [1 (E3|F1)]
(With current amalgamation, this is the same problem)
Right cut, but escape analysis gets funnily confused after the cut.
Needless to say, I hope to get this right with the new_escape patch...
owl:135 FAIL 1 N17 [0]
Bad split.
strategy2:55 PASS C12 [C12]
Random.
strategy3:124 PASS C5 [C5]
Owl reading better (thought semeai still misjudged.)
nngs4:350 PASS H10 [H10]
Owl reading much better.
nngs4:470 PASS R8 [R8]
Good.
strategy5:236 PASS R12 [R12]
Very good.
Index: engine/owl.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v
retrieving revision 1.220
diff -u -p -r1.220 owl.c
--- engine/owl.c 28 Aug 2004 20:54:43 -0000 1.220
+++ engine/owl.c 8 Sep 2004 15:30:21 -0000
@@ -186,7 +186,8 @@ static void owl_shapes_callback(int anch
int ll, void *data);
static void owl_add_move(struct owl_move_data *moves, int move, int value,
const char *reason, int same_dragon, int lunch,
- int escape, int defense_pos, int max_moves);
+ int cuts[MAX_CUTS], int escape,
+ int defense_pos, int max_moves);
static void owl_determine_life(struct local_owl_data *owl,
struct local_owl_data *second_owl,
int does_attack,
@@ -214,6 +215,8 @@ static void owl_mark_boundary(struct loc
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 generate_lunch_cut_list(int lunch, const char goal[BOARDMAX],
+ 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);
@@ -728,7 +731,7 @@ do_owl_analyze_semeai(int apos, int bpos
&& find_defense(semeai_worms[sworm], NULL)) {
critical_semeai_worms[sworm] = 1;
owl_add_move(moves, upos, 95, "attack semeai worm", 1, NO_MOVE,
- 0, NO_MOVE, MAX_SEMEAI_MOVES);
+ NULL, 0, NO_MOVE, MAX_SEMEAI_MOVES);
TRACE("Added %1m %d (-1)\n", upos, 95);
}
}
@@ -747,7 +750,7 @@ do_owl_analyze_semeai(int apos, int bpos
&& find_defense(semeai_worms[sworm], &upos)) {
critical_semeai_worms[sworm] = 1;
owl_add_move(moves, upos, 85, "defend semeai worm", 1, NO_MOVE,
- 0, NO_MOVE, MAX_SEMEAI_MOVES);
+ NULL, 0, NO_MOVE, MAX_SEMEAI_MOVES);
TRACE("Added %1m %d (0)\n", upos, 85);
}
}
@@ -981,7 +984,7 @@ do_owl_analyze_semeai(int apos, int bpos
owla, owlb, 50,
critical_semeai_worms);
owl_add_move(moves, outside_liberty.pos, move_value,
- "safe outside liberty", 0, NO_MOVE, 0, NO_MOVE,
+ "safe outside liberty", 0, NO_MOVE, NULL, 0, NO_MOVE,
MAX_SEMEAI_MOVES);
TRACE("Added %1m %d (5)\n", outside_liberty.pos, move_value);
}
@@ -990,7 +993,7 @@ do_owl_analyze_semeai(int apos, int bpos
owla, owlb, 50,
critical_semeai_worms);
owl_add_move(moves, backfill_outside_liberty.pos, move_value,
- "backfilling move", 0, NO_MOVE, 0,
+ "backfilling move", 0, NO_MOVE, NULL, 0,
NO_MOVE, MAX_SEMEAI_MOVES);
TRACE("Added %1m %d (6)\n", backfill_outside_liberty.pos, move_value);
}
@@ -1000,7 +1003,7 @@ do_owl_analyze_semeai(int apos, int bpos
owla, owlb, 10,
critical_semeai_worms);
owl_add_move(moves, common_liberty.pos, move_value,
- "safe common liberty", 1, NO_MOVE, 0,
+ "safe common liberty", 1, NO_MOVE, NULL, 0,
NO_MOVE, MAX_SEMEAI_MOVES);
TRACE("Added %1m %d (7)\n", common_liberty.pos, move_value);
}
@@ -1009,7 +1012,7 @@ do_owl_analyze_semeai(int apos, int bpos
owla, owlb, 10,
critical_semeai_worms);
owl_add_move(moves, backfill_common_liberty.pos, move_value,
- "backfilling move", 0, NO_MOVE, 0,
+ "backfilling move", 0, NO_MOVE, NULL, 0,
NO_MOVE, MAX_SEMEAI_MOVES);
TRACE("Added %1m %d (6)\n", backfill_common_liberty.pos, move_value);
}
@@ -1024,7 +1027,7 @@ do_owl_analyze_semeai(int apos, int bpos
if (move) {
owl_add_move(moves, move, 70, "eyespace filling", 0, NO_MOVE,
- 0, NO_MOVE, MAX_SEMEAI_MOVES);
+ NULL, 0, NO_MOVE, MAX_SEMEAI_MOVES);
}
}
@@ -1394,7 +1397,7 @@ semeai_review_owl_moves(struct owl_move_
critical_semeai_worms)
+ value_bonus);
owl_add_move(semeai_moves, move, move_value, owl_moves[k].name,
- same_dragon, NO_MOVE, owl_moves[k].escape,
+ same_dragon, NO_MOVE, NULL, owl_moves[k].escape,
NO_MOVE, MAX_SEMEAI_MOVES);
TRACE("Added %1m %d\n", move, move_value);
}
@@ -2893,7 +2896,7 @@ owl_estimate_life(struct local_owl_data
*/
owl_add_move(vital_moves, dummy_moves[0].defense_pos,
dummy_moves[0].value, dummy_moves[0].name, 2, NO_MOVE,
- 0, NO_MOVE, MAX_MOVES);
+ NULL, 0, NO_MOVE, MAX_MOVES);
}
return 0;
@@ -3107,7 +3110,7 @@ owl_determine_life(struct local_owl_data
if (attack_point != NO_MOVE) {
owl_add_move(moves, attack_point, value, reason, 1, NO_MOVE,
- 0, NO_MOVE, MAX_MOVES);
+ NULL, 0, NO_MOVE, MAX_MOVES);
vital_values[attack_point] = value;
eyes_attack_points[num_eyes] = attack_point;
}
@@ -3162,7 +3165,7 @@ owl_determine_life(struct local_owl_data
if (defense_point != NO_MOVE) {
owl_add_move(moves, defense_point, value, reason, 1, NO_MOVE,
- 0, NO_MOVE, MAX_MOVES);
+ NULL, 0, NO_MOVE, MAX_MOVES);
vital_values[defense_point] = value;
}
}
@@ -3207,6 +3210,7 @@ owl_determine_life(struct local_owl_data
value -= 10;
if (does_attack) {
+ int cuts[MAX_CUTS];
defense_point = improve_lunch_defense(owl->lunch[lunch],
owl->lunch_defense_point[lunch]);
@@ -3235,8 +3239,9 @@ owl_determine_life(struct local_owl_data
TRACE("save lunch at %1m with %1m, score %d, probable eye %d, max eye
%d\n",
owl->lunch[lunch], defense_point, value,
lunch_probable, lunch_max);
+ generate_lunch_cut_list(owl->lunch[lunch], owl->goal, cuts);
owl_add_move(moves, defense_point, value,
- "save lunch", 1, NO_MOVE, 0, NO_MOVE, MAX_MOVES);
+ "save lunch", 1, NO_MOVE, cuts, 0, NO_MOVE, MAX_MOVES);
}
else {
attack_point = improve_lunch_attack(owl->lunch[lunch],
@@ -3252,10 +3257,10 @@ owl_determine_life(struct local_owl_data
if (owl->lunch_attack_code[lunch] == WIN
|| is_illegal_ko_capture(attack_point, owl->color))
owl_add_move(moves, attack_point, value, "eat lunch",
- 1, owl->lunch[lunch], 0, NO_MOVE, MAX_MOVES);
+ 1, owl->lunch[lunch], NULL, 0, NO_MOVE, MAX_MOVES);
else
owl_add_move(moves, attack_point, value, "eat lunch",
- 1, NO_MOVE, 0, NO_MOVE, MAX_MOVES);
+ 1, NO_MOVE, NULL, 0, NO_MOVE, MAX_MOVES);
num_lunches++;
eyevalue_list[num_eyes++] = e;
}
@@ -4005,6 +4010,31 @@ generate_cut_list(struct pattern *patter
cuts[0], cuts[1]);
}
+/* This function adds all direct neighbours of the lunch into the cut list.
+ * This is used both for attack and defense.
+ */
+static void
+generate_lunch_cut_list(int lunch, const char goal[BOARDMAX],
+ int cuts[MAX_CUTS])
+{
+ int adjs[MAXCHAIN];
+ int adj, num_cuts, k;
+
+ adj = chainlinks(lunch, adjs);
+ num_cuts = 0;
+ for (k = 0; k < adj; k++) {
+ if (goal[adjs[k]])
+ cuts[num_cuts++] = adjs[k];
+ if (num_cuts == MAX_CUTS)
+ break;
+ }
+ if (num_cuts < MAX_CUTS)
+ cuts[num_cuts] = NO_MOVE;
+ if (num_cuts > 1)
+ DEBUG(DEBUG_SPLIT_OWL, "Adding %d cuts for lunch at %1m.\n",
+ num_cuts, lunch);
+}
+
/* 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
@@ -4296,7 +4326,7 @@ owl_shapes_callback(int anchor, int colo
}
owl_add_move(moves, move, tval, pattern->name, same_dragon, NO_MOVE,
- escape, defense_pos, MAX_MOVES);
+ NULL, escape, defense_pos, MAX_MOVES);
}
@@ -4305,7 +4335,7 @@ owl_shapes_callback(int anchor, int colo
static void
owl_add_move(struct owl_move_data *moves, int move, int value,
const char *reason, int same_dragon, int lunch,
- int escape, int defense_pos, int max_moves)
+ int cuts[MAX_CUTS], int escape, int defense_pos, int max_moves)
{
int k;
@@ -4354,6 +4384,12 @@ owl_add_move(struct owl_move_data *moves
moves[k].lunch = lunch;
moves[k].escape = escape;
moves[k].defense_pos = defense_pos;
+ if (cuts) {
+ memcpy(moves[k].cuts, cuts, MAX_CUTS * sizeof(cuts[0]));
+ /* gprintf("Added cuts for move at %1m.\n", moves[k].pos); */
+ }
+ else
+ moves[k].cuts[0] = NO_MOVE;
}
break;
}
@@ -4661,7 +4697,6 @@ owl_test_cuts(char goal[BOARDMAX], int c
{
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;
@@ -4794,6 +4829,7 @@ owl_test_cuts(char goal[BOARDMAX], int c
showboard(0);
componentdump(component2);
}
+ free(conn_data);
}
sgf_dumptree = save_sgf_dumptree;
count_variations = save_count_variations;
@@ -6061,12 +6097,16 @@ sniff_lunch(int lunch, int *min, int *pr
eat_lunch_escape_bonus(lunch, min, probable, max, owl);
}
+
void
estimate_lunch_eye_value(int lunch, int *min, int *probable, int *max,
int appreciate_one_two_lunches)
{
int other = OTHER_COLOR(board[lunch]);
int size = countstones(lunch);
+ /* FIXME: This function should take into account half eyes that become
+ * eyse due to capturing the lunch.
+ */
if (size > 6) {
*min = 2;
Index: engine/readconnect.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/readconnect.c,v
retrieving revision 1.83
diff -u -p -r1.83 readconnect.c
--- engine/readconnect.c 24 Aug 2004 14:39:53 -0000 1.83
+++ engine/readconnect.c 8 Sep 2004 15:30:21 -0000
@@ -88,6 +88,7 @@ static void order_connection_moves(int *
int color_to_move, const char *funcname);
static int nodes_connect = 0;
+static int fast_connection_reading = 0;
/* Used by alternate connections. */
static char connection_shadow[BOARDMAX];
@@ -1389,12 +1390,14 @@ fast_disconnect(int str1, int str2, int
modify_depth_values(-3);
connection_node_limit /= 4;
+ fast_connection_reading = 1;
if (verbose > 0)
verbose--;
result = recursive_disconnect2(str1, str2, move, 0);
verbose = save_verbose;
+ fast_connection_reading = 0;
connection_node_limit = save_limit;
modify_depth_values(3);
@@ -2145,7 +2148,10 @@ recursive_disconnect2(int str1, int str2
str1 = find_origin(str1);
str2 = find_origin(str2);
- attack_code1 = attack(str1, &attack_pos1);
+ if (fast_connection_reading)
+ attack_code1 = ladder_capture(str1, &attack_pos1);
+ else
+ attack_code1 = attack(str1, &attack_pos1);
if (attack_code1 == WIN) {
sgf_dumptree = save_sgf_dumptree;
count_variations = save_count_variations;
@@ -2157,7 +2163,10 @@ recursive_disconnect2(int str1, int str2
return WIN;
}
- attack_code2 = attack(str2, &attack_pos2);
+ if (fast_connection_reading)
+ attack_code2 = ladder_capture(str2, &attack_pos2);
+ else
+ attack_code2 = attack(str2, &attack_pos2);
if (attack_code2 == WIN) {
sgf_dumptree = save_sgf_dumptree;
count_variations = save_count_variations;
Index: regression/connection.tst
===================================================================
RCS file: /cvsroot/gnugo/gnugo/regression/connection.tst,v
retrieving revision 1.77
diff -u -p -r1.77 connection.tst
--- regression/connection.tst 4 Sep 2004 06:25:43 -0000 1.77
+++ regression/connection.tst 8 Sep 2004 15:30:22 -0000
@@ -411,6 +411,20 @@ trymove white C15
#? [1 B15]
popgo
+# See also trevorb:470
+loadsgf games/trevor/auto/b30.sgf 68
+trymove W L5
+trymove B L4
+trymove W M4
+trymove B L3
+115 disconnect M4 M6
+#? [0]
+popgo
+popgo
+popgo
+popgo
+
+
# Report number of nodes visited by the tactical reading
10000 get_reading_node_counter
#? [0]&
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnugo-devel] saving lunch can split owl dragon,
Arend Bayer <=