gnugo-devel
[Top][All Lists]
Advanced

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

Re: [gnugo-devel] reading patch


From: Gunnar Farneback
Subject: Re: [gnugo-devel] reading patch
Date: Mon, 07 Oct 2002 22:08:12 +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)

I wrote:
> Most notably reading:140 doesn't pass with this variant. It occurs to
> me that we should probably use the same type of moves that are
> generated by break_chain2_efficient_moves(), and in fact the same
> code. This would most likely solve reading:140 but possibly cause
> fewer failures in the rest of the test suite.

Implemented in the appended patch, which obviously conflicts with
Paul's patch. The regression delta is five PASSes.

reading:37      PASS
reading:140     PASS
reading:170     PASS
owl:237         PASS
nngs2:70        PASS

- new static function do_find_break_chain2_efficient_moves() split off
  from break_chain2_efficient_moves()
- superstring_breakchain() revised

/Gunnar

Index: engine/reading.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/reading.c,v
retrieving revision 1.78
diff -u -r1.78 reading.c
--- engine/reading.c    28 Sep 2002 14:15:26 -0000      1.78
+++ engine/reading.c    7 Oct 2002 19:56:41 -0000
@@ -176,6 +176,8 @@
 static void break_chain_moves(int str, struct reading_moves *moves);
 static void break_chain2_efficient_moves(int str, 
                                         struct reading_moves *moves);
+static void do_find_break_chain2_efficient_moves(int str, int adj,
+                                                struct reading_moves *moves);
 static void break_chain2_moves(int str, struct reading_moves *moves,
                               int require_safe);
 static void break_chain2_defense_moves(int str, struct reading_moves *moves);
@@ -4391,81 +4393,91 @@
 static void
 break_chain2_efficient_moves(int str, struct reading_moves *moves)
 {
+  int r;
+  int adj, adjs[MAXCHAIN];
+  
+  /* Find links with 2 liberties. */
+  adj = chainlinks2(str, adjs, 2);
+  
+  for (r = 0; r < adj; r++)
+    do_find_break_chain2_efficient_moves(str, adjs[r], moves);
+}
+
+
+/* Helper function for break_chain2_efficient_moves(). */
+static void
+do_find_break_chain2_efficient_moves(int str, int adj,
+                                    struct reading_moves *moves)
+{
   int color = board[str];
   int other = OTHER_COLOR(color);
-  int r;
   int k;
-  int adj, adjs[MAXCHAIN];
   int adj2, adjs2[MAXCHAIN];
   int libs[2];
   int ai, aj;
   int bi, bj;
   int ci, cj;
+  ASSERT1(countlib(adj) == 2, adj);
   
-  /* Find links with 2 liberties. */
-  adj = chainlinks2(str, adjs, 2);
+  adj2 = chainlinks2(adj, adjs2, 1);
+  if (adj2 == 1 && countlib(str) > 2) {
+    int apos;
+    findlib(adjs2[0], 1, &apos);
+    if (!is_self_atari(apos, color))
+      ADD_CANDIDATE_MOVE(apos, 0, *moves);
+    return;
+  }
   
-  for (r = 0; r < adj; r++) {
-    adj2 = chainlinks2(adjs[r], adjs2, 1);
-    if (adj2 == 1 && countlib(str) > 2) {
-      int apos;
-      findlib(adjs2[0], 1, &apos);
-      if (!is_self_atari(apos, color))
-       ADD_CANDIDATE_MOVE(apos, 0, *moves);
-      continue;
-    }
-    
-    if (adj2 > 1)
-      continue;
+  if (adj2 > 1)
+    return;
     
-    findlib(adjs[r], 2, libs);
-    for (k = 0; k < 2; k++)
-      if (approxlib(libs[k], other, 3, NULL) <= 2
-         && !is_self_atari(libs[1 - k], color))
-       ADD_CANDIDATE_MOVE(libs[1 - k], 0, *moves);
-    
-    /* A common special case is this kind of edge position
-     * 
-     * ..XXX.
-     * X.XOO.
-     * XOOX*.
-     * ......
-     * ------
-     *
-     * where a move at * is most effective for saving the two stones
-     * to the left.
-     *
-     * The code below tries to identify this case. We use the crude
-     * heuristic that the two liberties of the X stone we want to
-     * capture should be placed diagonally and that one liberty should
-     * be on the edge. Then we propose to play the other liberty.
-     * Notice that both moves may be proposed when attacking a stone
-     * on 2-2.
-     *
-     * Update: This was too crude. Also require that the X stone is on
-     * the second line and that the proposed move is not a self-atari.
-     */
-    ai = I(libs[0]);
-    aj = J(libs[0]);
-    bi = I(libs[1]);
-    bj = J(libs[1]);
-    ci = I(adjs[r]);
-    cj = J(adjs[r]);
-    if (gg_abs(ai - bi) == 1
-       && gg_abs(aj - bj) == 1
-       && (ci == 1 || ci == board_size - 2
-           || cj == 1 || cj == board_size - 2)) {
-
-      if ((ai == 0 || ai == board_size - 1
-          || aj == 0 || aj == board_size - 1)
-         && !is_self_atari(libs[1], board[str]))
-       ADD_CANDIDATE_MOVE(libs[1], 0, *moves);
-
-      if ((bi == 0 || bi == board_size - 1
-          || bj == 0 || bj == board_size - 1)
-         && !is_self_atari(libs[0], board[str]))
-       ADD_CANDIDATE_MOVE(libs[0], 0, *moves);
-    }
+  findlib(adj, 2, libs);
+  for (k = 0; k < 2; k++)
+    if (approxlib(libs[k], other, 3, NULL) <= 2
+       && !is_self_atari(libs[1 - k], color))
+      ADD_CANDIDATE_MOVE(libs[1 - k], 0, *moves);
+  
+  /* A common special case is this kind of edge position
+   * 
+   * ..XXX.
+   * X.XOO.
+   * XOOX*.
+   * ......
+   * ------
+   *
+   * where a move at * is most effective for saving the two stones
+   * to the left.
+   *
+   * The code below tries to identify this case. We use the crude
+   * heuristic that the two liberties of the X stone we want to
+   * capture should be placed diagonally and that one liberty should
+   * be on the edge. Then we propose to play the other liberty.
+   * Notice that both moves may be proposed when attacking a stone
+   * on 2-2.
+   *
+   * Update: This was too crude. Also require that the X stone is on
+   * the second line and that the proposed move is not a self-atari.
+   */
+  ai = I(libs[0]);
+  aj = J(libs[0]);
+  bi = I(libs[1]);
+  bj = J(libs[1]);
+  ci = I(adj);
+  cj = J(adj);
+  if (gg_abs(ai - bi) == 1
+      && gg_abs(aj - bj) == 1
+      && (ci == 1 || ci == board_size - 2
+         || cj == 1 || cj == board_size - 2)) {
+    
+    if ((ai == 0 || ai == board_size - 1
+        || aj == 0 || aj == board_size - 1)
+       && !is_self_atari(libs[1], board[str]))
+      ADD_CANDIDATE_MOVE(libs[1], 0, *moves);
+    
+    if ((bi == 0 || bi == board_size - 1
+        || bj == 0 || bj == board_size - 1)
+       && !is_self_atari(libs[0], board[str]))
+      ADD_CANDIDATE_MOVE(libs[0], 0, *moves);
   }
 }
 
@@ -4701,20 +4713,32 @@
   int adjs[MAXCHAIN];
   int k;
   int apos;
+  struct reading_moves moves;
   int savemove = 0;
   int savecode = 0;
 
   SETUP_TRACE_INFO("superstring_breakchain", str);
 
+  moves.num = 0;
+
   proper_superstring_chainlinks(str, &adj, adjs, liberty_cap);
   for (k = 0; k < adj; k++) {
+    int liberties = countlib(adjs[k]);
+    if (liberties == 1) {
+      findlib(adjs[k], 1, &apos);
+      ADD_CANDIDATE_MOVE(apos, 0, moves);
+    }
+    else if (liberties == 2)
+      do_find_break_chain2_efficient_moves(str, adjs[k], &moves);
+  }
+  
+  order_moves(str, &moves, color, read_function_name, 0);
+
+  for (k = 0; k < moves.num; k++) {
     int new_komaster, new_kom_pos;
     int ko_move;
 
-    if (countlib(adjs[k]) > 1)
-      continue;
-    findlib(adjs[k], 1, &apos);
-
+    apos = moves.pos[k];
     if (komaster_trymove(apos, color, "superstring_break_chain", str,
                         komaster, kom_pos, &new_komaster, &new_kom_pos,
                         &ko_move, savecode == 0 && stackp <= ko_depth)) {




reply via email to

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