gnugo-devel
[Top][All Lists]
Advanced

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

Re: [gnugo-devel] connect before capture !


From: Paul Pogonyshev
Subject: Re: [gnugo-devel] connect before capture !
Date: Sat, 29 Jan 2005 23:22:48 +0200
User-agent: KMail/1.4.3

Alain Baeckeroot wrote:
> Hello
>
> This gnugo 3.6 against itself:
>
> An weird game , with noticeable
> W 42 connect W stones because of atari,
> W 44 eat 3 B stones responsible for the atari !
>
> This seems to be a pure mistake ;)
>
> (preceded by an incredible connection due to sente loss
> caused by a useless B d3 ...)

I have a patch that solves it.  The patch tries to be more intelligent
when computing tactical followup values.  Apart from solving this problem,
it also gives a pass in nngs4:580.  The pass looks quite accidental (I
assume W E5 is supposed to kill black stones), but still not bad: now GNU
Go doesn't give any followup to W H5 for threating G6, because black's
response at G5 would threat to defend J5 in turn.

I didn't compare node counters, but it must not cost anything.

With regards to Alain's testcase, the first part of the patch (concerned
with reducing followup based on `ATTACK_MOVE' reasons) reduces the
followup of D9.  The second part keeps the followup for G7 (though
reduces it a little); previously, G7 followup was removed altogether,
because the defense move at J9 would threat the stone at G7.

Paul


--- value_moves.c       23 Jan 2005 00:06:01 +0200      1.144
+++ value_moves.c       29 Jan 2005 21:18:01 +0200      
@@ -2004,23 +2004,98 @@ estimate_territorial_value(int pos, int 
            && find_defense(aa, &defense_move) == WIN
            && defense_move != NO_MOVE) {
          int bad_followup;
-         if (trymove(defense_move, other,
-                     "estimate_territorial_value-b", NO_MOVE)) {
-           if (board[pos] == EMPTY || attack(pos, NULL) != 0) {
+         int attack_move;
+
+         if (attack(pos, &attack_move) != WIN) {
+           int i;
+
+           if (trymove(defense_move, other,
+                       "estimate_territorial_value-b", NO_MOVE)) {
+             if (board[pos] == EMPTY || attack(pos, NULL) != 0) {
+               popgo();
+               popgo();
+               break;
+             }
+
+             /* Now check all `ATTACK_MOVE' reasons for this same
+              * move.  If the defense against current threat makes a
+              * string attacked by this move defendable, we reduce
+              * the followup.
+              *
+              * Adjustments done later are concerned with current
+              * dragon states.  Here we actually try to check if
+              * opponent's reply to our move will have a followup in
+              * turn.
+              */
+             for (i = 0; i < MAX_REASONS; i++) {
+               int reason = move[pos].reason[i];
+               int attacked_string;
+               if (reason < 0)
+                 break;
+
+               attacked_string = move_reasons[reason].what;
+               if (move_reasons[reason].type == ATTACK_MOVE
+                   && board[attacked_string] == other) {
+                 int defense_code = find_defense(attacked_string, NULL);
+                 double down_coefficient = 0.0;
+
+                 switch (defense_code) {
+                 case WIN:
+                   down_coefficient = 2.0;
+                   break;
+
+                 case KO_A:
+                   down_coefficient = 2.0 * 0.5;
+                   break;
+
+                 case KO_B:
+                   down_coefficient = 2.0 * 0.7;
+                   break;
+                 }
+
+                 if (adjustment_down
+                     < (worm[attacked_string].effective_size
+                        * down_coefficient)) {
+                   adjustment_down = (worm[attacked_string].effective_size
+                                      * down_coefficient);
+                 }
+               }
+             }
+
              popgo();
+           }
+         }
+         else {
+           /* Our move is attackable to begin with.  However, maybe
+            * the attack is not sufficient to defend opponent's
+            * string?
+            */
+           if (trymove(attack_move, other,
+                       "estimate_territorial_value-c", NO_MOVE)) {
+             if (attack(aa, NULL) == 0) {
+               /* It is sufficient, no followup. */
+               popgo();
+               popgo();
+               break;
+             }
+
              popgo();
-             break;
            }
-           popgo();
+
+           /* Heuristically reduce the followup, since our string
+            * will be still attackable if opponent defends his
+            * string.
+            */
+           adjustment_down = 2 * countstones(pos);
          }
-         
+
          bad_followup = 0;
          for (s = 0; s < num_adj; s++) {
            int lib;
            if (countlib(adjs[s]) == 1) {
              findlib(adjs[s], 1, &lib);
              if (trymove(lib, other,
-                         "estimate_territorial_value-c", NO_MOVE)) {
+                         "estimate_territorial_value-d", NO_MOVE)) {
                if (!attack(aa, NULL)
                    && (board[pos] == EMPTY || attack(pos, NULL) != 0)) {
                  popgo();





reply via email to

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