gnugo-devel
[Top][All Lists]
Advanced

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

[gnugo-devel] tactical reading patch


From: Paul Pogonyshev
Subject: [gnugo-devel] tactical reading patch
Date: Sat, 9 Apr 2005 20:46:39 +0300
User-agent: KMail/1.4.3

- make superstring_break_chain_moves() attack 3-liberty chains

This function has always been called with `liberty_cap' of 4, so it
looked for 3-liberty chains, but then silently discarded them.  Now
it passes such chains to do_find_break_chain3_moves(), which I broke
out of break_chain3_moves() function.  Basically, the only difference
is that do_find_break_chain3_moves() accepts an arbitrary array of
chains, which the caller may fill the way it likes.

I also took the opportunity to rename some variables in
break_chain3_moves() so that their names carry some meaning.

Breakage:

reading:187     PASS 1 E11 [1 E11]
reading:205     PASS 0 [0]
reading:206     PASS 0 [0]

  All three are good and unrelated to each other.

trevor:671      PASS 1 D1 [1 (D1|C3|C1)]

  Good, properly solved.

nngs:900        PASS Q15 [Q15]
global:44       FAIL J7 [D5]
trevord:680     PASS S16 [S16]

  Did not check.

Total: 6 PASS, 1 FAIL


I don't have node counters for 3.7.3, but judging by the regressions
of my recent tuning patches, this one costs almost nothing.  Here are
the counters for CVS + this patch: 1676160258 3155994 13122511.

Paul


--- reading.c   05 Apr 2005 21:04:12 +0300      1.157
+++ reading.c   09 Apr 2005 18:03:52 +0300      
@@ -4402,7 +4402,7 @@ break_chain_moves(int str, struct readin
  */
 static int
 defend_secondary_chain1_moves(int str, struct reading_moves *moves,
-    int min_liberties)
+                             int min_liberties)
 {
   int r, s;
   int color = OTHER_COLOR(board[str]);
@@ -4724,42 +4724,38 @@ break_chain2_defense_moves(int str, stru
 }
 
 
-/*
- * (str) points to a group.
- * If there is a string in the surrounding chain having
- * exactly three liberties whose attack leads to the rescue of
- * (str), break_chain3_moves(str, *moves) adds attack moves against
- * the surrounding string as candidate moves.
+/* Helper function for break_chain3_moves() and
+ * superstring_break_chain_moves().
  */
-
 static void
-break_chain3_moves(int str, struct reading_moves *moves, int be_aggressive)
-{
-  int color = board[str];
-  int other = OTHER_COLOR(color);
+do_find_break_chain3_moves(int *chain_links, int num_chain_links,
+                          struct reading_moves *moves, int be_aggressive,
+                          const char *caller_function_name)
+{
+  int other = board[chain_links[0]];
+  int color = OTHER_COLOR(other);
+  char move_added[BOARDMAX];
+  int possible_moves[MAX_MOVES];
+  int num_possible_moves = 0;
   int r;
   int k;
-  int u = 0, v;
-  int apos;
-  int adj;
-  int adjs[MAXCHAIN];
-  int libs[3];
-  int possible_moves[MAX_MOVES];
-  int mw[BOARDMAX];
 
-  memset(mw, 0, sizeof(mw));
-  
-  adj = chainlinks2(str, adjs, 3);
-  for (r = 0; r < adj; r++) {
-    int lib1 = 0, lib2 = 0, lib3 = 0;
-    apos = adjs[r];
+  gg_assert(num_chain_links > 0);
+
+  memset(move_added, 0, sizeof move_added);
+
+  for (r = 0; r < num_chain_links; r++) {
+    int lib1;
+    int lib2;
+    int lib3;
+    int libs[3];
 
     /* We make a list in the (adjs) array of the liberties
      * of boundary strings having exactly three liberties. We mark
      * each liberty in the mw array so that we do not list any
      * more than once.
      */
-    findlib(apos, 3, libs);
+    findlib(chain_links[r], 3, libs);
 
     /* If the 3 liberty chain easily can run away through one of the
      * liberties, we don't play on any of the other liberties.
@@ -4773,55 +4769,87 @@ break_chain3_moves(int str, struct readi
     if ((lib1 >= 4 || lib2 >= 4) && lib3 >= 4)
       continue;
 
-    if (lib1 >= 4 && !mw[libs[0]]) {
-      mw[libs[0]] = 1;
-      possible_moves[u++] = libs[0];
+    if (lib1 >= 4) {
+      if (!move_added[libs[0]]) {
+       possible_moves[num_possible_moves++] = libs[0];
+       move_added[libs[0]] = 1;
+      }
+
       continue;
     }
     
-    if (lib2 >= 4 && !mw[libs[1]]) {
-      mw[libs[1]] = 1;
-      possible_moves[u++] = libs[1];
+    if (lib2 >= 4) {
+      if (!move_added[libs[1]]) {
+       possible_moves[num_possible_moves++] = libs[1];
+       move_added[libs[1]] = 1;
+      }
+
       continue;
     }
     
-    if (lib3 >= 4 && !mw[libs[2]]) {
-      mw[libs[2]] = 1;
-      possible_moves[u++] = libs[2];
+    if (lib3 >= 4) {
+      if (!move_added[libs[2]]) {
+       possible_moves[num_possible_moves++] = libs[2];
+       move_added[libs[2]] = 1;
+      }
+
       continue;
     }
 
     /* No easy escape, try all liberties. */
     for (k = 0; k < 3; k++) {
-      if (!mw[libs[k]]) {
-       mw[libs[k]] = 1;
-       possible_moves[u++] = libs[k];
+      if (!move_added[libs[k]]) {
+       possible_moves[num_possible_moves++] = libs[k];
+       move_added[libs[k]] = 1;
       }
     }
 
     if (stackp <= backfill2_depth
        || (be_aggressive && stackp <= backfill_depth))
-      defend_secondary_chain1_moves(adjs[r], moves, 3);
+      defend_secondary_chain1_moves(chain_links[r], moves, 3);
   }
 
-  for (v = 0; v < u; v++) {
-    /* We do not wish to consider the move if it can be 
-     * immediately recaptured, unless stackp < backfill2_depth.
-     * Beyond backfill2_depth, the necessary capturing move might not
-     * get generated in follow-up for the attacker.
-     * (This currently only makes a difference at stackp == backfill2_depth.)
+  for (k = 0; k < num_possible_moves; k++) {
+    /* We do not wish to consider the move if it can be immediately
+     * recaptured, unless stackp < backfill2_depth.  Beyond
+     * backfill2_depth, the necessary capturing move might not get
+     * generated in follow-up for the attacker.  (This currently only
+     * makes a difference at stackp == backfill2_depth.)
      */
-    int xpos = possible_moves[v];
+    int move = possible_moves[k];
+
     if (stackp <= break_chain_depth
        || (be_aggressive && stackp <= backfill_depth)
-       || approxlib(xpos, color, 2, NULL) > 1)
+       || approxlib(move, color, 2, NULL) > 1)
       /* We use a negative initial score here as we prefer to find
        * direct defense moves.
        */
-      ADD_CANDIDATE_MOVE(xpos, -2, *moves, "break_chain3");
+      ADD_CANDIDATE_MOVE(move, -2, *moves, caller_function_name);
+  }
+}
+
+
+/*
+ * (str) points to a group.
+ * If there is a string in the surrounding chain having
+ * exactly three liberties whose attack leads to the rescue of
+ * (str), break_chain3_moves(str, *moves) adds attack moves against
+ * the surrounding string as candidate moves.
+ */
+
+static void
+break_chain3_moves(int str, struct reading_moves *moves, int be_aggressive)
+{
+  int chain_links[MAXCHAIN];
+  int num_chain_links = chainlinks2(str, chain_links, 3);
+
+  if (num_chain_links > 0) {
+    do_find_break_chain3_moves(chain_links, num_chain_links,
+                              moves, be_aggressive, "break_chain3");
   }
 }
 
+
 /*
  * (str) points to a group.
  * If there is a string in the surrounding chain having
@@ -4942,6 +4970,8 @@ superstring_break_chain_moves(int str, i
 {
   int adj;
   int adjs[MAXCHAIN];
+  int chain_links3[MAXCHAIN];
+  int num_chain_links3 = 0;
   int k;
   int apos;
 
@@ -4954,6 +4984,13 @@ superstring_break_chain_moves(int str, i
     }
     else if (liberties == 2)
       do_find_break_chain2_efficient_moves(str, adjs[k], moves);
+    else if (liberties == 3)
+      chain_links3[num_chain_links3++] = adjs[k];
+  }
+
+  if (num_chain_links3 > 0) {
+    do_find_break_chain3_moves(chain_links3, num_chain_links3,
+                              moves, 0, "superstring_break_chain-3");
   }
 }
 





reply via email to

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