gnugo-devel
[Top][All Lists]
Advanced

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

Re: [gnugo-devel] thrashing dragons again


From: bump
Subject: Re: [gnugo-devel] thrashing dragons again
Date: Sun, 19 Dec 2004 05:13:17 -0800

Arend wrote:

> - We use the thrashing dragon heuristic much more often: Do it even if we
> are behind (up to 30 pts), and don't bother to make it dependant on the
> move value without the thrashing dragon heuristic. This means we don't
> have to run review_move_reasons() twice in the case of a thrashing
> dragon. The rational is that we still won't miss an urgent move somewhere
> else, as the thrashing dragon moves would have to have higher value
> that this urgent moves.
> The decision whether we want to use the thrashing dragon heuristics is
> now remembered by an explicit variable (which gets passed down from
> do_genmove() to estimate_strategical_value()).
> 
> - Strategic attack against thrashing dragon now get the same bonus as
> connection moves around the dragon. Hence if we have several such moves,
> the decision is made according to territorial value, which often guesses
> right.

I thought a little about thrashing dragons and I came up
with the following. It first tries to find a confining
move by the current heuristic, making the dragon ALIVE
then rerunning shapes, but if this doesn't produce
a changed move, then it tries again by making the dragon
CRITICAL, then running owl_reasons(). The rationale is
that if the move is not changed it is probably not
relevant to the thrashing dragon which GNU thinks is dead.
So then it looks for an owl move. A confining or
territorial move is often preferred to a nakade move.

Unfortunately there is exactly one regression change, a
PASS in olympiad2004:4.

It occurs to me that if the opponent attacks our
semeai dragon then his semeai dragon should be
considered thrashing. I haven't tried to implement
this.

Dan

Index: engine/genmove.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/genmove.c,v
retrieving revision 1.100
diff -u -r1.100 genmove.c
--- engine/genmove.c    7 Dec 2004 04:50:02 -0000       1.100
+++ engine/genmove.c    9 Dec 2004 20:19:44 -0000
@@ -50,7 +50,7 @@
 
 static int revise_semeai(int color);
 static int revise_thrashing_dragon(int color, float our_score,
-                                  float advantage);
+                                  float advantage, int new_status);
 
 static void break_mirror_go(int color);
 static int find_mirror_move(int *move, int color);
@@ -438,23 +438,42 @@
   time_report(1, "review move reasons", NO_MOVE, 1.0);
 
   /* If we are ahead by 15 points or more, consider a thrashing
-   * dragon dangerous and change its status from DEAD to
-   * UNKNOWN. This may generate a move.
+   * dragon dangerous and try to generate a move to attack it.
+   * Confining moves are preferred to owl moves since the owl
+   * code has already found the dragon to be dead. If changing
+   * the status of the dragon to ALIVE produces a move that was
+   * different from the previous best move, that move is probably
+   * a confining move for the thrashing dragon. If this fails, we
+   * change the status to CRITICAL which may produce an owl move.
    */
   if (*value < 0.4 * our_score && !doing_scoring && !limit_search) {
-    if (revise_thrashing_dragon(color, our_score, 15.0)) {
+    int old_move = move;
+    if (revise_thrashing_dragon(color, our_score, 15.0, ALIVE)) {
       shapes(color);
       if (!disable_endgame_patterns)
        endgame_shapes(color);
+      collect_move_reasons(color);
       if (review_move_reasons(&move, value, color, pure_threat_value,
-                             our_score, allowed_moves)) {
+                             our_score, allowed_moves) &&
+         move != old_move)
        TRACE("Upon reconsideration move generation likes %1m with value %f\n",
-             move, *value); 
+             move, *value);
+      else {
+       TRACE("second thrashing\n");
+       if (revise_thrashing_dragon(color, our_score, 15.0, CRITICAL)) {
+         shapes(color);
+         if (!disable_endgame_patterns)
+           endgame_shapes(color);
+         collect_move_reasons(color);
+         if (review_move_reasons(&move, value, color, pure_threat_value,
+                                 our_score, allowed_moves))
+           TRACE("Upon reconsideration move generation likes %1m with value 
%f\n",
+                 move, *value); 
+       }
       }
     }
-    time_report(1, "move reasons with revised thrashing status", NO_MOVE, 1.0);
   }
-
+    
   /* If the move value is 6 or lower, we look for endgame patterns too. */
   if (*value <= 6.0 && !disable_endgame_patterns && !limit_search) {
     endgame_shapes(color);
@@ -472,7 +491,7 @@
    * run shapes and endgame_shapes again. This may turn up a move.
    */
   if (move == PASS_MOVE) {
-    if (revise_thrashing_dragon(color, our_score, 0.0)
+    if (revise_thrashing_dragon(color, our_score, 0.0, CRITICAL)
        || revise_semeai(color)) {
       shapes(color);
       endgame_shapes(color);
@@ -650,7 +669,8 @@
  */
 
 static int
-revise_thrashing_dragon(int color, float our_score, float advantage)
+revise_thrashing_dragon(int color, float our_score, float advantage,
+                       int new_status)
 {
   int pos;
   char safe_stones[BOARDMAX];
@@ -661,15 +681,14 @@
     return 0;
 
   if (disable_threat_computation
-      || !thrashing_dragon 
-      || dragon[thrashing_dragon].status != DEAD)
+      || !thrashing_dragon)
     return 0;
   
   for (pos = BOARDMIN; pos < BOARDMAX; pos++)
     if (ON_BOARD(pos) && thrashing_stone[pos]
        && worm[pos].unconditional_status != DEAD) {
-      dragon[pos].status = UNKNOWN;
-      DRAGON2(pos).safety = ALIVE;
+      dragon[pos].status = new_status;
+      DRAGON2(pos).safety = new_status;
     }
 
   set_strength_data(OTHER_COLOR(color), safe_stones, strength);




reply via email to

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