gnugo-devel
[Top][All Lists]
Advanced

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

Re: [gnugo-devel] another semeai patch


From: Paul Pogonyshev
Subject: Re: [gnugo-devel] another semeai patch
Date: Thu, 15 Jan 2004 02:45:15 +0000
User-agent: KMail/1.5.94

I wrote:
> So, maybe we should rather try to make `probable_eyes_b' contain more
> accurate results (and not waste semeai nodes).  I will regress the
> change i proposed: ignoring lunches for dragon B which are part of
> dragon A (like we do for dragon A's lunches which are part of B).

Here is the breakage:

trevorc:1000    FAIL F11 [N9|M11]
semeai:59       PASS 1 1 H5 [1 1 H5]
semeai:60       FAIL 1 1 H5 [0 0 PASS]
semeai:75       PASS 1 0 PASS [1 0 PASS]
semeai:76       PASS 1 0 N3 [1 0 (PASS|N3|      K2)]
semeai:78       PASS 1 0 A6 [1 0 (PASS|A6|C6|C1)]
semeai:99       pass (failed by CVS)
ninestones:560  PASS J15 [A9|B10|D11|F11|J15|A16]
ninestones:660  FAIL Q2 [P1]
9x9:120         FAIL B1 [F1]
9x9:290         PASS D2 [D2]

Without the original breakage delta we get

trevorc:1000    FAIL F11 [N9|M11]
semeai:75       PASS 1 0 PASS [1 0 PASS]
semeai:76       PASS 1 0 N3 [1 0 (PASS|N3|      K2)]
semeai:78       PASS 1 0 A6 [1 0 (PASS|A6|C6|C1)]
semeai:99       pass (failed by CVS)
ninestones:660  FAIL Q2 [P1]
9x9:290         PASS D2 [D2]

5 passes, 2 fails (3 passes are most likely similar to each other).
In addition to a slightly positive delta, more correct eyevalue
estimation gives a warming feeling.

There seems to be no significant impact on node counters.

The new version of the patch, which reenables "lunch ignoring code" is
below.

Paul


--- owl.c.~1.187.~      2004-01-12 23:48:50.000000000 +0000
+++ owl.c       2004-01-14 22:44:39.000000000 +0000
@@ -228,6 +228,8 @@ static int semeai_trymove_and_recurse(in
                                      int *this_resulta, int *this_resultb);
 static void semeai_add_sgf_comment(int value, int owl_phase);
 static int semeai_trust_tactical_attack(int str);
+static int semeai_propose_eyespace_filling_move(struct local_owl_data *owla,
+                                               struct local_owl_data *owlb);
 static void semeai_review_owl_moves(struct owl_move_data owl_moves[MAX_MOVES],
                                    struct local_owl_data *owla,
                                    struct local_owl_data *owlb, int color,
@@ -704,7 +706,7 @@ do_owl_analyze_semeai(int apos, int bpos
        owla->lunch[k] = NO_MOVE;
       }
     }
-#if 0
+#if 1
     for (k = 0; k < MAX_LUNCHES; k++) {
       if (owlb->lunch[k] != NO_MOVE 
          && owla->goal[owlb->lunch[k]]) {
@@ -925,7 +927,20 @@ do_owl_analyze_semeai(int apos, int bpos
   }
 
   if (moves[0].pos == NO_MOVE) {
-    TRACE("No move found\n");
+    /* If no move has been found yet, see if we can fill opponent's
+     * eye (i.e. put more stones in "bulky five" shape).
+     */
+    if (min_eyes(&probable_eyes_b) == 1) {
+      int move = semeai_propose_eyespace_filling_move(owla, owlb);
+
+      if (move) {
+       owl_add_move(moves, move, 70,
+                    "eyespace filling", 0, 0, NO_MOVE, MAX_SEMEAI_MOVES);
+      }
+    }
+
+    if (moves[0].pos == NO_MOVE)
+      TRACE("No move found\n");
   }
   
   /* Now we are ready to try moves. Turn on the sgf output ... */
@@ -1292,6 +1307,69 @@ semeai_review_owl_moves(struct owl_move_
   }
 }
 
+
+/* Propose an eyespace filling move.  Such a move can, for instance,
+ * add a stone to opponent's "bulky five" shape.  We of course choose
+ * a move that doesn't allow opponent to turn his dead eyeshape into a
+ * two eyes eyeshape.  E.g. in this position, the function will
+ * propose the move at '*', not at the '.':
+ *
+ *      XXX
+ *     XXOX
+ *     XOOX
+ *     X.*X
+ *     ----
+ */
+static int
+semeai_propose_eyespace_filling_move(struct local_owl_data *owla,
+                                    struct local_owl_data *owlb)
+{
+  int color = OTHER_COLOR(owlb->color);
+  int pos;
+  char mw[BOARDMAX];
+  char mz[BOARDMAX];
+
+  owl_find_relevant_eyespaces(owlb, mw, mz);
+
+  /* Never try to fill opponent's eyes which contain our dragon.  This
+   * is nothing else than suicide.
+   */
+  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+    if (ON_BOARD(pos) && owla->goal[pos])
+      mw[owlb->my_eye[pos].origin] = 0;
+  }
+
+  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+    if (board[pos] == EMPTY) {
+      int origin = owlb->my_eye[pos].origin;
+
+      if (mw[origin] > 1
+         && min_eyes(&owlb->my_eye[origin].value) == 1) {
+       int good_move = 0;
+
+       if (trymove(pos, color, "eyespace_filling", NO_MOVE, EMPTY, NO_MOVE)) {
+         struct eyevalue new_value;
+         int dummy_attack;
+         int dummy_defense;
+
+         compute_eyes(origin, &new_value, &dummy_attack, &dummy_defense,
+                      owlb->my_eye, owlb->half_eye, 0, owlb->color);
+         if (max_eyes(&new_value) <= 1)
+           good_move = 1;
+
+         popgo();
+       }
+
+       if (good_move)
+         return pos;
+      }
+    }
+  }
+
+  return NO_MOVE;
+}
+
+
 /* Try to estimate the value of a semeai move. This has two
  * components. The first is the change in the total number of
  * liberties for strings involved in the semeai. The second is a bonus





reply via email to

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