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, 10 Apr 2004 18:03:26 +0300
User-agent: KMail/1.6.50

- edge_block_moves() proposes more moves

More in the comments in the patch.  Note that the added moves
are not similar to those in #if 0'ed version of the function.

<advertisement>
I used DUMP_ALL_RESULTS feature in `reading.c' for breakage
analysis.  It's difficult to find tactical reading deviations
in a `reg_genmove' test otherwise.  If only it was faster ;)
</advertisement>

Regression breakage:

owl:150         PASS 0 [0]

        Certain impovement.  `attack C17' now reports `1 D17'
        as it should.  Don't know if the owl reading became
        more correct, but it's not an owl patch after all.

trevora:290     PASS E6 [!C8]

        Don't know, must be some weird cache issues.  The only
        reading result deviation is as follows:

                                       [orig] [patched]
                W:B5 attack B5 (16)     5 C5    0 PASS

        However, I'm unable to reproduce it without issuing
        `reg_genmove', even when seed is set to 0 from command
        line.

niki:4          pass (failed by CVS)

        Three tactical deviations.  In the one that is close to
        the P17 dragon the patch gives improvement.  Reading
        result is incorrect (should be 5 P19), but only because
        it is way beyond ko depth.  Unpatched version doesn't
        see any attack at all.

          W:Q19 B:S17 W:S15 B:S16 W:R15 B:T16 W:S14 B:T18 W:R18 B:Q18 attack 
R18 (16)
             [orig] [patched]
             0 PASS  5 R19

nngs:1620       improvement (the targeted test case)

        This time I didn't analyze reading deviations (I know
        what I aimed at in this test).  Unpatched version
        doesn't want to constraint C3 dragon as it considers
        it dead.  After the patch, B5 is valued to 40.15, while
        B3 is 40.42.  Maybe we should relax the correct answer
        for this test case.

nngs4:230       FAIL L18 [Q18]

        Unbearable amount of reading changes.  However, in the
        one at smallest depth (which is also in the region of
        the move):

                                                [orig] [patched]
                B:R18 W:Q18 attack R18 (17)     0 PASS  5 R17

        the patch gives an improvement (5 R17 is correct).  So
        the fail is probably due to uncovered owl misreads.

manyfaces1:36   PASS P16 [P16]

        Similar to above.  In a selected local deviation

                                                  [orig] [patched]
          W:R10 B:S11 W:S16 W:Q17 attack R17 (16) 0 PASS  5 Q18

        the patched version gives the correct result.

arend2:70       PASS O9 [N7|O9]

        Again several deviations and again the patch gives correct
        result in the one near the move and with the smallest
        depth:

                                                [orig] [patched]
                W:O9 B:N7 attack O10 (16)       0 PASS  5 N10

9x9:350         FAIL 1 B4 [0]

        In two related deviations patched version gives correct
        results:

                                                          [orig] [patched]
          B:B4 W:B5 B:D2 W:B2 B:C2 W:B3 attack C3 (16)    0 PASS  5 E2
          B:B4 W:B5 B:D2 W:B2 B:C2 W:E2 attack C2 (16)    0 PASS  5 B3

        This a "getting deep, looks lively" owl misread.

So, in all cases the patch seems to give tactical improvement.

Node counters (before is not a clean CVS):

before: 1547248251 2797728 10935111
after:  1552157384 2792395 10926816
            +0.32%  -0.19%   -0.08%

Paul



--- reading.c.~1.138.~  2004-02-12 23:29:21.000000000 +0200
+++ reading.c   2004-04-10 18:02:16.000000000 +0300
@@ -32,7 +32,7 @@
 #include "patterns.h"
 #include "gg_utils.h"
 
-/* If defined, attack() and find_defense() write all results to
+/* If nonzero, attack() and find_defense() write all results to
  * stderr.  Use this to if you have deviations in results, but cannot
  * find where they come from.
  *
@@ -41,7 +41,8 @@
  * sorted dumps:
  *
  *   join -t= sorted-first-dump sorted-second-dump \
- *   | sed -e "s/^[^=]\+=\([^=]\+\)=\1$//" | tr -s "\n" | tr = "\t"
+ *   | sed -e "s/^[^=]\+=\([^=]\+\)=\1$//" | tr -s "\n" | tr = "\t" \
+ *   | uniq
  *
  * to get a nice list of deviations.  This is only meaningful if you
  * dump results of a single test (or at least tests originating at a
@@ -4196,23 +4197,31 @@ edge_block_moves(int str, int apos, stru
 
 /* In positions like
  *
- * OOX..
- * XXO*.
- * x.X..
- * -----
+ *   OOX..
+ *   XXO*.
+ *   x.X..
+ *   -----
  *
  * where the X stones to the left are being attacked, it is usually
  * important to start by considering the move at *. Thus we propose
  * the move at * with a high initial score.
  *
+ * Also, it is often needed to prevent "crawling" along first line
+ * which can eventually give defender more liberties, like here:
+ *
+ *   O.OO..X
+ *   OXXO..X
+ *   ...X*..
+ *   -------
+ *
  * This function identifies the situation
  *
- * XO.?   bdf?
- * .X.o   aceg
- * ----   ----
+ *   XO.?   bdf?
+ *   .X.o   aceg
+ *   ----   ----
  *
  * where a is a liberty of the attacked string, b is a stone of the
- * attacked string, and f is the considered moves.
+ * attacked string, and e and f are the considered moves.
  */
 
 static void
@@ -4220,17 +4229,13 @@ edge_block_moves(int str, int apos, stru
 {
   int color = board[str];
   int other = OTHER_COLOR(color);
-  int k, l;
-  int cpos;
-  int dpos;
-  int epos;
-  int fpos;
-  int gpos;
-  int hpos;
+  int k;
 
   /* Search for the right orientation. */
   for (k = 0; k < 4; k++) {
+    int l;
     int up = delta[k];
+
     if (ON_BOARD(apos - up))
       continue;
     if (board[apos + up] != color || !same_string(apos + up, str))
@@ -4238,26 +4243,45 @@ edge_block_moves(int str, int apos, stru
     
     for (l = 0; l < 2; l++) {
       int right = delta[(k+1)%4];
+      int cpos;
+      int dpos;
+      int epos;
+      int fpos;
+
       if (l == 1)
        right = -right;
 
       cpos = apos + right;
       dpos = apos + right + up;
-
-      if (board[cpos] != color || board[dpos] != other || countlib(dpos) > 1)
-       continue;
-
       epos = cpos + right;
       fpos = dpos + right;
-      gpos = epos + right;
-      hpos = apos - right;
-      
-      if (!ON_BOARD(epos))
-       continue;
-      
-      if (board[epos] == EMPTY && board[fpos] == EMPTY 
-         && (board[gpos] != color))
-       ADD_CANDIDATE_MOVE(fpos, 30, *moves, "edge_block");
+
+      if (board[cpos] == color && board[dpos] == other
+         && board[epos] == EMPTY && board[fpos] == EMPTY) {
+       if (countlib(dpos) == 1) {
+         int gpos = epos + right;
+
+         /* Check if we have the first situation. */
+         if (board[gpos] != color)
+           ADD_CANDIDATE_MOVE(fpos, 30, *moves, "edge_block-A");
+       }
+       else {
+         int edge_scan;
+
+         /* Look along board edge to see if the defender's string can
+          * run away to a friend.
+          */
+         for (edge_scan = epos; ; edge_scan += right) {
+           if (board[edge_scan] == color || board[edge_scan + up] == color) {
+             ADD_CANDIDATE_MOVE(epos, 10, *moves, "edge_block-B");
+             break;
+           }
+
+           if (board[edge_scan] != EMPTY || board[edge_scan + up] != EMPTY)
+             break;
+         }
+       }
+      }
     }
   }
 }




reply via email to

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