gnugo-devel
[Top][All Lists]
Advanced

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

[gnugo-devel] tactics code cleanup


From: Evan Berggren Daniel
Subject: [gnugo-devel] tactics code cleanup
Date: Fri, 29 Nov 2002 23:30:13 -0500 (EST)

This patch converts the remaining tactics functions to the candidate move
mechanism (eg int find_cap(int str, int *move) -> void
find_cap_moves(int str, struct reading_moves *moves)).

This actually has a moderate number of regression changes (10 so far).  I
have yet to investigate all of them, but they seem to be a result of
moving from the simplified trymove() code in the original functions to the
more complex code in the attackn() and defendn() functions.  For example,
optics:1201 now passes again.  This is because no tactical attack on the
t13 string is found.  After w makes a dead eyespace, b plays atari above,
and the passes, forcing w to fill liberties inside.  However, black picks
up the four w stones, gaining four internal liberties at stackp == 10, and
is counted alive tactically.  Previously, the findcap() function required
a defense by black, which inevitably shortened a liberty.  I believe the
change as a result of the cleanup is an improvement.

The performance differnce as a result of the patch is a slight slowdown
(reading nodes in reading.tst 97293 -> 98746).  However, this seems to be
a result of poor ordering.  My patch removes some overlap between the
different functions, but also removes the ordering of the function calls.
Tuning of the move ordering should solve this.

I plan to redo the move ordering patch I sent in earlier on a larger test
suite, so that should fix the performance problem.

Thanks

Evan Daniel


The delta so far (as of nngs.tst):

./regress.sh . reading.tst
173 unexpected PASS!
./regress.sh . ld_owl.tst
188 unexpected FAIL: Correct '2 Q19', got '0'
302 unexpected FAIL: Correct 'critical T19 (Q19|R18)', got 'alive'
./regress.sh . optics.tst
1201 unexpected PASS!
./regress.sh . connection.tst
26 unexpected FAIL: Correct '1 B4', got '0'
27 unexpected FAIL: Correct '1 B4', got '0'
./regress.sh . trevora.tst
390 unexpected FAIL: Correct 'A2', got 'J4'
./regress.sh . arb.tst
150 unexpected PASS!
./regress.sh . lazarus.tst
6 unexpected PASS!
./regress.sh . trevorb.tst
160 unexpected PASS!


And the patch:

Index: engine/reading.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/reading.c,v
retrieving revision 1.86
diff -u -r1.86 reading.c
--- engine/reading.c    27 Nov 2002 16:32:08 -0000      1.86
+++ engine/reading.c    30 Nov 2002 04:05:07 -0000
@@ -144,8 +144,8 @@
                                 struct reading_moves *moves);
 static void special_rescue2_moves(int str, int libs[2],
                                  struct reading_moves *moves);
-static int special_rescue3(int str, int libs[3], int *move,
-                          int komaster, int kom_pos);
+static void special_rescue3_moves(int str, int libs[3],
+                                 struct reading_moves *moves);
 static void hane_rescue_moves(int str, int libs[4],
                              struct reading_moves *moves);
 static void special_rescue5_moves(int str, int libs[3],
@@ -158,17 +158,16 @@
 static int attack2(int str, int *move, int komaster, int kom_pos);
 static int attack3(int str, int *move, int komaster, int kom_pos);
 static int attack4(int str, int *move, int komaster, int kom_pos);
-static int find_cap2(int str, int alib, int blib, int *move,
-                    int komaster, int kom_pos);
-static int find_cap(int str, int *move, int komaster, int kom_pos);
-static int special_attack2(int str, int libs[2], int *move,
-                          int komaster, int kom_pos);
-static int special_attack3(int str, int libs[2], int *move,
-                          int komaster, int kom_pos);
-static int special_attack4(int str, int libs[2], int *move,
-                          int komaster, int kom_pos);
-static int draw_back(int str, int *move, int komaster, int kom_pos);
-static int edge_closing_backfill(int str, int apos, int *move);
+static void find_cap_moves(int str, struct reading_moves *moves);
+static void special_attack2_moves(int str, int libs[2],
+                                struct reading_moves *moves);
+static void special_attack3_moves(int str, int libs[2],
+                                struct reading_moves *moves);
+static void special_attack4_moves(int str, int libs[2],
+                                struct reading_moves *moves);
+static void draw_back_moves(int str, struct reading_moves *moves);
+static void edge_closing_backfill_moves(int str, int apos,
+                                       struct reading_moves *moves);
 static void edge_block_moves(int str, int apos,
                             struct reading_moves *moves);
 static void propose_edge_moves(int str, int *libs, int liberties,
@@ -181,10 +180,9 @@
 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);
-static int break_chain3(int str, int *move, int komaster, int kom_pos);
-static int superstring_breakchain(int str, int *move,
-                                 int komaster, int kom_pos,
-                                 int liberty_cap);
+static void break_chain3_moves(int str, struct reading_moves *moves);
+static void superstring_breakchain_moves(int str, int liberty_cap,
+                                        struct reading_moves *moves);
 static void double_atari_chain2_moves(int str,
                                      struct reading_moves *moves);
 static void order_moves(int str, struct reading_moves *moves,
@@ -1349,17 +1347,15 @@
     }
   }

+  saved_num_moves = moves.num;
+
   if (stackp <= superstring_depth) {
-    int dcode = superstring_breakchain(str, &xpos, komaster, kom_pos, 4);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, dcode, xpos, move,
-                           "superstring_breakchain");
+    superstring_breakchain_moves(str, 4, &moves);
   }

-
   /* If nothing else works, we try playing a liberty of the
    * super_string.
    */
-  saved_num_moves = moves.num;
   if (stackp <= superstring_depth) {
     int ss_liberties;
     int ss_libs[MAX_LIBERTIES + 4];
@@ -1393,6 +1389,10 @@
   if (stackp <= backfill_depth) {
     special_rescue5_moves(str, libs, &moves);
   }
+
+  if (stackp <= backfill2_depth) {
+    break_chain3_moves(str, &moves);
+  }

   /* Only order and test the new set of moves. */
   order_moves(str, &moves, other, read_function_name, saved_num_moves);
@@ -1422,17 +1422,6 @@
     }
   }

-  /* We place the more speculative moves trying to break chain links
-   * with 2 or 3 liberties last, because these moves often are not
-   * really relevant.
-   */
-
-  if (stackp <= backfill2_depth) {
-    int bc = break_chain3(str, &xpos, komaster, kom_pos);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, bc, xpos, move,
-                           "break chain3");
-  }
-
   if (savecode != 0)
     RETURN_RESULT(savecode, savemove, move, "saved move");

@@ -1587,28 +1576,25 @@

   /* If nothing else works, try to defend with second order liberties. */

-  if (stackp <= backfill_depth) {
-    int dcode = special_rescue3(str, libs, &xpos, komaster, kom_pos);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, dcode, xpos, move,
-                           "special rescue3");
-  }
-
+  saved_num_moves = moves.num;
+
   if (level >= 10 && stackp <= backfill2_depth) {
-    int dcode = superstring_breakchain(str, &xpos, komaster, kom_pos, 4);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, dcode, xpos, move,
-                           "superstring_breakchain");
+    superstring_breakchain_moves(str, 4, &moves);
+  }
+
+  if (stackp <= backfill_depth) {
+         special_rescue3_moves(str, libs, &moves);
   }
-
-
-  saved_num_moves = moves.num;

   if (stackp <= depth) {
     for (k = 0; k < liberties; k++)
       special_rescue_moves(str, libs[k], &moves);
   }

-  if (stackp <= backfill2_depth)
+  if (stackp <= backfill2_depth) {
     break_chain2_defense_moves(str, &moves);
+    break_chain3_moves(str, &moves);
+  }

   /* If nothing else works, we try playing a liberty of the
    * super_string.
@@ -1674,17 +1660,6 @@
     }
   }

-  /* We place the more speculative moves trying to break chain links
-   * with 2 or 3 liberties last, because these moves often are not
-   * really relevant.
-   */
-
-  if (stackp <= backfill2_depth) {
-    int bc = break_chain3(str, &xpos, komaster, kom_pos);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, bc, xpos, move,
-                           "break chain3");
-  }
-
   if (savecode != 0)
     RETURN_RESULT(savecode, savemove, move, "saved move");

@@ -1891,14 +1866,12 @@
  *   .*.   afg
  *   ---   b--
  */
-static int
-special_rescue3(int str, int libs[3], int *move, int komaster, int kom_pos)
+static void
+special_rescue3_moves(int str, int libs[3], struct reading_moves *moves)
 {
   int color = board[str];
   int other = OTHER_COLOR(color);
   int apos, bpos, cpos, dpos, epos, fpos, gpos;
-  int savemove = 0;
-  int savecode = 0;
   int k, l, r;

   ASSERT1(countlib(str) == 3, str);
@@ -1948,26 +1921,10 @@
          continue;

        /* Try to play at (fpos). */
-       if (trymove(fpos, color, "special_rescue3", str, komaster, kom_pos)) {
-         int acode = do_attack(str, NULL, komaster, kom_pos);
-         if (acode != WIN) {
-           if (acode == 0) {
-             popgo();
-             *move = fpos;
-             return WIN;
-           }
-           UPDATE_SAVED_KO_RESULT(savecode, savemove, acode, fpos);
-         }
-         popgo();
-       }
+       ADD_CANDIDATE_MOVE(fpos, 0, *moves);
       }
     }
   }
-
-  if (savecode != 0)
-    *move = savemove;
-
-  return savecode;
 }


@@ -3083,7 +3040,6 @@
   int adj, adjs[MAXCHAIN];
   int savemove = 0;
   int savecode = 0;
-  int acode;
   int dcode;
   int k;
   int atari_possible = 0;
@@ -3189,7 +3145,15 @@
       break_chain_moves(apos, &moves);
   }

+  if (stackp <= backfill_depth) {
+    special_attack2_moves(str, libs, &moves);
+    special_attack3_moves(str, libs, &moves);
+    special_attack4_moves(str, libs, &moves);
+  }
+
+
   propose_edge_moves(str, libs, liberties, &moves, other);
+  find_cap_moves(str, &moves);
   order_moves(str, &moves, other, read_function_name, 0);

   for (k = 0; k < moves.num; k++) {
@@ -3223,28 +3187,6 @@
     }
   }

-  /* The simple ataris didn't work. Try something more fancy. */
-  acode = find_cap2(str, libs[0], libs[1], &xpos, komaster, kom_pos);
-  CHECK_RESULT_UNREVERSED(savecode, savemove, acode, xpos, move, "find cap2");
-
-  if (stackp <= backfill_depth) {
-    acode = special_attack2(str, libs, &xpos, komaster, kom_pos);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, acode, xpos, move,
-                           "special attack2");
-  }
-
-  if (stackp <= backfill_depth) {
-    acode = special_attack3(str, libs, &xpos, komaster, kom_pos);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, acode, xpos, move,
-                           "special attack3");
-  }
-
-  if (stackp <= backfill_depth) {
-    acode = special_attack4(str, libs, &xpos, komaster, kom_pos);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, acode, xpos, move,
-                           "special attack4");
-  }
-
   /* If it is not possible to make a direct atari, we try filling
    * a liberty of the superstring.
    */
@@ -3385,8 +3327,7 @@
        || !is_self_atari(apos, other))
       ADD_CANDIDATE_MOVE(apos, 0, moves);

-    if (edge_closing_backfill(str, apos, &xpos))
-      ADD_CANDIDATE_MOVE(xpos, 0, moves);
+    edge_closing_backfill_moves(str, apos, &moves);

 #if 0
     /* Try backfilling if atari is impossible. */
@@ -3402,6 +3343,16 @@

   /* Pick up some edge moves. */
   propose_edge_moves(str, libs, liberties, &moves, other);
+
+  /* The simple ataris didn't work. Try something more fancy. */
+  if (stackp <= backfill_depth) {
+    find_cap_moves(str, &moves);
+  }
+
+  if (stackp <= fourlib_depth) {
+    draw_back_moves(str, &moves);
+  }
+
   order_moves(str, &moves, other, read_function_name, 0);

   /* Try the moves collected so far. */
@@ -3437,19 +3388,6 @@
     }
   }

-  /* The simple ataris didn't work. Try something more fancy. */
-  if (stackp <= backfill_depth) {
-    int acode = find_cap(str, &xpos, komaster, kom_pos);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, acode, xpos, move,
-                           "find cap3");
-  }
-
-  if (stackp <= fourlib_depth) {
-    int acode = draw_back(str, &xpos, komaster, kom_pos);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, acode, xpos, move,
-                           "draw back");
-  }
-
   /* Try to defend chain links with two liberties. */
   if (stackp <= backfill2_depth) {
     int saved_num_moves = moves.num;
@@ -3623,8 +3561,7 @@
        || !is_self_atari(apos, other))
       ADD_CANDIDATE_MOVE(apos, 0, moves);

-    if (edge_closing_backfill(str, apos, &xpos))
-      ADD_CANDIDATE_MOVE(xpos, 10, moves);
+    edge_closing_backfill_moves(str, apos, &moves);

     /* Look for edge blocking moves. */
     edge_block_moves(str, apos, &moves);
@@ -3632,6 +3569,11 @@

   /* Pick up some edge moves. */
   propose_edge_moves(str, libs, liberties, &moves, other);
+
+  if (stackp <= backfill_depth) {
+    find_cap_moves(str, &moves);
+  }
+
   order_moves(str, &moves, other, read_function_name, 0);

   /* Try the moves collected so far. */
@@ -3668,94 +3610,19 @@
     }
   }

-  if (stackp <= backfill_depth) {
-    int acode = find_cap(str, &xpos, komaster, kom_pos);
-    CHECK_RESULT_UNREVERSED(savecode, savemove, acode, xpos, move,
-                           "find cap");
-  }
-
   RETURN_RESULT(savecode, savemove, move, "saved move");
 }


-/* find_cap2(str, alib, blib, &i, &j, komaster)
- * looks for a configuration of the following type:
- *
- *  X.
- *  .*
- *
- * where X is an element of the string in question. It tries the
- * move at * and returns true this move captures the string, leaving
- * (i, j) pointing to *.
- */
-
-static int
-find_cap2(int str, int alib, int blib, int *move, int komaster, int kom_pos)
-{
-  int ai, aj;
-  int bi, bj;
-
-  /* Check if the two liberties are located like the figure above. */
-  if (alib != SW(blib)
-      && alib != NW(blib)
-      && alib != NE(blib)
-      && alib != SE(blib))
-    return 0;
-
-  ai = I(alib);
-  aj = J(alib);
-  bi = I(blib);
-  bj = J(blib);
-  /* Which of the two corner points should we use? One of them is
-   * always occupied by the string at (str), the other one is either
-   * free or occupied by something else.
-   */
-  if (BOARD(bi, aj) == EMPTY)
-    *move = POS(bi, aj);
-  else if (BOARD(ai, bj) == EMPTY)
-    *move = POS(ai, bj);
-  else
-    return 0;
-
-  /* Ok, we found the spot. Now see if the move works. */
-  RTRACE("trying to capture %1m with capping move at %1m\n", str, *move);
-  if (trymove(*move, OTHER_COLOR(board[str]), "find_cap2", str,
-             komaster, kom_pos)) {
-    int dcode = do_find_defense(str, NULL, komaster, kom_pos);
-    popgo();
-    switch (dcode) {
-    case 0:
-      RTRACE("cap2 succeeded!\n");
-      return WIN;
-      break;
-    case WIN:
-      RTRACE("cap2 failed!\n");
-      return 0;
-      break;
-    case KO_B:
-      RTRACE("cap2 succeeded with ko return code KO_B\n");
-      return KO_B;
-      break;
-    case KO_A:
-      RTRACE("cap2 succeeded with ko return code KO_A\n");
-      return KO_A;
-      break;
-    }
-  }
-
-  return 0;
-}
-
-
-/* If (str) points to a string with 2 - 4 liberties, find_cap(str, &move)
+/* If (str) points to a string with 2 - 4 liberties,
+ * find_cap_moves(str, &moves)
  * looks for a configuration of the following type:
  *
  *  Xa
  *  b*
  *
  * where X are elements of the string in question and a and b are
- * two of its liberties. It tries the move at * and returns true
- * this move captures the string, leaving (*move) pointing to *.
+ * two of its liberties.
  *
  * For larger strings, this can find moves like
  *
@@ -3768,39 +3635,46 @@
  * even though they are not capping moves.
  */

-static int
-find_cap(int str, int *move, int komaster, int kom_pos)
+static void
+find_cap_moves(int str, struct reading_moves *moves)
 {
   int alib, blib;
   int numlibs;
   int libs[4];
-  int xpos = 0;
   int i,j;
-  int savemove = 0;
-  int savecode = 0;
-  int acode;
+  int ai, aj;
+  int bi, bj;

   numlibs = findlib(str, 4, libs);
   if (numlibs > 4 || numlibs < 2)
-    return 0;
+    return;

-  for (i = 0; i < numlibs - 1; i++)
+  for (i = 0; i < numlibs - 1; i++) {
     for (j = i + 1; j < numlibs; j++) {
       alib = libs[i];
       blib = libs[j];

-      acode = find_cap2(str, alib, blib, &xpos, komaster, kom_pos);
-      if (acode == WIN) {
-        *move = xpos;
-        return WIN;
-      }
-      UPDATE_SAVED_KO_RESULT_UNREVERSED(savecode, savemove, acode, xpos);
+      /* Check if the two liberties are located like the figure above. */
+      if (alib != SW(blib)
+          && alib != NW(blib)
+          && alib != NE(blib)
+          && alib != SE(blib))
+        continue;
+
+      ai = I(alib);
+      aj = J(alib);
+      bi = I(blib);
+      bj = J(blib);
+      /* Which of the two corner points should we use? One of them is
+       * always occupied by the string at (str), the other one is either
+       * free or occupied by something else.
+       */
+      if (BOARD(bi, aj) == EMPTY)
+        ADD_CANDIDATE_MOVE(POS(bi, aj), 10, *moves);
+      else if (BOARD(ai, bj) == EMPTY)
+        ADD_CANDIDATE_MOVE(POS(ai, bj), 10, *moves);
     }
-
-  if (savecode != 0)
-    *move = savemove;
-
-  return savecode;
+  }
 }


@@ -3818,15 +3692,13 @@
  * fairly similar to this situation.
  */

-static int
-special_attack2(int str, int libs[2], int *move, int komaster, int kom_pos)
+static void
+special_attack2_moves(int str, int libs[2], struct reading_moves *moves)
 {
   int color = board[str];
   int other = OTHER_COLOR(color);
   int newlibs[3];
   int xpos;
-  int savemove = 0;
-  int savecode = 0;
   int k;

   for (k = 0; k < 2; k++) {
@@ -3837,26 +3709,11 @@
       else
        xpos = newlibs[1];

-      if (!is_self_atari(xpos, other)
-         && trymove(xpos, other, "special_attack2", str, komaster, kom_pos)) {
-       int dcode = do_find_defense(str, NULL, komaster, kom_pos);
-       if (dcode != WIN && do_attack(str, NULL, komaster, kom_pos)) {
-         if (dcode == 0) {
-           popgo();
-           *move = xpos;
-           return WIN;
-         }
-         UPDATE_SAVED_KO_RESULT(savecode, savemove, dcode, xpos);
-       }
-       popgo();
+      if (!is_self_atari(xpos, other)) {
+       ADD_CANDIDATE_MOVE(xpos, 0, *moves);
       }
     }
   }
-
-  if (savecode != 0)
-    *move = savemove;
-
-  return savecode;
 }


@@ -3872,18 +3729,12 @@
  * the code that follows can find the attacking move at c.
  */

-static int
-special_attack3(int str, int libs[2], int *move, int komaster, int kom_pos)
+static void
+special_attack3_moves(int str, int libs[2], struct reading_moves *moves)
 {
   int color = board[str];
   int other = OTHER_COLOR(color);
-  int acode;
-  int dcode;
-  int savemove = 0;
-  int savecode = 0;
-  int newlibs[2];
   int xpos;
-  int ypos;
   int apos;
   int bpos;
   int k;
@@ -3911,49 +3762,11 @@
        continue;
     }
     else
-      return 0; /* Incorrect configuration, give up. */
+      return; /* Incorrect configuration, give up. */

-    if (is_self_atari(xpos, other)
-       || !trymove(xpos, other, "special_attack3-A", str, komaster, kom_pos))
-      continue;
-
-    if (countlib(xpos) == 2) {
-      findlib(xpos, 2, newlibs);
-      if (newlibs[0] == apos)
-       ypos = newlibs[1];
-      else
-       ypos = newlibs[0];
-
-      if (!is_self_atari(ypos, color)
-         && trymove(ypos, color, "special_attack3-B", str,
-                    komaster, kom_pos)) {
-       acode = do_attack(str, NULL, komaster, kom_pos);
-       if (acode == 0) {
-         popgo();
-         popgo();
-         continue;
-       }
-       UPDATE_SAVED_KO_RESULT_UNREVERSED(savecode, savemove, acode, xpos);
-       popgo();
-      }
-    }
-
-    dcode = do_find_defense(str, NULL, komaster, kom_pos);
-    if (dcode != WIN && do_attack(str, NULL, komaster, kom_pos)) {
-      if (dcode == 0) {
-       popgo();
-       *move = xpos;
-       return WIN;
-      }
-      UPDATE_SAVED_KO_RESULT(savecode, savemove, dcode, xpos);
-    }
-    popgo();
+    if (!is_self_atari(xpos, other))
+      ADD_CANDIDATE_MOVE(xpos, 0, *moves);
   }
-
-  if (savecode != 0)
-    *move = savemove;
-
-  return savecode;
 }


@@ -3968,14 +3781,11 @@
  * the code that follows can find the attacking move at *.
  */

-static int
-special_attack4(int str, int libs[2], int *move, int komaster, int kom_pos)
+static void
+special_attack4_moves(int str, int libs[2], struct reading_moves *moves)
 {
   int color = board[str];
   int other = OTHER_COLOR(color);
-  int dcode;
-  int savemove = 0;
-  int savecode = 0;
   int adj, adjs[MAXCHAIN];
   int adj2, adjs2[MAXCHAIN];
   int libs2[2];
@@ -3995,7 +3805,7 @@
    */
   if (!is_self_atari(libs[0], other)
       || !is_self_atari(libs[1], other))
-    return 0;
+    return;

   /* Pick up chain links with 2 liberties. */
   adj = chainlinks2(str, adjs, 2);
@@ -4050,27 +3860,10 @@
        if (elibs > dlibs)
          continue;

-       if (trymove(dpos, other, "special_attack4", str, komaster, kom_pos)) {
-         dcode = do_find_defense(str, NULL, komaster, kom_pos);
-
-         if (dcode != WIN && do_attack(str, NULL, komaster, kom_pos)) {
-           if (dcode == 0) {
-             popgo();
-             *move = dpos;
-             return WIN;
-           }
-           UPDATE_SAVED_KO_RESULT(savecode, savemove, dcode, dpos);
-         }
-         popgo();
-       }
+       ADD_CANDIDATE_MOVE(dpos, 0, *moves);
       }
     }
   }
-
-  if (savecode != 0)
-    *move = savemove;
-
-  return savecode;
 }


@@ -4087,14 +3880,12 @@
  *
  */

-static int
-draw_back(int str, int *move, int komaster, int kom_pos)
+static void
+draw_back_moves(int str, struct reading_moves *moves)
 {
   int r, k;
   int adj, adjs[MAXCHAIN];
   int libs[2];
-  int savemove = 0;
-  int savecode = 0;

   adj = chainlinks2(str, adjs, 2);
   for (r = 0; r < adj; r++) {
@@ -4109,27 +3900,10 @@
                     && liberty_of_string(NORTH(libs[k]), str))
              || (ON_BOARD1(EAST(libs[k]))
                     && liberty_of_string(EAST(libs[k]), str)))) {
-       if (trymove(libs[k], OTHER_COLOR(board[str]), "draw_back", str,
-                   komaster, kom_pos)) {
-         int dcode = do_find_defense(str, NULL, komaster, kom_pos);
-         if (dcode != WIN && do_attack(str, NULL, komaster, kom_pos)) {
-           if (dcode == 0) {
-             popgo();
-             *move = libs[k];
-             return WIN;
-           }
-           UPDATE_SAVED_KO_RESULT(savecode, savemove, dcode, libs[k]);
-         }
-         popgo();
-       }
+       ADD_CANDIDATE_MOVE(libs[k], 0, *moves);
       }
     }
   }
-
-  if (savecode != 0)
-    *move = savemove;
-
-  return savecode;
 }

 /* In the following position the reading is much simplifed if we start
@@ -4152,8 +3926,8 @@
  * and b and c do not contain more O stones than X stones.
  */

-static int
-edge_closing_backfill(int str, int apos, int *move)
+static void
+edge_closing_backfill_moves(int str, int apos, struct reading_moves *moves)
 {
   int color = board[str];
   int other = OTHER_COLOR(color);
@@ -4168,7 +3942,7 @@
     if (ON_BOARD(apos - up))
       continue;
     if (board[apos + up] != color)
-      return 0;
+      return;
     if (board[apos + right] == EMPTY
        && (!ON_BOARD(apos - right)
            || board[apos - right] == color))
@@ -4180,14 +3954,14 @@
       right = -right;
     }
     else
-      return 0;
+      return;

     if (board[apos + up + right] != other)
-      return 0;
+      return;

     bpos = apos + up + 2 * right;
     if (!ON_BOARD(bpos))
-      return 0;
+      return;

     cpos = apos + 2 * right;

@@ -4204,13 +3978,11 @@
       number_o++;

     if (number_o > number_x)
-      return 0;
+      return;

-    *move = apos + right;
-    return WIN;
+    ADD_CANDIDATE_MOVE(apos + right, 0, *moves);
+    return;
   }
-
-  return 0;
 }


@@ -4612,19 +4384,15 @@


 /*
- * (str) points to a group. break_chain3(str, *move)
- * returns 1 if there is a string in the surrounding chain having
+ * (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). Then (*move) points to the location of the attacking move.
- *
- * Returns KO_A if the saving move depends on ignoring a ko threat;
- *
- * Returns KO_B if the saving move requires making a ko threat and winning
- * the ko.
+ * (str), break_chain3(str, *moves) adds attack moves against
+ * the surrounding string as candidate moves.
  */

-static int
-break_chain3(int str, int *move, int komaster, int kom_pos)
+static void
+break_chain3_moves(int str, struct reading_moves *moves)
 {
   int color = board[str];
   int other = OTHER_COLOR(color);
@@ -4635,13 +4403,8 @@
   int adj;
   int adjs[MAXCHAIN];
   int libs[3];
-  int moves[MAX_MOVES];
+  int possible_moves[MAX_MOVES];
   int mw[BOARDMAX];
-  int savemove = 0;
-  int savecode = 0;
-  int liberties = countlib(str);
-
-  SETUP_TRACE_INFO("break_chain3", str);

   memset(mw, 0, sizeof(mw));

@@ -4658,6 +4421,7 @@
      */
     findlib(apos, 3, libs);

+#if 1
     /* If the 3 liberty chain easily can run away through one of the
      * liberties, we don't play on any of the other liberties.
      */
@@ -4672,146 +4436,70 @@

     if (lib1 >= 4 && !mw[libs[0]]) {
       mw[libs[0]] = 1;
-      moves[u++] = libs[0];
+      possible_moves[u++] = libs[0];
       continue;
     }

     if (lib2 >= 4 && !mw[libs[1]]) {
       mw[libs[1]] = 1;
-      moves[u++] = libs[1];
+      possible_moves[u++] = libs[1];
       continue;
     }

     if (lib3 >= 4 && !mw[libs[2]]) {
       mw[libs[2]] = 1;
-      moves[u++] = libs[2];
+      possible_moves[u++] = libs[2];
       continue;
     }
+#endif

     /* No easy escape, try all liberties. */
     for (k = 0; k < 3; k++) {
       if (!mw[libs[k]]) {
        mw[libs[k]] = 1;
-       moves[u++] = libs[k];
+       possible_moves[u++] = libs[k];
       }
     }
   }

   /* We do not wish to consider the move if it can be
    * immediately recaptured, unless stackp <= backfill2_depth.
+   * This doesn't actually seem to impact reading node counts.
    */

   for (v = 0; v < u; v++) {
-    if (!trymove(moves[v], color, "break_chain3-A", str, komaster, kom_pos))
-      continue;
-
-    if (countlib(moves[v]) == 1 && stackp > backfill2_depth) {
-      popgo();
+#if 1
+    if (approxlib(possible_moves[v], color, 5, NULL) == 1 && stackp > 
backfill2_depth)
       continue;
-    }
-
-    /* If we just filled our own liberty we back out now */
-    if (countlib(str) >= liberties) {
-      int acode = do_attack(str, NULL, komaster, kom_pos);
-      if (acode == 0) {
-       *move = moves[v];
-       popgo();
-       SGFTRACE(moves[v], WIN, "attack defended");
-       return WIN;
-      }
-      UPDATE_SAVED_KO_RESULT(savecode, savemove, acode, moves[v]);
-    }
-    popgo(); /* (moves[v]) */
-  }
-
-  if (savecode != 0) {
-    *move = savemove;
-    SGFTRACE(savemove, savecode, "saved move");
-    return savecode;
+#endif
+    ADD_CANDIDATE_MOVE(possible_moves[v], 0, *moves);
   }
-
-  SGFTRACE(0, 0, NULL);
-  return 0;
 }

 /* This function looks for moves attacking those components
  * of the surrounding chain of the superstring (see find_superstring
  * for the definition) which have fewer than liberty_cap liberties,
  * and which are not adjacent to the string itself, since those
- * are tested by break_chain. If such a boundary chain can be
- * attacked, and if attacking the boundary results in saving
- * the (str) string, then success is reported.
+ * are tested by break_chain.
  */
-/* FIXME: Consider ko captures */
-static int
-superstring_breakchain(int str, int *move, int komaster, int kom_pos,
-                      int liberty_cap)
+static void
+superstring_breakchain_moves(int str, int liberty_cap, struct reading_moves 
*moves)
 {
-  int color = board[str];
   int adj;
   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);
+      ADD_CANDIDATE_MOVE(apos, 0, *moves);
     }
     else if (liberties == 2)
-      do_find_break_chain2_efficient_moves(str, adjs[k], &moves);
+      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;
-
-    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)) {
-      if (!ko_move) {
-       int acode = do_attack(str, NULL, new_komaster, new_kom_pos);
-       if (acode == 0) {
-         popgo();
-         *move = apos;
-         SGFTRACE(apos, WIN, "attack defended");
-         return WIN;
-       }
-       else if (acode != WIN) {
-         UPDATE_SAVED_KO_RESULT(savecode, savemove, acode, apos);
-       }
-       popgo();
-      }
-      else {
-       if (do_attack(str, NULL, new_komaster, new_kom_pos) != WIN) {
-         savemove = apos;
-         savecode = KO_B;
-       }
-       popgo();
-      }
-    }
-  }
-
-  if (savecode != 0) {
-    *move = savemove;
-    SGFTRACE(savemove, savecode, "saved move");
-    return savecode;
-  }
-
-  SGFTRACE(0, 0, NULL);
-  return 0;
 }

 /*





reply via email to

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