[Top][All Lists]

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

[gnugo-devel] attack5

From: Evan Berggren Daniel
Subject: [gnugo-devel] attack5
Date: Fri, 8 Nov 2002 15:13:25 -0500 (EST)

I tried implementing a simple attack5 reading function to see what
happens, and results look reasonably promising.

The function only attempts to attack by playing liberties of the string.
The reasoning behind this is:
- these are the fastest to fail and therefore the cheapest attacks to try
- if we need a more complex attack, it's probably better to let the owl
code or semeai code do it
- we can get useful results without a corresponding defend5 function
(though it should probably be written anyway).

Regression delta is 17 PASSes, 11 FAILs.  Many of the fails are accidental
or uncovering other bugs.

This probably needs a lot more analysis before putting it in CVS.  I'm
unsure of whether it's a good idea to put it in without defend5.  Clearly,
defend5 is needed before more sophisticated attacks can be tried in

I think the real delta is something like 10 PASSes and 5 FAILs.

Currently, it is probably too expensive, at ~10% reading nodes in owl.tst.
However, this is with a depth value of 5, which seems too high.  It is ~5%
at depth 3.  I will look into making it faster if there is interest in the


Evan Daniel

Here's the details:

optics:1201 FAIL

This uncovers an interesting bug.  Before the patch, the tactical code
can't see what's going on, but the owl code gets it right.  After the
patch, the tactical code gets the attack and defense of the group right.
For reasons unclear to me the owl code then fails to understand things.
The real problem is that if the test is posed as a genmove problem for
either side then it still FAILs.  The bug is that the tactical code sees a
very large attack, and it gets ignored by genmove.  Also, it would be
interesting to figure out why improving the tactical understanding of the
situation hurts the owl results.

blunder:12 PASS

This is real, and exactly the sort of thing I was hoping for

nngs1:35 FAIL

Accidental.  The valuation of D13 drops about 2 points, causing O6 to be
the highest valued move.

nngs1:46 FAIL

This test is bad.  The test is written as !J5, with a comment that defense
of the UR is urgent.  Gnugo fails to defend the UR with or without the
patch, and the patch simply changes gnugo's current answer of B12 to J5,
which is probably an improvement, since I don't think B12 works anyway.

golife:2 PASS

I think this is real, but I haven't investigate in detail.

viking:1 PASS

looks accidental

dniwog:7 PASS

very real.

lazarus:4 PASS

looks real.  Q12 is now valued at 72 points, putting it well ahead of T5.
I haven't looked at why.

lazarus:13 FAIL

S8 is now valued at 95 points.  The owl code sees an attack on R13 and P10
here that it didn't see before.  attack R8 now returns 1 R7, which I think
is correct.  I think this might be a partial improvement, but I can't read
the position well enough to tell.

lazarus:14 PASS

I'm not entirely sure.  T5 is now more highly valued, but Q14 is still
ranked higher than Q15.

lazarus: 15 PASS

Again T5 gets valued highly.  S8 is still valued highly also.  S13 is no
longer valued much at all, which probably counts as an improvement.

trevorb:650 FAIL

I'm not sure, could well be real.

strategy2:72 PASS

This is real.  Before, gnugo thought the black dragon was killable because
H2 got 5 liberties for the white group, which made it tactically alive.
gnugo no longer sees a defense for the H4 string, and believes that E8 is
alive, not critical.  This is good.

nicklas1:603 FAIL

Looks real.

nicklas5:1211 PASS

A tactical attack on the F15 dragon is now found.  However, gnugo still
misreads the semeai.  (Fill outside liberties, and l8 still gets counted
alive.)  So the thing the test was looking for hasn't been fixed.

global:32 PASS

Looks real.

vie:16 PASS

Gnugo now sees an attack on the black group, and no defense, but probably
still doesn't understand the semeai.

arend:33 FAIL

Improved, but the basic problem that gnugo fails to see the cut has not
been solved.  As long as gnugo believes the D8 dragon is alive, it is
probably better to block the invasion in the UR, which it now does by
playing S15.  So I think this counts as a fail, not a FAIL.

13x13:36 FAIL

gnugo now defends the corner tactically with B2.  This is probably a bad
idea.  I think this move might actually be reasonable, but the valuation
of 88 probably isn't.  However, I can't really read the position, so
someone else should probably look at this.

trevord:650 PASS

I'm not sure.

strategy4:188 PASS

Looks real.

K3 is still valued too close to the correct answers, but this is an

The owl_attack on B5 at B6 is now found.

handtalk:2 FAIL

I'm not sure, could be real.

nngs2:480 PASS

Gnugo now plays J6, which is a move to secure life like the comment
suggests.  Looks real.

nngs2:520 PASS

Gnugo now sees an attack on D8 at D9, and connects to defend against it.
However, it only sees the attack tactically, and does not understand the
semeai.  Looks like an improvement, or perhaps even a real PASS.

nngs3:870 PASS

Looks accidental.  Gnugo no longer plays g2, but instead plays b4, which
isn't any better.  G2 is no longer see as at all valuable, though, so this
probably counts as a small improvement.

nngs3:1010 FAIL

This is a fail, not a fail.  Currently gnugo only values the correct move
at 2.4, which means it doesn't see the risk of w living.

strategy5:224 FAIL

Probably real.

ninestones:40 PASS

This is real.  D2 is no longer valued.

And here's the patch:

Index: engine/reading.c
RCS file: /cvsroot/gnugo/gnugo/engine/reading.c,v
retrieving revision 1.83
diff -u -r1.83 reading.c
--- engine/reading.c    20 Oct 2002 10:05:39 -0000      1.83
+++ engine/reading.c    8 Nov 2002 20:08:31 -0000
@@ -158,6 +158,7 @@
 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 attack5(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_cap3(int str, int *move, int komaster, int kom_pos);
@@ -2837,8 +2838,8 @@

   libs = countlib(str);

-  if (libs > 4
-      || (libs == 4 && stackp > fourlib_depth)) {
+  if (libs > 5
+      || (libs >= 4 && stackp > fourlib_depth)) {
     /* No need to cache the result in these cases. */
     if (sgf_dumptree) {
       char buf[100];
@@ -2886,6 +2887,8 @@
     result = attack3(str, &xpos, komaster, kom_pos);
   else if (libs == 4)
     result = attack4(str, &xpos, komaster, kom_pos);
+  else if (libs == 5)
+    result = attack5(str, &xpos, komaster, kom_pos);

   ASSERT1(result >= 0 && result <= WIN, str);
@@ -3642,6 +3656,76 @@
     xpos = moves.pos[k];
     /* Conditional ko capture is disabled because it seems to expensive. */
     if (komaster_trymove(xpos, other, "attack4-A", str,
+                        komaster, kom_pos, &new_komaster, &new_kom_pos,
+                        &ko_move, 0 && stackp <= ko_depth && savecode == 0)) {
+      if (!ko_move) {
+       dcode = do_find_defense(str, NULL, new_komaster, new_kom_pos);
+       if (dcode != WIN && do_attack(str, NULL, new_komaster, new_kom_pos)) {
+         popgo();
+         CHECK_RESULT(savecode, savemove, dcode, xpos, move,
+                      "attack effective");
+       }
+       else
+         popgo();
+      }
+      else {
+       if (do_find_defense(str, NULL, new_komaster, new_kom_pos) != WIN
+           && do_attack(str, NULL, new_komaster, new_kom_pos) != 0) {
+         savemove = xpos;
+         savecode = KO_B;
+       }
+       popgo();
+      }
+    }
+  }
+  RETURN_RESULT(savecode, savemove, move, "saved move");
+static int
+attack5(int str, int *move, int komaster, int kom_pos)
+  int color = board[str];
+  int other = OTHER_COLOR(color);
+  int xpos;
+  int k;
+  int liberties;
+  int libs[5];
+  int dcode = 0;
+  struct reading_moves moves;
+  int savemove = 0;
+  int savecode = 0;
+  SETUP_TRACE_INFO("attack5", str);
+  gg_assert(IS_STONE(board[str]));
+  reading_node_counter++;
+  moves.num = 0;
+  if (stackp > 3) {
+    SGFTRACE(0, 0, "stackp > 3");
+    return 0;
+  }
+  liberties = findlib(str, 5, libs);
+  gg_assert(liberties == 5);
+  for (k = 0; k < 5; k++) {
+    ADD_CANDIDATE_MOVE(libs[k], 5, moves);
+  }
+  /* Try the moves collected so far. */
+  for (k = 0; k < moves.num && k < 5; k++) {
+    int new_komaster;
+    int new_kom_pos;
+    int ko_move;
+    if (stackp >= branch_depth && k > 0)
+      break;
+    xpos = moves.pos[k];
+    /* Conditional ko capture is disabled because it seems to expensive. */
+    if (komaster_trymove(xpos, other, "attack5-A", str,
                         komaster, kom_pos, &new_komaster, &new_kom_pos,
                         &ko_move, 0 && stackp <= ko_depth && savecode == 0)) {
       if (!ko_move) {

reply via email to

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