[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [gnugo-devel] atari_atari & kikashi problems
From: |
Gunnar Farneback |
Subject: |
Re: [gnugo-devel] atari_atari & kikashi problems |
Date: |
Thu, 03 Jan 2002 19:27:36 +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) |
Trevor wrote:
> This is a serious weakness that may be simple to fix. Pointless (or
> worse) kikashi before saving string:
> trevord:280
> trevord:760
> trevorc:1300
> trevorc:1100
> trevorc:480
> trevorc:540
> trevorc:640
> trevorc:760
> Normally GNU Go doesn't make pointless kikashi (i.e. moves with
> a followup, but no other value). However, if the followup threatens
> to save a string by capturing a surrounding string, then the kikashi
> gets overvalued - more than saving the group directly.
Many of these can be attributed to improper followup values and are
solved by the patch below. Suppose that a move at '*' is a threat
against a string 'a'. What the patch essentially does is to check
whether the defense of 'a' in turn is a threat against '*', assuming
that implies that '*' probably ends in gote and shouldn't have a
followup value.
/Gunnar
Index: engine/move_reasons.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.c,v
retrieving revision 1.55
diff -u -r1.55 move_reasons.c
--- engine/move_reasons.c 21 Dec 2001 07:51:38 -0000 1.55
+++ engine/move_reasons.c 3 Jan 2002 17:12:32 -0000
@@ -2732,6 +2732,9 @@
* attacking that worm. We make at most one adjustment
* of each type.
*
+ * No followup value is awarded if the defense move is a threat
+ * back on our move because we're likely to end in gote then.
+ *
* FIXME: It might be possible that parts of the dragon
* can be cut in the process of capturing the (aa)
* worm. In that case, not the entire size of the
@@ -2747,14 +2750,15 @@
* a structured manner.
*/
- if (trymove(pos, color, "estimate_territorial_value",
- NO_MOVE, EMPTY, NO_MOVE)) {
+ if (trymove(pos, color, "estimate_territorial_value-A",
+ NO_MOVE, EMPTY, NO_MOVE)) {
int adjs[MAXCHAIN];
float adjusted_value = 2 * worm[aa].effective_size;
float adjustment_up = 0.0;
float adjustment_down = 0.0;
int s;
int num_adj;
+ int defense_move;
/* In rare cases it may happen that the trymove() above
* actually removed the string at aa.
@@ -2764,6 +2768,27 @@
else
num_adj = chainlinks(aa, adjs);
+ /* No followup value if string can be defended with threat
+ * against our move.
+ *
+ * FIXME: This is somewhat halfhearted since only one defense
+ * move is tested.
+ */
+ if (board[aa] != EMPTY
+ && find_defense(aa, &defense_move) != 0
+ && defense_move != NO_MOVE) {
+ if (trymove(defense_move, OTHER_COLOR(color),
+ "estimate_territorial_value-b", NO_MOVE,
+ EMPTY, NO_MOVE)) {
+ if (board[pos] == EMPTY || attack(pos, NULL) != 0) {
+ popgo();
+ popgo();
+ break;
+ }
+ popgo();
+ }
+ }
+
for (s = 0; s < num_adj; s++) {
int adj = adjs[s];
@@ -3038,7 +3063,7 @@
*/
this_value = 0.0;
- if (move[pos].move_safety == 1)
+ if (move[pos].move_safety == 1 && safe_move(pos, color) == WIN)
saved_stones[pos] = INFLUENCE_SAVED_STONE;
else
saved_stones[pos] = INFLUENCE_CAPTURED_STONE;
Index: patterns/helpers.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/helpers.c,v
retrieving revision 1.20
diff -u -r1.20 helpers.c
--- patterns/helpers.c 15 Dec 2001 14:35:27 -0000 1.20
+++ patterns/helpers.c 3 Jan 2002 17:12:37 -0000
@@ -426,12 +426,23 @@
* XXXXO.
*
* where X can get out of atari with profit by capturing three O stones.
+ *
+ * Another case where we don't award the followup value is when the
+ * opponent can defend with a threat against our move, e.g. in this
+ * position:
+ *
+ * .OOOXX.
+ * .OXXO.X
+ * ..*.X..
+ * ..XX...
+ *
*/
void
threaten_to_capture_helper(int move, int str)
{
int adj, adjs[MAXCHAIN];
+ int defense_move;
int k;
adj = chainlinks2(str, adjs, 1);
@@ -439,8 +450,23 @@
if (worm[adjs[k]].defend_codes[0] != 0
&& !does_defend(move, adjs[k]))
return;
-
+
+ if (!TRYMOVE(move, OTHER_COLOR(board[str])))
+ return;
+ if (find_defense(str, &defense_move) != 0
+ && defense_move != NO_MOVE
+ && TRYMOVE(defense_move, board[str])) {
+ if (board[move] == EMPTY || attack(move, NULL) != 0) {
+ popgo();
+ popgo();
+ return;
+ }
+ popgo();
+ }
+ popgo();
+
add_followup_value(move, 2.0 * worm[str].effective_size);
+ TRACE("...followup value %f\n", 2.0 * worm[str].effective_size);
}