[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] tuning patch
From: |
Gunnar Farneback |
Subject: |
[gnugo-devel] tuning patch |
Date: |
Sun, 11 Aug 2002 12:47:13 +0200 |
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 some mixed tuning.
- extended_chainlinks() revised
- MAX_REASONS increased from 80 to 100
- modify_stupid_eye_vital_point() revised
- new functions improve_lunch_attack() and improve_lunch_defense()
- backfilling in do_owl_attack() when trying the defender's best move
- sniff_lunch() revised
- new experimental_connections contingent code in shapes_callback()
- induce_secondary_move_reasons() revised
- tuning
- endgame tuning
- owl tuning
The regression results are somewhat mixed too, with a net result of
plus 2.
New passes
----------
owl: 65
ld_owl: 182
golife: 1
nicklas1: 1405
trevorc: 890, 1580
global: 34
arend: 29
strategy4: 166, 199
nngs2: 110
strategy5: 227, 235
New failures
------------
owl: 47, 66
nngs1: 30
neurogo: 13
rosebud: 1
viking: 12
nicklas1: 1801
global: 40, 41
vie: 41
nngs2: 40
/Gunnar
Index: engine/board.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/board.c,v
retrieving revision 1.47
diff -u -r1.47 board.c
--- engine/board.c 3 May 2002 17:57:58 -0000 1.47
+++ engine/board.c 10 Aug 2002 19:43:55 -0000
@@ -2486,10 +2486,13 @@
/* extended_chainlinks() returns (in the (adj) array) the opponent
* strings being directly adjacent to (str) or having a common liberty
* with (str). The number of such strings is returned.
+ *
+ * If the both_colors parameter is true, also own strings sharing a
+ * liberty are returned.
*/
int
-extended_chainlinks(int str, int adj[MAXCHAIN])
+extended_chainlinks(int str, int adj[MAXCHAIN], int both_colors)
{
struct string_data *s;
int n;
@@ -2521,7 +2524,8 @@
*/
for (r = 0; r < liberties; r++) {
for (k = 0; k < 4; k++) {
- if (board[libs[r] + delta[k]] == OTHER_COLOR(board[str])
+ if ((board[libs[r] + delta[k]] == OTHER_COLOR(board[str])
+ || (both_colors && board[libs[r] + delta[k]] == board[str]))
&& UNMARKED_STRING(libs[r] + delta[k])) {
adj[n] = string[string_number[libs[r] + delta[k]]].origin;
MARK_STRING(adj[n]);
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.107
diff -u -r1.107 liberty.h
--- engine/liberty.h 6 Aug 2002 19:04:11 -0000 1.107
+++ engine/liberty.h 10 Aug 2002 19:43:59 -0000
@@ -141,7 +141,7 @@
int chainlinks(int str, int adj[MAXCHAIN]);
int chainlinks2(int str, int adj[MAXCHAIN], int lib);
int chainlinks3(int str, int adj[MAXCHAIN], int lib);
-int extended_chainlinks(int str, int adj[MAXCHAIN]);
+int extended_chainlinks(int str, int adj[MAXCHAIN], int both_colors);
/* This is increased by one anytime a move is (permanently) played or
Index: engine/move_reasons.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.h,v
retrieving revision 1.20
diff -u -r1.20 move_reasons.h
--- engine/move_reasons.h 11 Jun 2002 14:25:22 -0000 1.20
+++ engine/move_reasons.h 10 Aug 2002 19:43:59 -0000
@@ -73,7 +73,7 @@
#define REDUNDANT (TERRITORY_REDUNDANT | STRATEGICALLY_REDUNDANT)
#define SECONDARY 4
-#define MAX_REASONS 80
+#define MAX_REASONS 100
#define MAX_TRACE_LENGTH 160
Index: engine/owl.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v
retrieving revision 1.98
diff -u -r1.98 owl.c
--- engine/owl.c 8 Aug 2002 23:03:03 -0000 1.98
+++ engine/owl.c 10 Aug 2002 19:44:10 -0000
@@ -208,7 +208,9 @@
int color, int komaster, int does_attack,
struct owl_move_data *moves, int *probable_min,
int *probable_max);
-static int modify_stupid_eye_vital_point(int *vital_point);
+static int modify_stupid_eye_vital_point(struct local_owl_data *owl,
+ int *vital_point,
+ int is_attack_point);
static void owl_mark_dragon(int apos, int bpos,
struct local_owl_data *owl);
static void owl_mark_worm(int apos, int bpos,
@@ -218,6 +220,8 @@
struct local_owl_data *owl, int semeai_call);
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);
+static int improve_lunch_defense(int lunch, int defense_point);
static void owl_make_domains(struct local_owl_data *owla,
struct local_owl_data *owlb);
static int owl_safe_move(int move, int color);
@@ -1374,16 +1378,34 @@
READ_RETURN(read_result, move, 0, WIN);
}
else if (dpos != NO_MOVE) {
- /* The dragon could be defended by another move. Try to attack
- * with this move.
+ /* The dragon could be defended by one more move. Try to
+ * attack with this move.
+ *
+ * If the move is suicide for us, try to find a backfilling
+ * move to play instead.
*/
- shape_moves[0].pos = dpos;
- shape_moves[0].value = 25;
- shape_moves[0].name = "defense move";
- shape_moves[0].same_dragon = 1;
- shape_moves[0].escape = 0;
- shape_moves[1].value = 0;
- moves = shape_moves;
+ shape_moves[0].name = "defense move";
+
+ if (is_suicide(dpos, other)) {
+ int dpos2;
+ for (k = 0; k < 4; k++) {
+ if (board[dpos + delta[k]] == other
+ && find_defense(dpos + delta[k], &dpos2)) {
+ dpos = dpos2;
+ shape_moves[0].name = "defense move (backfill)";
+ break;
+ }
+ }
+ }
+
+ if (dpos != NO_MOVE) {
+ shape_moves[0].pos = dpos;
+ shape_moves[0].value = 25;
+ shape_moves[0].same_dragon = 1;
+ shape_moves[0].escape = 0;
+ shape_moves[1].value = 0;
+ moves = shape_moves;
+ }
}
}
@@ -1465,7 +1487,8 @@
&ko_move, savecode == 0))
continue;
- TRACE("Trying %C %1m. Current stack: ", other, mpos);
+ TRACE("Trying %C %1m. Escape = %d. Current stack: ",
+ other, mpos, escape);
if (verbose)
dump_stack();
@@ -2047,7 +2070,8 @@
if (moves[k].escape)
new_escape++;
- TRACE("Trying %C %1m. Current stack: ", color, mpos);
+ TRACE("Trying %C %1m. Escape = %d. Current stack: ",
+ color, mpos, escape);
if (verbose)
dump_stack();
@@ -2483,7 +2507,7 @@
pos, eyevalue.maxeye, eyevalue.mineye, pessimistic_min);
if (eye[attack_point].marginal
- && modify_stupid_eye_vital_point(&attack_point))
+ && modify_stupid_eye_vital_point(owl, &attack_point, 1))
TRACE("vital point looked stupid, moved it to %1m\n",
attack_point);
@@ -2531,8 +2555,9 @@
reason, defense_point, value, pos,
eyevalue.maxeye, eyevalue.mineye, pessimistic_min);
- if (eye[defense_point].marginal
- && modify_stupid_eye_vital_point(&defense_point))
+ if ((eye[defense_point].marginal
+ || eye[defense_point].origin != pos)
+ && modify_stupid_eye_vital_point(owl, &defense_point, 0))
TRACE("vital point looked stupid, moved it to %1m\n",
defense_point);
@@ -2577,16 +2602,18 @@
continue;
if (does_attack) {
+ defense_point = improve_lunch_defense(owl->lunch[lunch],
+
owl->lunch_defense_point[lunch]);
TRACE("save lunch at %1m with %1m, score %d\n",
- owl->lunch[lunch], owl->lunch_defense_point[lunch], value);
- owl_add_move(moves, owl->lunch_defense_point[lunch], value,
- "save lunch", 1, 0);
+ owl->lunch[lunch], defense_point, value);
+ owl_add_move(moves, defense_point, value, "save lunch", 1, 0);
}
else {
+ attack_point = improve_lunch_attack(owl->lunch[lunch],
+ owl->lunch_attack_point[lunch]);
TRACE("eat lunch at %1m with %1m, score %d\n",
- owl->lunch[lunch], owl->lunch_attack_point[lunch], value);
- owl_add_move(moves, owl->lunch_attack_point[lunch], value,
- "eat lunch", 1, 0);
+ owl->lunch[lunch], attack_point, value);
+ owl_add_move(moves, attack_point, value, "eat lunch", 1, 0);
}
}
}
@@ -2596,7 +2623,9 @@
}
-/* The optics code occasionally comes up with stupid vital moves, like
+/* Case 1.
+ *
+ * The optics code occasionally comes up with stupid vital moves, like
* a in this position:
*
* ----+
@@ -2609,14 +2638,29 @@
*
* This function moves such moves to the second line.
*
+ * Case 2.
+ *
+ * In this position the optics code can suggest the empty 1-2 point as
+ * vital move for the eyespace on the right edge. That is okay for attack
+ * but obviously not for defense.
+ *
+ * ----+
+ * XO.O|
+ * XOOX|
+ * XXO.|
+ * .XOO|
+ * .XXX|
+ *
*/
static int
-modify_stupid_eye_vital_point(int *vital_point)
+modify_stupid_eye_vital_point(struct local_owl_data *owl, int *vital_point,
+ int is_attack_point)
{
int up;
int right;
int k;
-
+
+ /* Case 1. */
for (k = 0; k < 4; k++) {
up = delta[k];
if (ON_BOARD(*vital_point - up))
@@ -2638,6 +2682,20 @@
return 1;
}
}
+
+ /* Case 2. */
+ if (!is_attack_point) {
+ if (approxlib(*vital_point, OTHER_COLOR(owl->color), 1, NULL) == 0) {
+ for (k = 4; k < 8; k++) {
+ int pos = *vital_point + delta[k];
+ if (board[pos] == OTHER_COLOR(owl->color)
+ && countlib(pos) == 1) {
+ findlib(pos, 1, vital_point);
+ return 1;
+ }
+ }
+ }
+ }
return 0;
}
@@ -3343,6 +3401,11 @@
int pos2 = pos + delta[k];
if (ON_BOARD(pos2) && owl->boundary[pos2] > boundary_mark)
boundary_mark = owl->boundary[pos2];
+ if (board[pos2] == owl->color
+ && dragon[pos2].color == owl->color
+ && dragon[pos2].status == ALIVE
+ && !owl->goal[pos2])
+ boundary_mark = 2;
}
owl->boundary[pos] = boundary_mark;
@@ -4000,6 +4063,81 @@
}
+/* Try to improve the move to attack a lunch. Essentially we try to
+ * avoid unsafe moves when there are less risky ways to attack.
+ */
+static int
+improve_lunch_attack(int lunch, int attack_point)
+{
+ int color = OTHER_COLOR(board[lunch]);
+ int defense_point;
+ int k;
+
+ if (safe_move(attack_point, color))
+ return attack_point;
+
+ for (k = 0; k < 4; k++) {
+ int pos = attack_point + delta[k];
+ if (board[pos] == color
+ && attack(pos, NULL)
+ && find_defense(pos, &defense_point)
+ && defense_point != NO_MOVE
+ && does_attack(defense_point, lunch)) {
+ TRACE("Moved attack of lunch %1m from %1m to %1m.\n",
+ lunch, attack_point, defense_point);
+ return defense_point;
+ }
+ }
+
+ return attack_point;
+}
+
+/* Try to improve the move to defend a lunch.
+ *
+ * An example where this is useful is the position below, where the
+ * defense of A is moved from b to c. This is a possible variation in
+ * ld_owl:182.
+ *
+ * ...X..| ...X..|
+ * ...X..| ...Xc.|
+ * ..XXO.| ..XXOb|
+ * XXXOOX| XXXOOA|
+ * XOOOX.| XOOOX.|
+ * .XOX.X| .XOX.X|
+ * ------+ ------+
+ */
+static int improve_lunch_defense(int lunch, int defense_point)
+{
+ int color = board[lunch];
+ int k;
+
+ for (k = 0; k < 4; k++) {
+ int pos = defense_point + delta[k];
+ if (board[pos] == OTHER_COLOR(color)
+ && countlib(pos) == 2) {
+ int libs[2];
+ int pos2;
+
+ findlib(pos, 2, libs);
+ if (libs[0] == defense_point)
+ pos2 = libs[1];
+ else
+ pos2 = libs[0];
+
+ if (accurate_approxlib(pos2, color, MAXLIBS, NULL)
+ > accurate_approxlib(defense_point, color, MAXLIBS, NULL)
+ && does_defend(pos2, lunch)) {
+ TRACE("Moved defense of lunch %1m from %1m to %1m.\n",
+ lunch, defense_point, pos2);
+ return pos2;
+ }
+ }
+ }
+
+ return defense_point;
+}
+
+
/* Wrapper for make domains. The second set of owl data is optional.
* Use a null pointer if it is not needed. Otherwise, make_domains
* is run separately for the two owl data, but information about
@@ -4261,22 +4399,43 @@
*/
static void
-sniff_lunch(int pos, int *min, int *probable, int *max,
+sniff_lunch(int lunch, int *min, int *probable, int *max,
struct local_owl_data *owl)
{
- int other = OTHER_COLOR(board[pos]);
+ int other = OTHER_COLOR(board[lunch]);
int size;
+ int libs[MAXLIBS];
+ int liberties;
+ int r;
- ASSERT1(IS_STONE(board[pos]), pos);
+ ASSERT1(IS_STONE(board[lunch]), lunch);
- if (owl->boundary[pos] == 2) {
+ if (owl->boundary[lunch] == 2) {
*min = 2;
*probable = 2;
*max = 2;
return;
}
- size = countstones(pos);
+ /* Do we believe this capture would help escaping? */
+ liberties = findlib(lunch, MAXLIBS, libs);
+ for (r = 0; r < liberties; r++) {
+ if (owl->escape_values[libs[r]] > 0
+ && !is_self_atari(libs[r], other)) {
+ int k;
+ for (k = 0; k < 8; k++)
+ if (owl->goal[libs[r] + delta[k]])
+ break;
+ if (k == 8) {
+ *min = 2;
+ *probable = 2;
+ *max = 2;
+ return;
+ }
+ }
+ }
+
+ size = countstones(lunch);
if (size > 6) {
*min = 2;
*probable = 2;
@@ -4294,7 +4453,7 @@
}
else if (size == 2) {
int stones[2];
- findstones(pos, 2, stones);
+ findstones(lunch, 2, stones);
/* A lunch on a 1-2 point tends always to be worth contesting. */
if ((obvious_false_eye(stones[0], other)
|| obvious_false_eye(stones[1], other))
@@ -4306,11 +4465,11 @@
else {
*min = 0;
*probable = 1;
- *max = 1;
+ *max = 2;
}
}
else if (size == 1) {
- if (!obvious_false_eye(pos, other)) {
+ if (!obvious_false_eye(lunch, other)) {
*min = 0;
*probable = 1;
*max = 1;
Index: engine/shapes.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/shapes.c,v
retrieving revision 1.33
diff -u -r1.33 shapes.c
--- engine/shapes.c 5 Aug 2002 23:42:15 -0000 1.33
+++ engine/shapes.c 10 Aug 2002 19:44:10 -0000
@@ -29,6 +29,7 @@
/* Maximum number of dragons considered by a, B, C, and d class patterns. */
#define MAX_DRAGONS_PER_PATTERN 5
+#define MAX_STRINGS_PER_PATTERN 5
/* Values of joseki patterns. */
#define U_VALUE 40.0
@@ -45,17 +46,27 @@
shapes_callback(int m, int n, int color, struct pattern *pattern, int ll,
void *data)
{
+ int other = OTHER_COLOR(color);
+
int k, l;
int move;
/* Dragons of our color. */
int my_dragons[MAX_DRAGONS_PER_PATTERN];
int my_ndragons = 0;
-
+
/* Dragons of other color. */
int your_dragons[MAX_DRAGONS_PER_PATTERN];
int your_ndragons = 0;
+ /* Strings of our color. */
+ int my_strings[MAX_STRINGS_PER_PATTERN];
+ int my_nstrings = 0;
+
+ /* Strings of other color. */
+ int your_strings[MAX_STRINGS_PER_PATTERN];
+ int your_nstrings = 0;
+
/* Make a local copy of the classification that we may modify. */
unsigned int class = pattern->class;
@@ -75,8 +86,6 @@
if ((class & (CLASS_B | CLASS_C | CLASS_c | CLASS_a | CLASS_d | CLASS_O |
CLASS_J | CLASS_j | CLASS_U | CLASS_T | CLASS_t)) != 0)
{
- int other = OTHER_COLOR(color);
-
/* Match each point. */
for (k = 0; k < pattern->patlen; ++k) {
int pos; /* absolute (board) co-ord of (transformed) pattern element */
@@ -133,16 +142,54 @@
your_dragons[l] = origin;
your_ndragons++;
}
- }
+ }
+
+ if (pattern->patn[k].att == ATT_O || pattern->patn[k].att == ATT_X) {
+ origin = find_origin(pos);
+ if (board[pos] == color && my_nstrings < MAX_STRINGS_PER_PATTERN) {
+ for (l = 0; l < my_nstrings; l++) {
+ if (my_strings[l] == origin)
+ break;
+ }
+ if (l == my_nstrings) {
+ /* We found another string of our color. Check that it
+ * cannot be tactically captured before adding it to the
+ * list of my_strings.
+ */
+ if (worm[pos].attack_codes[0] == 0
+ || does_defend(move, pos)) {
+ /* Ok, add the string to the list. */
+ my_strings[l] = origin;
+ my_nstrings++;
+ }
+ }
+ }
+
+ if (board[pos] == other && your_nstrings < MAX_STRINGS_PER_PATTERN) {
+ for (l = 0; l < your_nstrings; l++) {
+ if (your_strings[l] == origin)
+ break;
+ }
+ if (l == your_nstrings) {
+ /* We found another opponent string, add it to the list. */
+ your_strings[l] = origin;
+ your_nstrings++;
+ }
+ }
+ }
} /* loop over elements */
} /* if we need to loop over the elements */
/* Nothing to connect. Remove C class bit. */
- if (my_ndragons < 2)
+ if (my_ndragons < 2 && !experimental_connections)
+ class &= ~CLASS_C;
+ if (my_nstrings < 2 && experimental_connections)
class &= ~CLASS_C;
/* Nothing to cut. Remove B class bit. */
- if (your_ndragons < 2)
+ if (your_ndragons < 2 && !experimental_connections)
+ class &= ~CLASS_B;
+ if (your_nstrings < 2 && experimental_connections)
class &= ~CLASS_B;
/*
@@ -183,7 +230,7 @@
*/
if (class & CLASS_n) {
/* Allow ko unsafety. */
- if (safe_move(move, OTHER_COLOR(color)) == 0) {
+ if (safe_move(move, other) == 0) {
if (0)
TRACE(" opponent can't play safely at %1m, move discarded\n", move);
return;
@@ -228,7 +275,7 @@
}
/* Pattern class B, cut all combinations of opponent dragons. */
- if (class & CLASS_B) {
+ if ((class & CLASS_B) && !experimental_connections) {
for (k = 0; k < your_ndragons; k++)
for (l = k+1; l < your_ndragons; l++) {
add_cut_move(move, your_dragons[k], your_dragons[l]);
@@ -237,11 +284,39 @@
}
/* Pattern class C, connect all combinations of our dragons. */
- if (class & CLASS_C) {
+ if ((class & CLASS_C) && !experimental_connections) {
for (k = 0; k < my_ndragons; k++)
for (l = k+1; l < my_ndragons; l++) {
add_connection_move(move, my_dragons[k], my_dragons[l]);
TRACE("...connects dragons %1m, %1m\n", my_dragons[k], my_dragons[l]);
+ }
+ }
+
+ /* Pattern class B, try to cut all combinations of opponent strings. */
+ if ((class & CLASS_B) && experimental_connections) {
+ for (k = 0; k < your_nstrings; k++)
+ for (l = k+1; l < your_nstrings; l++) {
+ if (string_connect(your_strings[k], your_strings[l], NULL)
+ && !play_connect_n(color, 1, 1, move,
+ your_strings[k], your_strings[l])) {
+ add_cut_move(move, your_strings[k], your_strings[l]);
+ TRACE("...cuts strings %1m, %1m\n",
+ your_strings[k], your_strings[l]);
+ }
+ }
+ }
+
+ /* Pattern class C, try to connect all combinations of our strings. */
+ if ((class & CLASS_C) && experimental_connections) {
+ for (k = 0; k < my_nstrings; k++)
+ for (l = k+1; l < my_nstrings; l++) {
+ if (disconnect(my_strings[k], my_strings[l], NULL)
+ && !play_connect_n(color, 0, 1, move,
+ my_strings[k], my_strings[l])) {
+ add_connection_move(move, my_strings[k], my_strings[l]);
+ TRACE("...connects strings %1m, %1m\n",
+ my_strings[k], my_strings[l]);
+ }
}
}
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.46
diff -u -r1.46 value_moves.c
--- engine/value_moves.c 8 Aug 2002 23:03:03 -0000 1.46
+++ engine/value_moves.c 10 Aug 2002 19:44:16 -0000
@@ -475,34 +475,60 @@
if (!attack_move && !strategically_sound_defense(aa, pos))
continue;
- num_adj = extended_chainlinks(aa, adjs);
+ num_adj = extended_chainlinks(aa, adjs, 1);
for (i = 0; i < num_adj; i++) {
for (j = i+1; j < num_adj; j++) {
int adj1 = adjs[i];
int adj2 = adjs[j];
-
- if (attack_move && !disconnect(adj1, adj2, NULL))
+
+ if (board[adj1] != board[adj2])
+ continue;
+ if (attack_move
+ && board[adj1] != board[aa]
+ && !disconnect(adj1, adj2, NULL))
+ continue;
+ if (!attack_move
+ && board[adj1] != board[aa]
+ && !string_connect(adj1, adj2, NULL))
+ continue;
+ if (attack_move
+ && board[adj1] == board[aa])
continue;
- if (!attack_move && !string_connect(adj1, adj2, NULL))
+ if (!attack_move
+ && board[adj1] == board[aa]
+ && !disconnect(adj1, adj2, NULL))
continue;
if (trymove(pos, color_to_move, "induce_secondary_move_reasons",
aa, EMPTY, NO_MOVE)) {
- if (attack_move && !disconnect(adj1, adj2, NULL)) {
+ if (attack_move
+ && board[adj1] != board[aa]
+ && !disconnect(adj1, adj2, NULL)) {
DEBUG(DEBUG_MOVE_REASONS,
"Connection move at %1m induced for %1m/%1m due to attack
of %1m\n",
pos, adj1, adj2, aa);
add_connection_move(pos, adj1, adj2);
}
- if (!attack_move && !string_connect(adj1, adj2, NULL)) {
+ if (!attack_move
+ && board[adj1] != board[aa]
+ && !string_connect(adj1, adj2, NULL)) {
DEBUG(DEBUG_MOVE_REASONS,
"Cut move at %1m induced for %1m/%1m due to defense of
%1m\n",
pos, adj1, adj2, aa);
add_cut_move(pos, adj1, adj2);
}
+ if (!attack_move
+ && board[adj1] == board[aa]
+ && !disconnect(adj1, adj2, NULL)) {
+ DEBUG(DEBUG_MOVE_REASONS,
+ "Connection move at %1m induced for %1m/%1m due to
defense of %1m\n",
+ pos, adj1, adj2, aa);
+ add_connection_move(pos, adj1, adj2);
+ }
+
popgo();
}
}
@@ -1501,10 +1527,12 @@
/* If the dragon is a single ko stone, the owl code currently
* won't detect that the owl attack is conditional. As a
- * workaround we deduct 0.5 points for the move here.
+ * workaround we deduct 0.5 points for the move here, but only
+ * if the move is a liberty of the string.
*/
if (dragon[aa].size == 1
- && is_ko_point(aa)) {
+ && is_ko_point(aa)
+ && liberty_of_string(pos, aa)) {
TRACE(" %1m: -0.5 - penalty for ko stone %1m (workaround)\n",
pos, aa);
tot_value -= 0.5;
Index: interface/play_ascii.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/play_ascii.c,v
retrieving revision 1.19
diff -u -r1.19 play_ascii.c
--- interface/play_ascii.c 6 Aug 2002 19:04:11 -0000 1.19
+++ interface/play_ascii.c 10 Aug 2002 19:44:17 -0000
@@ -460,7 +460,8 @@
last_move_i = i;
last_move_j = j;
- mprintf("%s(%d): %m\n", color_to_string(gameinfo->to_move), movenum+1, i, j);
+ mprintf("%s(%d): %m\n", color_to_string(gameinfo->to_move),
+ movenum+1, i, j);
if (is_pass(POS(i, j)))
(*passes)++;
else
@@ -910,11 +911,10 @@
if (tmpstring) {
/* discard newline */
tmpstring[strlen(tmpstring)-1] = 0;
- if (!sgftree_readfile(&sgftree, tmpstring))
- {
- fprintf(stderr, "Cannot open or parse '%s'\n", tmpstring);
- break;
- }
+ if (!sgftree_readfile(&sgftree, tmpstring)) {
+ fprintf(stderr, "Cannot open or parse '%s'\n", tmpstring);
+ break;
+ }
sgf_initialized = 0;
gameinfo_play_sgftree(gameinfo, sgftree.root, NULL);
sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap);
Index: patterns/endgame.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/endgame.db,v
retrieving revision 1.35
diff -u -r1.35 endgame.db
--- patterns/endgame.db 4 Jul 2002 19:33:00 -0000 1.35
+++ patterns/endgame.db 10 Aug 2002 19:44:19 -0000
@@ -1393,6 +1393,16 @@
; && proper_eye(b) && oplay_attack(*,A)
+Pattern CE31
+# gf New pattern. (3.3.6)
+
+X.X
+?*?
+?O?
+
+:|,OXe
+
+
######################################################################
#
# Center followup patterns
Index: patterns/mkpat.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/mkpat.c,v
retrieving revision 1.77
diff -u -r1.77 mkpat.c
--- patterns/mkpat.c 6 Aug 2002 19:04:11 -0000 1.77
+++ patterns/mkpat.c 10 Aug 2002 19:44:22 -0000
@@ -1979,10 +1979,10 @@
if (tree_output)
tree_write_patterns(outfile, name);
else
-#endif
fprintf(outfile, "\nvoid\ninit_tree_%s(void)\n{\n"
" /* nothing to do - tree option not compiled */\n"
"}\n\n", name);
+#endif
/* Write out the patterns. */
if (fullboard)
Index: patterns/owl_defendpats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_defendpats.db,v
retrieving revision 1.64
diff -u -r1.64 owl_defendpats.db
--- patterns/owl_defendpats.db 11 Jun 2002 14:12:32 -0000 1.64
+++ patterns/owl_defendpats.db 10 Aug 2002 19:44:28 -0000
@@ -599,11 +599,12 @@
Pattern D207
# tm reduced value (3.1.22) (see nngs:710)
+# gf Modified. (3.3.6)
-O.X second line kosumi
-.*x
-...
----
+?O.X second line kosumi
+o.*x
+o...
+----
:8,-,value(66)
@@ -2219,6 +2220,7 @@
Pattern D625
# gf New pattern. (3.1.14)
+# gf Revised constraint. (3.3.6)
O*o prevent eye stealing capture
XO.
@@ -2227,10 +2229,10 @@
:8,n,value(45)
a*o
-XO.
+XOb
---
-;lib(a)==1
+;lib(a)==1 && !obvious_false_oeye(b)
Pattern D626
@@ -3769,6 +3771,7 @@
Pattern D1006
# gf Added n classification. (3.1.11)
+# gf Revised constraint. (3.3.6)
OXO connect underneath
.*.
@@ -3776,11 +3779,11 @@
:|,n,value(60)
-aXb
+aCb
.*.
---
-;lib(a)>1 && lib(b)>1
+;lib(a)>1 && lib(b)>1 && !attack(C)
Pattern D1006b
@@ -4215,6 +4218,7 @@
Pattern D1122
+# gf Repaired constraint. (3.3.6)
?O? Cut and maybe capture to make eye
X*X
@@ -4226,7 +4230,7 @@
A*B
---
-;oplay_attack(*,A,A) || oplay_attack(*,B,B)
+;oplay_attack(*,A) || oplay_attack(*,B)
Pattern D1123
@@ -6538,6 +6542,18 @@
+----
;lib(A)==1
+
+
+Pattern D1423
+# gf New pattern. (3.3.6)
+
+|OO? throw in to make ko or better
+|.O?
+|XOO
+|*.O
++---
+
+:8,s,value(45)
# END OF FILE
Index: patterns/owl_vital_apats.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/owl_vital_apats.db,v
retrieving revision 1.29
diff -u -r1.29 owl_vital_apats.db
--- patterns/owl_vital_apats.db 3 Jun 2002 15:01:00 -0000 1.29
+++ patterns/owl_vital_apats.db 10 Aug 2002 19:44:29 -0000
@@ -741,11 +741,12 @@
Pattern VA44
# tm New Pattern (3.1.17)
+# gf Fixed symmetry. (3.3.6)
XoX
o*o
-:8,s,value(57)
+:|,s,value(57)
XbX
a*c
Index: patterns/patterns2.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/patterns2.db,v
retrieving revision 1.41
diff -u -r1.41 patterns2.db
--- patterns/patterns2.db 3 Jun 2002 15:01:00 -0000 1.41
+++ patterns/patterns2.db 10 Aug 2002 19:44:32 -0000
@@ -3386,4 +3386,27 @@
:8,-,shape(-10)
+Pattern Temp9
+# gf New pattern. (3.3.6)
+
+|............ don't play halfways between hoshi
+|...O.....O..
+|......*.....
+|............
+|............
++------------
+
+:8,-
+
+|............
+|...O..a..O..
+|......*.....
+|............
+|............
++------------
+
+>antisuji(*);
+>antisuji(a);
+
+
# END OF FILE
- [gnugo-devel] tuning patch,
Gunnar Farneback <=