[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
attack5.
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
results.
Thanks
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
improvement.
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) {
- [gnugo-devel] attack5,
Evan Berggren Daniel <=