gnugo-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [gnugo-devel] gnugo 3.4 problems


From: Gunnar Farnebäck
Subject: Re: [gnugo-devel] gnugo 3.4 problems
Date: Sat, 20 Nov 2004 05:20:02 +0100
User-agent: EMH/1.14.1 SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.3 Emacs/21.3 (sparc-sun-solaris2.9) MULE/5.0 (SAKAKI)

Dan wrote:
> I assume by send-two-return-one you mean move 120 in the game
> in question.

Yes.

> This doesn't address the problem at move 118.

That problem has already been solved between 3.4 and 3.6 in the sense
that O15 is now valued lower than the correct semeai moves at S17 and
T17. Unfortunately S19 is valued even higher, but that's the same
problem as in move 120.

> I can give two reasons for not adding an antisuji pattern.
> 
> (1) Might be useful as a ko threat.

Fair enough, although the move in most cases loses points as a ko
threat.

> (2) The send-two-return-one move is a warning of a deeper
> problem which might go unnoiticed if the move is fixed
> by superficial means. Perhaps we would not have seen
> this game if move 118 had been made but not move 120.

Well, we could go a step farther and crash on such moves (development
versions only of course).

> To amplify (2), if the owl or semeai code finds such a move
> and it is silently overruled when shapes finds an antisuji
> move, this is arguably worse than if the move were actually
> played, since there is a concealed bug in the owl or semeai
> reading.

Actually I don't think there's a bug in this case, other than by
design limitations of the ko result codes. Let's see what happens in
this semeai.

Move 94, black T17:
This is a really good move by GNU Go, reducing white to one eye and
starting the semeai. The following four moves are also correct.

Move 104, black N8:
Semeai move is P19, leaving a 3-step ko in black's favor.
The played move at N8 (tenuki) leaves a 2-step ko in black's favor.

Move 108, black L10:
Semeai move is P19, leaving a 2-step ko in black's favor.
The played move at L10 (tenuki) leaves a direct ko where white still
must find the first ko threat.

Move 114, black T15:
Correct move is P19, leaving a direct ko where white must find the
first ko threat. 
The played move at T15 leaves a direct ko where black must find the
first ko threat.
Tenuki leaves a 2-step ko in white's favor.

Move 118, black O15:
Correct moves are Q19, S17, T17, leaving a direct ko where black must
find the first ko threat.
The played move at O15 leaves a 3-step ko in white's favor.
Tenuki leaves a 2-step ko in white's favor.

Move 120, black S19:
Correct moves are S17, T17, leaving a 2-step ko in white's favor.
S19 and tenuki both leave a 3-step ko in white's favor.


Since GNU Go only distinguishes between good ko where the opponent
must find the first ko threat and bad ko where itself must find the
first ko threat, it's only at move 114 where it has a chance to tell
the good moves from the bad moves.

That said the patch below does solve this send-two-return-one problem,
by filtering out the bad move from consideration in
do_find_more_owl_attack_and_defense_moves(), which I consider
perfectly legitimate.

- new function send_two_return_one() in utils.c
- don't consider send-two-return-one moves in
  do_find_more_owl_attack_and_defense_moves() 

/Gunnar

Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.231
diff -u -r1.231 liberty.h
--- engine/liberty.h    13 Nov 2004 04:46:43 -0000      1.231
+++ engine/liberty.h    19 Nov 2004 04:42:58 -0000
@@ -540,6 +540,7 @@
 int does_defend(int move, int str);
 int double_atari(int move, int color, float *value,
                 char safe_stones[BOARDMAX]);
+int send_two_return_one(int move, int color);
 int play_attack_defend_n(int color, int do_attack, int num_moves, ...);
 int play_attack_defend2_n(int color, int do_attack, int num_moves, ...);
 int play_break_through_n(int color, int num_moves, ...);
Index: engine/utils.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/utils.c,v
retrieving revision 1.101
diff -u -r1.101 utils.c
--- engine/utils.c      19 Nov 2004 04:30:09 -0000      1.101
+++ engine/utils.c      19 Nov 2004 04:43:01 -0000
@@ -1393,6 +1393,63 @@
 }
     
 
+/* Returns true if a move by (color) fits a shape like:
+ *
+ *  -----
+ *  O.O*X        (O=color)
+ *  OOXXX
+ *
+ * More specifically the move should have the following properties:
+ * - The move is a self-atari
+ * - The move forms a string of exactly two stones
+ * - When the opponent captures, the capturing stone becomes a single
+ *   stone in atari
+ * - When capturing back the original position is repeated
+ */
+
+int
+send_two_return_one(int move, int color)
+{
+  int other = OTHER_COLOR(color);
+  int lib1;
+  int lib2;
+
+  /* Try to play the move. */
+  if (!trymove(move, color, "send_two_return_one-A", NO_MOVE))
+    return 0;
+
+  /* Does the move leave exactly two stones in atari? */
+  if (findlib(move, 1, &lib1) > 1 || countstones(move) != 2) {
+    popgo();
+    return 0;
+  }
+
+  /* Let the opponent capture. This move is guaranteed to be legal. */
+  trymove(lib1, other, "send_two_return_one-A", NO_MOVE);
+
+  /* Is the capturing string single and in atari? */
+  if (findlib(lib1, 1, &lib2) > 1 || countstones(lib1) > 1) {
+    popgo();
+    popgo();
+    return 0;
+  }
+
+  popgo();
+  popgo();
+
+  /* The move to capture back is in lib2. This must be one of the two
+   * captured stones, either the move or the adjacent stone. If it is
+   * the same as the first move, the previous position is not repeated
+   * by capturing back, so we return false.
+   */
+  if (lib2 == move)
+    return 0;
+
+  /* The move matches the shape. */
+  return 1;
+}
+
+
 /* Score the game and determine the winner */
 
 void
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.135
diff -u -r1.135 value_moves.c
--- engine/value_moves.c        13 Nov 2004 04:46:45 -0000      1.135
+++ engine/value_moves.c        19 Nov 2004 04:43:02 -0000
@@ -287,6 +287,10 @@
   int dd2 = NO_MOVE;
   int save_verbose;
 
+  /* Never consider moves of the send-two-return-one type here. */
+  if (send_two_return_one(pos, color))
+    return;
+
   save_verbose = verbose;
   if (verbose > 0)
     verbose --;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]