[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] Big patch
From: |
Gunnar Farneback |
Subject: |
[gnugo-devel] Big patch |
Date: |
Wed, 07 Jan 2004 01:13:13 +0100 |
User-agent: |
EMH/1.14.1 SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.3 Emacs/20.7 (sparc-sun-solaris2.7) (with unibyte mode) |
This patch includes a lot of changes I made while Savannah was down.
Although it might be somewhat unwieldy I think it's better to get them
all now than lose time by trying to split it up.
- bugfix in dragon_invincible()
- compute_crude_status() revised to consider dragons with big
territorial moyo value as alive
- semeai moves considered safe in mark_changed_dragon
- compare number of eyes when both colors pass in
do_owl_analyze_semeai() instead of always consider it a seki
- do not use the attack point from owl if owl considers a dragon dead
but semeai revises it to critical
- bugfix in break_through_helper() in reading.c
- new static function close_enough_for_proper_semeai() in semeai.c
- liberty_of_dragon() transformed into neighbor_of_dragon() in semeai.c
- in semeai(), be more careful when considering two dragons involved
in a semeai
- new static function max_lunch_eye_value() in value_moves.c
- when restraining thrashing dragons, do not bother connecting
inessential strings which cannot provide an eye (in
estimate_strategical_value())
- new autohelper function adjacent_to_stone_in_atari
- influence tuning
- eye tuning
- owl tuning
- tuning
The regression delta (compared to CVS of January 1):
ld_owl:10 pass (fails in CVS)
blunder:17 PASS R7 [R7]
blunder:21 FAIL O4 [L9]
rosebud:1 PASS E16 [E16]
lazarus:13 FAIL M12 [R13|M8|L9]
trevorb:100 FAIL C4 [B1]
strategy2:80 PASS Q4 [P4|Q4|Q3|S8]
nicklas4:1103 PASS C3 [C2|C3]
nngs:220 FAIL R4 [L1|E7|G13|K9]
nngs:320 PASS B16 [B15|B16]
nngs:380 PASS H3 [!H2|S1]
nngs:710 fail (passes in CVS)
nngs:1090 PASS B16 [B17|B16]
trevorc:550 pass (fails in CVS)
trevorc:1360 FAIL G5 [F12]
global:36 pass (fails in CVS)
13x13:37 FAIL D7 [E10]
13x13:38 PASS G11 [G11]
13x13:60 PASS K5 [K5|L5]
strategy4:198 FAIL F1 [C10|S18]
owl1:330 PASS 1 R1 [1 R1]
owl1:331 PASS 1 R1 [1 (R1|S1|T2)]
owl1:334 pass (fails in CVS)
owl1:335 pass (fails in CVS)
handtalk:18 pass (fails in CVS)
handtalk:20 PASS N18 [N18]
nngs2:270 PASS S19 [S19]
nngs2:300 PASS L10 [!Q13]
nngs2:460 PASS L2 [J4|K2|K3|K4|K5|L2]
nngs2:500 pass (fails in CVS)
nngs3:1110 PASS B7 [B7]
nngs4:40 PASS H3 [H3|F4]
nngs4:330 fail (passes in CVS)
nngs4:630 PASS B6 [B6]
nngs4:750 FAIL D5 [C7]
strategy5:230 pass (fails in CVS)
ninestones:40 fail (passes in CVS)
ninestones:50 PASS R13 [R13]
ninestones:190 pass (fails in CVS)
ninestones:670 PASS H7 [H7]
tactics1:106 PASS F8 [F8|F6]
gunnar:8 PASS P10 [!O13]
gunnar:45 pass (fails in CVS)
arend2:150 FAIL D7 [D6|C6]
arend2:230 PASS G14 [!H14]
nando:27 fail (passes in CVS)
thrash:3 PASS O5 [O5|N5|N4]
thrash:11 PASS S3 [S3]
gifu03:205 PASS P5 [P5]
gifu03:302 PASS B6 [C1|B6]
9x9:70 pass (fails in CVS)
9x9:110 pass (fails in CVS)
9x9:290 FAIL E2 [D2]
In total 39 new passes and 14 failures. No detailed analysis of the
failures this time but I've checked that they are acceptable.
/Gunnar
Index: engine/dragon.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/dragon.c,v
retrieving revision 1.127
diff -u -r1.127 dragon.c
--- engine/dragon.c 31 Dec 2003 14:38:24 -0000 1.127
+++ engine/dragon.c 1 Jan 2004 12:42:37 -0000
@@ -1023,7 +1023,12 @@
}
for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
- if (mx[pos] == 1)
+ /* Necessary to check eye margins here since the loop above only
+ * considers margins which are directly adjacent to some stone of
+ * the dragon.
+ */
+ if (mx[pos] == 1
+ && eye[pos].msize == 0)
strong_eyes++;
}
@@ -1665,6 +1670,9 @@
return CRITICAL;
}
+ if (DRAGON2(pos).moyo_territorial_value > 9.99)
+ return ALIVE;
+
return UNKNOWN;
}
Index: engine/move_reasons.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.c,v
retrieving revision 1.119
diff -u -r1.119 move_reasons.c
--- engine/move_reasons.c 18 Nov 2003 08:55:46 -0000 1.119
+++ engine/move_reasons.c 1 Jan 2004 12:42:39 -0000
@@ -1524,7 +1524,7 @@
worm_is_safe = 1;
popgo();
}
- if (worm_is_safe) {
+ if (worm_is_safe || move_reason_type == SEMEAI_MOVE) {
/* This string can now be considered safe. Hence we mark the
* whole string as such:
*/
Index: engine/owl.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v
retrieving revision 1.186
diff -u -r1.186 owl.c
--- engine/owl.c 31 Dec 2003 07:03:39 -0000 1.186
+++ engine/owl.c 1 Jan 2004 12:42:42 -0000
@@ -335,9 +335,10 @@
int save_verbose = verbose;
int dummy_resulta;
int dummy_resultb;
+ int dummy_semeai_move;
double start = 0.0;
int reading_nodes_when_called = get_reading_node_counter();
-
+
struct local_owl_data *owla;
struct local_owl_data *owlb;
@@ -345,7 +346,9 @@
resulta = &dummy_resulta;
if (!resultb)
resultb = &dummy_resultb;
-
+ if (!semeai_move)
+ semeai_move = &dummy_semeai_move;
+
if (debug & DEBUG_OWL_PERFORMANCE)
start = gg_cputime();
@@ -474,14 +477,14 @@
if (move == PASS_MOVE) {
DEBUG(DEBUG_OWL_PERFORMANCE,
"analyze_semeai %1m vs. %1m, result %d %d %1m (%d, %d nodes, %f
seconds)\n",
- apos, bpos, *resulta, *resultb, semeai_move, local_owl_node_counter,
+ apos, bpos, *resulta, *resultb, *semeai_move, local_owl_node_counter,
get_reading_node_counter() - reading_nodes_when_called,
gg_cputime() - start);
}
else {
DEBUG(DEBUG_OWL_PERFORMANCE,
"analyze_semeai_after_move %C %1m: %1m vs. %1m, result %d %d %1m (%d,
%d nodes, %f seconds)\n",
- color, move, apos, bpos, *resulta, *resultb, semeai_move,
+ color, move, apos, bpos, *resulta, *resultb, *semeai_move,
local_owl_node_counter,
get_reading_node_counter() - reading_nodes_when_called,
gg_cputime() - start);
@@ -547,6 +550,11 @@
int dummy_move;
int tested_moves;
int critical_semeai_worms[MAX_SEMEAI_WORMS];
+ int sworm;
+ int we_might_be_inessential;
+ struct eyevalue probable_eyes_a;
+ struct eyevalue probable_eyes_b;
+ struct eyevalue dummy_eyes;
SETUP_TRACE_INFO2("do_owl_analyze_semeai", apos, bpos);
@@ -614,8 +622,7 @@
{
int upos;
- int sworm;
-
+
for (sworm = 0; sworm < s_worms; sworm++) {
critical_semeai_worms[sworm] = 0;
if (board[semeai_worms[sworm]] == other) {
@@ -644,14 +651,19 @@
* threatened, try to save it.
*/
+ we_might_be_inessential = 1;
for (sworm = 0; sworm < s_worms; sworm++)
- if (board[semeai_worms[sworm]] == color
- && attack(semeai_worms[sworm], NULL)
- && find_defense(semeai_worms[sworm], &upos)) {
- critical_semeai_worms[sworm] = 1;
- owl_add_move(moves, upos, 85, "defend semeai worm", 1, 0, NO_MOVE,
- MAX_SEMEAI_MOVES);
- TRACE("Added %1m %d (0)\n", upos, 85);
+ if (board[semeai_worms[sworm]] == color) {
+ if (important_semeai_worms[sworm])
+ we_might_be_inessential = 0;
+
+ if (attack(semeai_worms[sworm], NULL)
+ && find_defense(semeai_worms[sworm], &upos)) {
+ critical_semeai_worms[sworm] = 1;
+ owl_add_move(moves, upos, 85, "defend semeai worm", 1, 0, NO_MOVE,
+ MAX_SEMEAI_MOVES);
+ TRACE("Added %1m %d (0)\n", upos, 85);
+ }
}
}
@@ -662,13 +674,15 @@
* of filling liberties until one of the dragons may be removed,
* or a seki results. The first stage we call the owl phase.
*/
- if (owl_phase) {
+ if (!owl_phase) {
+ set_eyevalue(&probable_eyes_a, 0, 0, 0, 0);
+ set_eyevalue(&probable_eyes_b, 0, 0, 0, 0);
+ }
+ else {
/* First the vital moves. These include moves to attack or
* defend the eyespace (e.g. nakade, or hane to reduce the
* number of eyes) or moves to capture a lunch.
*/
- struct eyevalue probable_eyes_a;
- struct eyevalue probable_eyes_b;
int eyemin_a;
int eyemin_b;
int eyemax_a;
@@ -795,10 +809,10 @@
* opponent semeai worms are allowed to be included for vital
* moves.
*/
- if (moves[0].pos == NO_MOVE) {
+ if (moves[0].pos == NO_MOVE || we_might_be_inessential) {
include_semeai_worms_in_eyespace = 1;
if (!owl_estimate_life(owlb, owla, vital_offensive_moves,
- &live_reasonb, komaster, 1, &probable_eyes_b,
+ &live_reasonb, komaster, 1, &dummy_eyes,
&eyemin_b, &eyemax_b))
semeai_review_owl_moves(vital_offensive_moves, owla, owlb, color,
&safe_outside_liberty_found,
@@ -1002,10 +1016,8 @@
*/
if (tested_moves == 0) {
const char *live_reasona;
- struct eyevalue probable_eyes_a;
int eyemin_a;
int eyemax_a;
- int sworm;
for (sworm = 0; sworm < s_worms; sworm++) {
if (board[semeai_worms[sworm]] == other) {
if (important_semeai_worms[sworm])
@@ -1016,7 +1028,7 @@
if (sworm == s_worms) {
include_semeai_worms_in_eyespace = 1;
if (!owl_estimate_life(owla, owlb, vital_defensive_moves,
- &live_reasona, komaster, 0, &probable_eyes_a,
+ &live_reasona, komaster, 0, &dummy_eyes,
&eyemin_a, &eyemax_a)) {
include_semeai_worms_in_eyespace = 0;
*resulta = 0;
@@ -1029,14 +1041,34 @@
}
}
- /* If we can't find a move and opponent passed, it's seki */
+ /* If we can't find a move and opponent passed, it's seki, unless
+ * one dragon has more eyes than the other.
+ */
if (tested_moves == 0 && pass == 1) {
- *resulta = WIN;
- *resultb = 0;
- *move = PASS_MOVE;
- TRACE("Seki\n");
- SGFTRACE_SEMEAI(PASS_MOVE, WIN, 0, "Seki");
- READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, WIN, 0);
+ if (max_eyes(&probable_eyes_a) < min_eyes(&probable_eyes_b)) {
+ *resulta = 0;
+ *resultb = 0;
+ *move = PASS_MOVE;
+ TRACE("You have more eyes.\n");
+ SGFTRACE_SEMEAI(PASS_MOVE, 0, 0, "You have more eyes");
+ READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, 0, 0);
+ }
+ else if (max_eyes(&probable_eyes_b) < min_eyes(&probable_eyes_a)) {
+ *resulta = WIN;
+ *resultb = WIN;
+ *move = PASS_MOVE;
+ TRACE("I have more eyes\n");
+ SGFTRACE_SEMEAI(PASS_MOVE, WIN, WIN, "I have more eyes");
+ READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, WIN, WIN);
+ }
+ else {
+ *resulta = WIN;
+ *resultb = 0;
+ *move = PASS_MOVE;
+ TRACE("Seki\n");
+ SGFTRACE_SEMEAI(PASS_MOVE, WIN, 0, "Seki");
+ READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, WIN, 0);
+ }
}
/* If no move was found, then pass. */
@@ -1489,7 +1521,7 @@
int result;
struct local_owl_data *owl;
int reading_nodes_when_called = get_reading_node_counter();
- double start = 0;
+ double start = 0.0;
int tactical_nodes;
int move = NO_MOVE;
int wpos = NO_MOVE;
@@ -2011,7 +2043,7 @@
int result = 0;
int reading_nodes_when_called = get_reading_node_counter();
char saved_boundary[BOARDMAX];
- double start = 0;
+ double start = 0.0;
int tactical_nodes;
int move = 0;
int move2 = 0;
@@ -2137,7 +2169,7 @@
int result;
static struct local_owl_data *owl;
int reading_nodes_when_called = get_reading_node_counter();
- double start = 0;
+ double start = 0.0;
int tactical_nodes;
int move = NO_MOVE;
int wpos = NO_MOVE;
@@ -2343,7 +2375,6 @@
break;
case 3:
-#if 1
{
int goalcount = 0;
@@ -2384,7 +2415,6 @@
if (!moves)
continue;
}
-#endif
} /* switch (pass) */
/* For the up to MAX_MOVES best moves with value equal to
@@ -2531,7 +2561,7 @@
struct local_owl_data *owl;
int reading_nodes_when_called = get_reading_node_counter();
char saved_goal[BOARDMAX];
- double start = 0;
+ double start = 0.0;
int tactical_nodes;
int move = 0;
int move2 = 0;
@@ -4182,6 +4212,16 @@
continue;
}
}
+
+ /* If owl thinks the dragon is dead but the semeai code has
+ * revised the status to critical, then the owl attack point
+ * tends to be unreliable. Don't add it in that case.
+ *
+ * FIXME: Instead of just discarding it, we may want to test
+ * whether it also wins the semeai.
+ */
+ if (DRAGON2(pos).owl_status != CRITICAL)
+ continue;
/* If we've reached this far, the attack is okay. */
if (DRAGON2(pos).owl_attack_code == GAIN) {
@@ -4318,7 +4358,7 @@
int acode;
int wpos = NO_MOVE;
int wid = MAX_GOAL_WORMS;
- double start = 0;
+ double start = 0.0;
if (debug & DEBUG_OWL_PERFORMANCE)
start = gg_cputime();
Index: engine/reading.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/reading.c,v
retrieving revision 1.130
diff -u -r1.130 reading.c
--- engine/reading.c 24 Nov 2003 21:15:20 -0000 1.130
+++ engine/reading.c 1 Jan 2004 12:42:46 -0000
@@ -919,7 +919,7 @@
/* If d is safe too, we have at least managed to break through. */
if (!attack(dpos, &gpos))
success = CUT;
-
+
/* Too bad, d could be attacked. We let O play the attack and
* then try to make a second cut at e. But first we must test if
* O at e is sufficient to capture d.
@@ -939,7 +939,7 @@
popgo();
return 0;
}
-
+
if (trymove(gpos, color, "break_through_helper-F", Fpos,
EMPTY, NO_MOVE)) {
if (trymove(epos, other, "break_through_helper-G", Fpos,
@@ -967,55 +967,62 @@
}
popgo();
}
+ else {
+ /* Failed to cut at all. */
+ popgo();
+ popgo();
+ return 0;
+ }
popgo();
}
}
/* By now, we're sure a cut works, so now we can try
- * to capture something. */
- if (!board[apos] || !board[bpos] || !defend_both(apos, bpos))
- success = WIN;
- else {
- /* Both a and b could be defended, or didn't need to be.
- * Let's see if a move at e is sufficient for O.
- */
- int attack_on_b = 0;
- int attack_on_a = 0;
-
- if (trymove(epos, color, "break_through_helper-B", Fpos,
- EMPTY, NO_MOVE)) {
- if (attack(bpos, NULL))
- attack_on_b = 1;
- else if (attack(apos, NULL))
- attack_on_a = 1;
- popgo();
- }
-
- /* Let O find a defense and play it. */
- if (attack_on_a || attack_on_b) {
- int hpos = NO_MOVE;
-
- if (((attack_on_a && find_defense(apos, &hpos))
- || (attack_on_b && find_defense(bpos, &hpos)))
- && hpos != NO_MOVE
- && trymove(hpos, color, "break_through_helper-C", Fpos,
- EMPTY, NO_MOVE)) {
- /* Now we make a second cut at e, trying to capture
- * either b or c.
- */
- if (trymove(epos, other, "break_through_helper-D", Fpos,
- EMPTY, NO_MOVE)) {
- if (!board[bpos]
- || !board[cpos]
- || !defend_both(bpos, cpos))
- success = WIN;
- popgo();
- }
+ * to capture something.
+ */
+ if (!board[apos] || !board[bpos] || !defend_both(apos, bpos))
+ success = WIN;
+ else {
+ /* Both a and b could be defended, or didn't need to be.
+ * Let's see if a move at e is sufficient for O.
+ */
+ int attack_on_b = 0;
+ int attack_on_a = 0;
+
+ if (trymove(epos, color, "break_through_helper-B", Fpos,
+ EMPTY, NO_MOVE)) {
+ if (attack(bpos, NULL))
+ attack_on_b = 1;
+ else if (attack(apos, NULL))
+ attack_on_a = 1;
+ popgo();
+ }
+
+ /* Let O find a defense and play it. */
+ if (attack_on_a || attack_on_b) {
+ int hpos = NO_MOVE;
+
+ if (((attack_on_a && find_defense(apos, &hpos))
+ || (attack_on_b && find_defense(bpos, &hpos)))
+ && hpos != NO_MOVE
+ && trymove(hpos, color, "break_through_helper-C", Fpos,
+ EMPTY, NO_MOVE)) {
+ /* Now we make a second cut at e, trying to capture
+ * either b or c.
+ */
+ if (trymove(epos, other, "break_through_helper-D", Fpos,
+ EMPTY, NO_MOVE)) {
+ if (!board[bpos]
+ || !board[cpos]
+ || !defend_both(bpos, cpos))
+ success = WIN;
popgo();
}
- else
- success = WIN; /* This should have been covered by
- * defend_both(), so probably unnecessary. */
+ popgo();
+ }
+ else
+ success = WIN; /* This should have been covered by
+ * defend_both(), so probably unnecessary. */
}
}
}
Index: engine/semeai.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/semeai.c,v
retrieving revision 1.65
diff -u -r1.65 semeai.c
--- engine/semeai.c 29 Nov 2003 08:56:33 -0000 1.65
+++ engine/semeai.c 1 Jan 2004 12:42:47 -0000
@@ -32,7 +32,7 @@
static void find_moves_to_make_seki(void);
static void update_status(int dr, enum dragon_status new_status,
enum dragon_status new_safety);
-
+static int close_enough_for_proper_semeai(int apos, int bpos);
/* semeai() searches for pairs of dragons of opposite color which
* have safety DEAD. If such a pair is found, owl_analyze_semeai is
@@ -94,6 +94,15 @@
|| DRAGON2(bpos).safety == INESSENTIAL)
continue;
+ /* Sometimes the dragons are considered neighbors but are too
+ * distant to constitute a proper semeai, e.g. in nngs4:650, P2
+ * vs. R3. Then the result of semeai reading may be meaningless
+ * and can confuse the analysis. In order to avoid this we check
+ * that the dragons either are directly adjacent or at least
+ * have one common liberty.
+ */
+ if (!close_enough_for_proper_semeai(apos, bpos))
+ continue;
/* The array semeai_results_first[d1][d2] will contain the status
* of d1 after the d1 d2 semeai, giving d1 the first move.
@@ -235,7 +244,7 @@
&& DRAGON2(str).hostile_neighbors == 1) {
int k;
int color = board[str];
- int opponent;
+ int opponent = NO_MOVE;
int certain;
for (k = 0; k < DRAGON2(str).neighbors; k++) {
@@ -244,6 +253,8 @@
break;
}
+ ASSERT1(opponent != NO_MOVE, opponent);
+
if (dragon[opponent].status != ALIVE)
continue;
@@ -284,19 +295,16 @@
}
-/* liberty_of_dragon(pos, origin) returns true if the vertex at (pos) is a
- * liberty of the dragon with origin at (origin).
+/* neighbor_of_dragon(pos, origin) returns true if the vertex at (pos) is a
+ * neighbor of the dragon with origin at (origin).
*/
static int
-liberty_of_dragon(int pos, int origin)
+neighbor_of_dragon(int pos, int origin)
{
int k;
if (pos == NO_MOVE)
return 0;
- if (board[pos] != EMPTY)
- return 0;
-
for (k = 0; k < 4; k++)
if (ON_BOARD(pos + delta[k]) && dragon[pos + delta[k]].origin == origin)
return 1;
@@ -304,6 +312,28 @@
return 0;
}
+/* Check whether two dragons are directly adjacent or have at least
+ * one common liberty.
+ */
+static int
+close_enough_for_proper_semeai(int apos, int bpos)
+{
+ int pos;
+ for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+ if (board[pos] == EMPTY
+ && neighbor_of_dragon(pos, apos)
+ && neighbor_of_dragon(pos, bpos))
+ return 1;
+ else if (IS_STONE(board[pos])) {
+ if (is_same_dragon(pos, apos) && neighbor_of_dragon(pos, bpos))
+ return 1;
+ if (is_same_dragon(pos, bpos) && neighbor_of_dragon(pos, apos))
+ return 1;
+ }
+ }
+
+ return 0;
+}
/* This function adds the semeai related move reasons, using the information
* stored in the dragon2 array.
@@ -332,10 +362,10 @@
add_semeai_move(dragon2[d].semeai_defense_point, dragon2[d].origin);
DEBUG(DEBUG_SEMEAI, "Adding semeai defense move for %1m at %1m\n",
DRAGON(d).origin, dragon2[d].semeai_defense_point);
- if (liberty_of_dragon(dragon2[d].semeai_defense_point,
- dragon2[d].semeai_target)
- && !liberty_of_dragon(dragon2[d].semeai_defense_point,
- dragon2[d].origin)
+ if (neighbor_of_dragon(dragon2[d].semeai_defense_point,
+ dragon2[d].semeai_target)
+ && !neighbor_of_dragon(dragon2[d].semeai_defense_point,
+ dragon2[d].origin)
&& !is_self_atari(dragon2[d].semeai_defense_point, color)) {
/* If this is a move to fill the non-common liberties of the
@@ -347,7 +377,7 @@
liberties = findlib(dragon2[d].semeai_target, MAXLIBS, libs);
for (r = 0; r < liberties; r++) {
- if (!liberty_of_dragon(libs[r], dragon2[d].origin)
+ if (!neighbor_of_dragon(libs[r], dragon2[d].origin)
&& !is_self_atari(libs[r], color)
&& libs[r] != dragon2[d].semeai_defense_point) {
owl_analyze_semeai_after_move(libs[r], color,
@@ -375,16 +405,16 @@
add_semeai_move(dragon2[d].semeai_attack_point, dragon2[d].origin);
DEBUG(DEBUG_SEMEAI, "Adding semeai attack move for %1m at %1m\n",
DRAGON(d).origin, dragon2[d].semeai_attack_point);
- if (liberty_of_dragon(dragon2[d].semeai_attack_point,
- dragon2[d].origin)
- && !liberty_of_dragon(dragon2[d].semeai_attack_point,
+ if (neighbor_of_dragon(dragon2[d].semeai_attack_point,
+ dragon2[d].origin)
+ && !neighbor_of_dragon(dragon2[d].semeai_attack_point,
dragon2[d].semeai_target)
&& !is_self_atari(dragon2[d].semeai_attack_point, color)) {
liberties = findlib(dragon2[d].origin, MAXLIBS, libs);
for (r = 0; r < liberties; r++) {
- if (!liberty_of_dragon(libs[r], dragon2[d].semeai_target)
+ if (!neighbor_of_dragon(libs[r], dragon2[d].semeai_target)
&& !is_self_atari(libs[r], color)
&& libs[r] != dragon2[d].semeai_attack_point) {
owl_analyze_semeai_after_move(libs[r], color, dragon2[d].origin,
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.114
diff -u -r1.114 value_moves.c
--- engine/value_moves.c 19 Nov 2003 07:53:49 -0000 1.114
+++ engine/value_moves.c 1 Jan 2004 12:42:47 -0000
@@ -1345,6 +1345,16 @@
return result;
}
+static int
+max_lunch_eye_value(int pos)
+{
+ int min;
+ int probable;
+ int max;
+
+ estimate_lunch_eye_value(pos, &min, &probable, &max, 0);
+ return max;
+}
/*
* Estimate the direct territorial value of a move at (pos).
@@ -2097,15 +2107,8 @@
break;
/* If the lunch has no potential to create eyes, no points. */
- {
- int min;
- int probable;
- int max;
-
- estimate_lunch_eye_value(aa, &min, &probable, &max, 0);
- if (max == 0)
- break;
- }
+ if (max_lunch_eye_value(aa) == 0)
+ break;
/* Can't use k in this loop too. */
for (l = 0; l < next_lunch; l++)
@@ -2232,8 +2235,6 @@
* This does not apply if we are doing scoring.
*
* FIXME: The margin of victory limit is not implemented.
- * FIXME: We need some heuristic whether this connection is
- * relevant at all, see e.g. thrash:4.
*/
if (!doing_scoring) {
@@ -2241,7 +2242,7 @@
aa = dragon[conn_worm1[move_reasons[r].what]].origin;
bb = dragon[conn_worm2[move_reasons[r].what]].origin;
cc = get_last_opponent_move(color);
-
+
if (cc != NO_MOVE
&& dragon[cc].status == DEAD
&& are_neighbor_dragons(aa, cc)
@@ -2249,8 +2250,15 @@
if (aa == bb)
this_value = 1.6 * dragon[cc].effective_size;
else if (DRAGON2(aa).safety == INESSENTIAL
- || DRAGON2(bb).safety == INESSENTIAL)
- this_value = 0.8 * dragon[cc].effective_size;
+ || DRAGON2(bb).safety == INESSENTIAL) {
+ if ((DRAGON2(aa).safety == INESSENTIAL
+ && max_lunch_eye_value(aa) == 0)
+ || (DRAGON2(bb).safety == INESSENTIAL
+ && max_lunch_eye_value(bb) == 0))
+ this_value = 0.0;
+ else
+ this_value = 0.8 * dragon[cc].effective_size;
+ }
else
this_value = 1.7 * dragon[cc].effective_size;
Index: patterns/barriers.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/barriers.db,v
retrieving revision 1.59
diff -u -r1.59 barriers.db
--- patterns/barriers.db 19 Nov 2003 07:53:49 -0000 1.59
+++ patterns/barriers.db 7 Jan 2004 00:02:38 -0000
@@ -3255,7 +3255,7 @@
>non_oterritory(d);
-Pattern Nonterritory51
+Pattern Nonterritory49
# gf New pattern. (3.5.3)
# See gifu03:205.
@@ -3274,7 +3274,7 @@
>non_xterritory(d);
-Pattern Nonterritory52
+Pattern Nonterritory50
# gf New pattern. (3.5.3)
# See gifu03:205.
@@ -3293,7 +3293,7 @@
>non_xterritory(d);
-Pattern Nonterritory54
+Pattern Nonterritory51
# gf New pattern. (3.5.3)
# See gifu03:206.
@@ -3310,5 +3310,65 @@
;!safe_omove(a) && !oplay_defend_both(b,a,?,c,b,d)
>non_oterritory(c);
+
+
+Pattern Nonterritory52
+# gf New pattern. (3.5.3)
+# See blunder:17.
+
+O??
+.XO
+?.?
+
+:8,t
+
+O??
+aCb
+?d?
+
+;lib(C)==2 && !adjacent_to_stone_in_atari(C) && !oplay_attack_either(a,a,b)
+
+>non_xterritory(d);
+
+
+Pattern Nonterritory53
+# gf New pattern. (3.5.3)
+# See gifu03:205.
+
+O.O
+.XO
+?.?
+
+:8,t
+
+Obc
+aXc
+?d?
+
+;oplay_attack(a,b,b) && !oplay_attack_either(a,a,c)
+
+>non_xterritory(d);
+
+
+Pattern Nonterritory54
+# gf New pattern. (3.5.3)
+# See nicklas4:1103
+
+OX.
+...
+...
+---
+
+:8,t
+
+ODc
+eab
+...
+---
+
+;oplay_defend_both(a,b,c,D,b) && oplay_attack(a,b,a)
+
+>non_oterritory(e);
+
# END OF FILE
Index: patterns/eyes.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/eyes.db,v
retrieving revision 1.44
diff -u -r1.44 eyes.db
--- patterns/eyes.db 19 Nov 2003 07:53:49 -0000 1.44
+++ patterns/eyes.db 7 Jan 2004 00:02:39 -0000
@@ -5539,13 +5539,22 @@
Pattern 78505
----
+..*.
+.XX
+
+:1122
+
+
+Pattern 78506
+
+----
X.*.
xX.
:1122
-Pattern 78506
+Pattern 78507
----
*.X.
@@ -5554,7 +5563,7 @@
:1122
-Pattern 78507
+Pattern 78508
----
*.X.
@@ -5563,7 +5572,7 @@
:1122
-Pattern 78508
+Pattern 78509
----
X.X.
@@ -5572,7 +5581,7 @@
:1122
-Pattern 78509
+Pattern 78510
----
X.X.
@@ -5594,7 +5603,7 @@
Pattern 78521
-|X.
+|xx
|XX
|.X.
+---
@@ -5610,6 +5619,16 @@
+---
:1111
+
+
+Pattern 78523
+
+|xx
+|XX
+|.*.
++---
+
+:1122
Pattern 78550
Index: patterns/helpers.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/helpers.c,v
retrieving revision 1.57
diff -u -r1.57 helpers.c
--- patterns/helpers.c 13 Nov 2003 22:48:44 -0000 1.57
+++ patterns/helpers.c 7 Jan 2004 00:02:39 -0000
@@ -685,6 +685,25 @@
}
/* True if str is adjacent to a stone in atari, which is tactically
+ * attackable (to exclude pointless captures of snapback stones).
+ */
+int
+adjacent_to_stone_in_atari(int str)
+{
+ int adj;
+ int adjs[MAXCHAIN];
+ int k;
+
+ adj = chainlinks2(str, adjs, 1);
+ for (k = 0; k < adj; k++)
+ if (attack(adjs[k], NULL))
+ return 1;
+
+ return 0;
+}
+
+
+/* True if str is adjacent to a stone in atari, which is tactically
* defendable.
*/
int
Index: patterns/mkpat.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/mkpat.c,v
retrieving revision 1.127
diff -u -r1.127 mkpat.c
--- patterns/mkpat.c 18 Nov 2003 00:00:02 -0000 1.127
+++ patterns/mkpat.c 7 Jan 2004 00:02:41 -0000
@@ -366,6 +366,8 @@
{"surround_map", 2, 0, 0.01, "surround_map(%s, %s)"},
{"oracle_threatens", 2, 0, 0.01, "oracle_threatens(%s, %s)"},
{"value", 0, 2, 0.0, "(%s->value)"},
+ {"adjacent_to_stone_in_atari",1, 0, 1.0,
+ "adjacent_to_stone_in_atari(%s)"},
{"adjacent_to_defendable_stone_in_atari", 1, 0, 1.0,
"adjacent_to_defendable_stone_in_atari(%s)"},
{"good_attack_threat", 2, 0, 0.01, "register_good_attack_threat(%s,
%s)"}
Index: patterns/owl_attackpats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_attackpats.db,v
retrieving revision 1.100
diff -u -r1.100 owl_attackpats.db
--- patterns/owl_attackpats.db 29 Nov 2003 08:56:33 -0000 1.100
+++ patterns/owl_attackpats.db 7 Jan 2004 00:02:42 -0000
@@ -1186,6 +1186,26 @@
;!oplay_disconnect(*,a,b)
+Pattern A242
+# gf New pattern. (3.5.3).
+# See e.g. nngs:1090.
+
+
+...o?
+..*O?
+...Xx
+-----
+
+:8,-,value(35)
+
+...o?
+ba*c?
+...Xx
+-----
+
+;xplay_disconnect(*,a,a,c) && xplay_disconnect(*,b,b,c)
+
+
#########################################################
# #
# Limiting moves on the first line #
@@ -1448,11 +1468,30 @@
Pattern A407
+# gf Added constraint. (3.5.3)
-O.X
-*Y.
-...
-...
+?O.X
+?*Y.
+?...
+?...
+
+:8,-,value(45)
+
+aO.X
+b*Y.
+c...
+?...
+
+;!(o_somewhere(a) && o_somewhere(b)) || x_somewhere(c)
+
+
+Pattern A407b
+# gf New pattern. (3.5.3)
+
+OO.X
+O.Y.
+o*..
+?...
:8,-,value(45)
@@ -2124,6 +2163,18 @@
:8,-,value(5)
+Pattern A518
+# gf New pattern. (3.5.3)
+# See nngs2:460
+
+O.xx? destroye eye
+.*.XX
+....X
+-----
+
+:8,-,value(45)
+
+
#########################################################
# #
# Eye reducing moves on the first line #
@@ -2501,6 +2552,24 @@
;lib(A)<3 && owl_eyespace(*)
+Pattern A622
+# gf New patterm. (3.5.3)
+# Compare D704b. See nngs3:450.
+
+xX.O half eye sometimes missed
+X.*o
+----
+
+:8,-,value(35)
+
+bXaO
+X.*o
+----
+
+; xplay_attack(*,a,a)
+; && (x_somewhere(b) || !safe_omove(b))
+
+
#########################################################
# #
# Eye reducing moves in the center #
@@ -3237,6 +3306,7 @@
Pattern A910
+# gf Revised constraint. (3.5.3)
XYX| try nakade in corner
.*.|
@@ -3248,7 +3318,7 @@
a*.|
---+
-;!obvious_false_xeye(a)
+;!obvious_false_xeye(a) && owl_maxeye(*)>1
Pattern A911
@@ -4432,18 +4502,20 @@
Pattern A1126
-# tm New Pattern (3.1.23) (see Pattern D1378)
+# tm New Pattern (3.1.23)
+# gf Revised constraint. (3.5.3)
+# See also D1378.
O*O prevent breakout & attack
?Y?
:|,-,value(55)
-A*B
+a*b
?Y?
-; vital_chain(A) && vital_chain(B)
-; && xplay_attack_either(*,A,B)
+; vital_chain(a) && vital_chain(b)
+; && xplay_attack_either(*,a,b) && !xplay_connect(*,a,b)
Pattern A1127
@@ -4598,18 +4670,68 @@
Pattern A1134
# pp New pattern (3.5.3). See trevorb:120.
# FIXME: is it better to do this algorithmically with owl boundaries?
+# gf Added explicit anchoring. (3.5.3)
-XOX prevent escaping by capturing
+XOY prevent escaping by capturing
.*O
---
:8,-,value(75)
-BOX
-.*A
+BOY
+.*a
+---
+
+; lib(a) == 1 && owl_escape_value(B) > 0
+
+
+Pattern A1134b
+# gf New pattern. (3.5.3).
+
+YOX prevent escaping by capturing
+.*O
+---
+
+:8,-,value(75)
+
+YOB
+.*a
+---
+
+; lib(a) == 1 && owl_escape_value(B) > 0
+
+
+Pattern A1134c
+# gf New pattern. (3.5.3).
+
+XOY prevent escaping by capturing
+.*O
+---
+
+:8,-,value(40)
+
+BOY
+.*a
+---
+
+; lib(a) == 1
+
+
+Pattern A1134d
+# gf New pattern. (3.5.3).
+# See 13x13b:23
+
+YOX prevent escaping by capturing
+.*O
+---
+
+:8,-,value(40)
+
+YOB
+.*a
---
-; lib(A) == 1 && owl_escape_value(B) > 0
+; lib(a) == 1
Pattern A1135
@@ -4644,6 +4766,25 @@
?A?
;owl_escape_value(A)>0 && !xplay_disconnect(*,A,B) && !oplay_connect(*,A,B)
+
+
+Pattern A1137
+# gf New pattern. (3.5.3)
+# Converse to D1125.
+
+xxx?
+...x
+.*O.
+?XXO
+
+:8,-,value(79)
+
+abc?
+...x
+.*O.
+?XXO
+
+;owl_escape_value(a) + owl_escape_value(b) + owl_escape_value(c) > 0
#########################################################
Index: patterns/owl_defendpats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_defendpats.db,v
retrieving revision 1.109
diff -u -r1.109 owl_defendpats.db
--- patterns/owl_defendpats.db 29 Nov 2003 08:56:33 -0000 1.109
+++ patterns/owl_defendpats.db 7 Jan 2004 00:02:47 -0000
@@ -715,6 +715,7 @@
Pattern D212
+# gf FIXME: This is not a second line move. Move the pattern.
??O??? capture one stone to improve eye space
?..OX?
@@ -894,6 +895,17 @@
:8,-,value(35)
+Pattern D221b
+# gf New pattern. (3.5.3)
+
+oo?x jump along second line
+O.*.
+O...
+----
+
+:8,-,value(45)
+
+
Pattern D222
# tm Pattern revised. (3.1.13)
@@ -1025,6 +1037,7 @@
Pattern D230
# tm New Pattern (3.1.16)
# gf Not down to edge. (3.3.20)
+# gf Not if it can be cut off. Constraint added. (3.5.3)
?OO...? expand along edge.
o....*?
@@ -1033,6 +1046,13 @@
:8,-,value(80)
+?Ob...?
+o...a*?
+?.....?
+-------
+
+;oplay_connect(*,a,*,b)
+
Pattern D231
# tm New Pattern (3.1.20) (see nngs:1320 owl_does_attack L15 M17)
@@ -1089,6 +1109,26 @@
:8,n,value(35)
+Pattern D234
+# gf New pattern. (3.5.3).
+# See e.g. nngs:1090.
+
+
+...x?
+..*X?
+...Oo
+-----
+
+:8,-,value(35)
+
+...x?
+ba*C?
+...Oo
+-----
+
+;oplay_disconnect(*,a,a,C) && oplay_disconnect(*,b,b,C)
+
+
#########################################################
# #
# Expanding moves in the center #
@@ -4133,6 +4173,7 @@
Pattern D1102
# tm reduced value (3.1.16)
+# gf Revised constraint. (3.5.3)
... create cutting points
X*X
@@ -4140,11 +4181,11 @@
:|,-,value(50)
-...
+c.d
A*B
?O?
-;lib(A)<=3 || lib(B)<=3
+;(lib(A)<=3 && olib(c)>2) || (lib(B)<=3 && olib(d)>2)
Pattern D1102a
@@ -4876,6 +4917,60 @@
; && (oplay_attack(*,B) || oplay_attack(*,C)) && !oplay_connect(*,B,C)
+Pattern D1143
+# gf New pattern. (3.5.3).
+# See e.g. nngs:1090.
+
+
+.*XO
+XOXO
+..Oo
+----
+
+:8,-,value(65)
+
+.*Ac
+BOAc
+..do
+----
+
+;lib(A)==2 && lib(c)>1 && lib(d)>1 && oplay_attack(*,B)
+
+
+Pattern D1144
+# gf New pattern. (3.5.3).
+# See 13x13b:23.
+
+OXO escape by capturing
+.*X
+---
+
+:8,-,value(82)
+
+bXc
+.*A
+---
+
+; lib(A) == 1 && (owl_escape_value(b) > 0 || owl_escape_value(c) > 0)
+
+
+Pattern D1144b
+# gf New pattern. (3.5.3).
+# See 13x13b:23.
+
+OXO escape by capturing
+.*X
+---
+
+:8,-,value(40)
+
+bXc
+.*A
+---
+
+; lib(A) == 1
+
+
########################################################
# #
# Kikashi #
@@ -6193,6 +6288,28 @@
; && oplay_disconnect(*,d,*)
+Pattern D1356b
+# gf New pattern. (3.5.3)
+# See nngs4:40
+
+?.... jump towards safety
+O..*.
+o....
+.....
+-----
+
+:8,E,value(91)
+
+?..a.
+c..*.
+o..b.
+.....
+-----
+
+; (owl_escape_value(a) + owl_escape_value(*) + owl_escape_value(b) > 0)
+; && !oplay_disconnect(*,c,*)
+
+
Pattern D1357
o...o block/connect to escape
@@ -6514,6 +6631,7 @@
Pattern D1378
# tm reduced value (3.1.17)
# gf Revised constraint. (3.3.18)
+# See also A1126.
X*X breakout & attack
?O?
Index: patterns/owl_vital_apats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_vital_apats.db,v
retrieving revision 1.41
diff -u -r1.41 owl_vital_apats.db
--- patterns/owl_vital_apats.db 13 Nov 2003 22:48:44 -0000 1.41
+++ patterns/owl_vital_apats.db 7 Jan 2004 00:02:47 -0000
@@ -754,6 +754,7 @@
# tm New Pattern (3.1.17)
# gf Fixed symmetry. (3.3.6)
# nn Modified constraint (3.3.14)
+# gf Revised constraint. (3.5.3)
XoX
o*o
@@ -766,7 +767,7 @@
; owl_proper_eye(*)
; && (owl_proper_eye(a) + owl_proper_eye(b) + owl_proper_eye(c) > 2)
; && safe_xmove(*)
-; && (owl_eye_size(*) <= 8 || !oplay_attack(*,*))
+; && ((owl_eye_size(*) <= 8 && owl_maxeye(*)>1) || !oplay_attack(*,*))
Pattern VA45
Index: patterns/patterns.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/patterns.db,v
retrieving revision 1.120
diff -u -r1.120 patterns.db
--- patterns/patterns.db 29 Nov 2003 08:56:33 -0000 1.120
+++ patterns/patterns.db 7 Jan 2004 00:02:47 -0000
@@ -4088,6 +4088,7 @@
Pattern EB407
+# gf Added constraint. (3.5.3)
oO.... jump along edge
O...*.
@@ -4096,6 +4097,13 @@
:8,Oe,jump_out_helper
+oa....
+O...*.
+......
+------
+
+;!oplay_disconnect(*,*,a)
+
Pattern EB408
@@ -5117,7 +5125,7 @@
X*a..
-----
-;(xplay_attack(*,a,a) || weak(b))
+;xplay_attack(*,a,a) || weak(b)
Pattern EB706
@@ -5335,6 +5343,23 @@
;!oplay_defend_both(b,c,a,b) && oplay_defend_both(*,c,a,*)
+Pattern EB719
+# gf New pattern. (3.5.3)
+# Inexact followup but usually big.
+
+.XXO block
+XOO*
+----
+
+:8,Xe,followup(6)
+
+aBBd
+Cee*
+----
+
+;alive(d) && critical(e) && !oplay_defend_both(*,?,a,B,C)
+
+
############################################################
# Monkey jump and other intrusions on first and second lines
############################################################
@@ -13472,6 +13497,19 @@
|..XOO..
:8,jda
+
+
+Pattern EJ101
+# gf New pattern. (3.5.3)
+# See nngs:1020.
+
+......X
+.O..OX.
+.....*O
+.......
+-------
+
+:8,jcd
######################################################################
Index: patterns/patterns.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/patterns.h,v
retrieving revision 1.59
diff -u -r1.59 patterns.h
--- patterns/patterns.h 13 Nov 2003 22:48:44 -0000 1.59
+++ patterns/patterns.h 7 Jan 2004 00:02:47 -0000
@@ -297,6 +297,7 @@
int connect_and_cut_helper2(int Apos, int bpos, int cpos, int color);
int edge_double_sente_helper(int move, int apos, int bpos, int cpos);
void test_attack_either_move(int move, int color, int worma, int wormb);
+int adjacent_to_stone_in_atari(int str);
int adjacent_to_defendable_stone_in_atari(int str);
void backfill_replace(int move, int str);
Index: patterns/patterns2.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/patterns2.db,v
retrieving revision 1.67
diff -u -r1.67 patterns2.db
--- patterns/patterns2.db 11 Nov 2003 21:48:59 -0000 1.67
+++ patterns/patterns2.db 7 Jan 2004 00:02:48 -0000
@@ -1070,6 +1070,22 @@
;(alive(a) || alive(b)) && !xplay_disconnect(*,C,D) && !oplay_connect(*,C,D)
+Pattern Cut304
+# gf New pattern. (3.5.3)
+
+?OO
+X.. cut through keima
+?*X
+
+:8,OB
+
+?OO
+Dab
+?*C
+
+;!oplay_defend_both(*,a,b,C,D) && !oplay_connect(*,C,D)
+
+
#######################################
#
# Cut of one space jump from two stones
@@ -2371,6 +2387,7 @@
Pattern Shape66
# db increased negative shape (3.1.7)
# ab added ??? lines added as jump is often good on 3rd line
+# gf This is way too general. Added constraint. (3.5.3)
xX. often bad to leave a gap
O.*
@@ -2380,6 +2397,14 @@
:8,-,shape(-3)
+xX.
+ca*
+.b.
+???
+???
+
+;oplay_disconnect(*,a,b,*,c)
+
Pattern Shape67
# gf New pattern. (3.1.3)
@@ -2985,6 +3010,7 @@
Pattern Sente13b
# gf Revised constraint. (3.1.10)
# gf Revised constraint. (3.3.16)
+# gf Revised constraint. (3.5.3)
.O
*?
@@ -2992,11 +3018,12 @@
:8,sO
ba
-*?
+*c
;lib(a) == 2 && !attack(a) && olib(b) > 2 && safe_omove(*)
;&& (safe_xmove(*) || safe_xmove(b))
-;&& oplay_attack(*,b,b)==WIN
+;&& (oplay_attack(*,b,b)==WIN
+; || (x_somewhere(c) && oplay_attack_either(*,b,b,c)))
# Action adds a reverse followup value.
>defend_against_atari(a)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnugo-devel] Big patch,
Gunnar Farneback <=