gnugo-devel
[Top][All Lists]
Advanced

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

Re: [gnugo-devel] changed board_hash after reading


From: Martin Holters
Subject: Re: [gnugo-devel] changed board_hash after reading
Date: Tue, 23 Aug 2005 19:38:09 +0200

ons 2005-08-17 klockan 23:21 +0200 skrev Gunnar FarnebXck:
> Martin wrote:
> > I digged a little deeper to find out that 
> > 
> >   if (komaster_trymove(...))
> >     popgo();
> > 
> > can alter the board_hash. I blame this on the invocations of
> > set_new_komaster() and set_new_kom_pos(). Before I start figuring out
> > what komaster_trymove does (and how to fix it): Is this indeed a problem
> > to be fixed or am I overlooking something and making wrong assumptions?
> 
[...]
> What I don't understand is why this hasn't caused more obvious
> problems. Actually, could you just try something quick and dirty and
> see what effects it has on the regressions? See also this message from
> Arend when he made komaster part of the board state:
> 
> http://lists.gnu.org/archive/html/gnugo-devel/2004-04/msg00042.html
> 

Ok, I tried the appended patches, where the changes to reading.c only
add some ad-hoc sanity checks that the board_hash doesn't change when it
should not (and should probably not be applied).
In board.c I moved the updates to the komaster states a little bit
around to make sure they only change when a new move is actually added
to the stack. Out of laziness, I appended part of it to do_trymove. Is
that legal or does it break something? I do not really understand the
komaster business, so I would appreciate some verification of these
changes by someone who has more insight.

Regression breakage is
arb:210         PASS D8 [D8]
ninestones:570  FAIL A2 [A9|B10|D11|F11|J15|A16]

Reading nodes increase by 2.2% (!), changes to owl and connection nodes
are below 0.1%. And of course, the assertions do not fire.

/Martin

Index: engine/board.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/board.c,v
retrieving revision 1.111
diff -u -r1.111 board.c
--- engine/board.c      12 Jun 2005 09:34:13 -0000      1.111
+++ engine/board.c      23 Aug 2005 17:22:11 -0000
@@ -314,6 +314,9 @@
 static void do_commit_suicide(int pos, int color);
 static void do_play_move(int pos, int color);
 
+static void set_new_komaster(int new_komaster);
+static void set_new_kom_pos(int new_kom_pos);
+
 static int komaster, kom_pos;
 
 
@@ -689,6 +692,18 @@
     do_play_move(pos, color);
   }
 
+  if (((komaster == WHITE || komaster == GRAY_WHITE)
+       && (IS_STONE(board[kom_pos])
+          || (!is_ko(kom_pos, BLACK, NULL)
+              && is_suicide(kom_pos, BLACK))))
+      || ((komaster == BLACK || komaster == GRAY_BLACK)
+         && (IS_STONE(board[kom_pos])
+             || (!is_ko(kom_pos, WHITE, NULL)
+                 && is_suicide(kom_pos, WHITE))))) {
+    set_new_komaster(EMPTY);
+    set_new_kom_pos(NO_MOVE);
+  }
+
   return 1;
 }
 
@@ -1226,35 +1241,19 @@
   int kpos;
   int previous_board_ko_pos = board_ko_pos;
 
-  /* First we check whether the ko claimed by komaster has been
-   * resolved. If that is the case, we revert komaster to EMPTY.
-   *
-   * The ko has been resolved in favor of the komaster if it has
-   * been filled, or if it is no longer a ko and an opponent move
-   * there is suicide.
-   */
-  if (((komaster == WHITE || komaster == GRAY_WHITE)
+  ASSERT1 (!((komaster == WHITE || komaster == GRAY_WHITE)
        && (IS_STONE(board[kom_pos])
           || (!is_ko(kom_pos, BLACK, NULL)
               && is_suicide(kom_pos, BLACK))))
       || ((komaster == BLACK || komaster == GRAY_BLACK)
          && (IS_STONE(board[kom_pos])
              || (!is_ko(kom_pos, WHITE, NULL)
-                 && is_suicide(kom_pos, WHITE))))) {
-    set_new_komaster(EMPTY);
-    set_new_kom_pos(NO_MOVE);
-  }
+                 && is_suicide(kom_pos, WHITE)))), pos);
 
   *is_conditional_ko = 0;
   ko_move = is_ko(pos, color, &kpos);
 
-  if (!ko_move) {
-    if (komaster == WEAK_KO) {
-      set_new_komaster(EMPTY);
-      set_new_kom_pos(NO_MOVE);
-    }
-  }
-  else {
+  if (ko_move) {
     /* If opponent is komaster we may not capture his ko. */
     if (komaster == other && pos == kom_pos)
       return 0;
@@ -1293,8 +1292,13 @@
     }
   }
 
-  if (!ko_move)
+  if (!ko_move) {
+    if (komaster == WEAK_KO) {
+      set_new_komaster(EMPTY);
+      set_new_kom_pos(NO_MOVE);
+    }
     return 1;
+  }
 
   if (komaster == other) {
     if (color == WHITE)
Index: engine/reading.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/reading.c,v
retrieving revision 1.159
diff -u -r1.159 reading.c
--- engine/reading.c    12 Jun 2005 09:34:14 -0000      1.159
+++ engine/reading.c    23 Aug 2005 17:22:21 -0000
@@ -183,6 +183,10 @@
 #define ATTACK_TRY_MOVES(no_deep_branching, defense_hint)              \
   do {                                                                 \
     int k;                                                             \
+    int i;                                                              \
+    Hash_data old_board_hash;                                           \
+    for (i = 0; i < NUM_HASHVALUES; i++)                                \
+      old_board_hash.hashval[i] = board_hash.hashval[i];                \
                                                                        \
     for (k = moves.num_tried; k < moves.num; k++) {                    \
       int ko_move;                                                     \
@@ -197,6 +201,7 @@
          if (!ko_move) {                                               \
            if (dcode == 0) {                                           \
              popgo();                                                  \
+             ASSERT1(hashdata_is_equal(board_hash, old_board_hash), str);\
              RETURN_RESULT(WIN, apos, move, "attack effective");       \
            }                                                           \
                                                                        \
@@ -210,7 +215,9 @@
        }                                                               \
                                                                        \
        popgo();                                                        \
+       ASSERT1(hashdata_is_equal(board_hash, old_board_hash), str);    \
       }                                                                        
\
+      ASSERT1(hashdata_is_equal(old_board_hash, board_hash), str);      \
                                                                        \
       if ((no_deep_branching) && stackp >= branch_depth)               \
        RETURN_RESULT(savecode, savemove, move, "branching limit");     \
@@ -380,6 +387,7 @@
 
   memset(shadow, 0, sizeof(shadow));
   result = do_attack(str, &the_move);
+  ASSERT1(result == do_attack(str, &the_move), str);
   nodes = reading_node_counter - nodes_when_called;
 
   if (debug & DEBUG_READING_PERFORMANCE) {
@@ -1162,6 +1170,8 @@
   int dcode = 0;
   int liberties;
   int retval;
+  int i;
+  Hash_data old_board_hash;
   
   SETUP_TRACE_INFO("find_defense", str);
 
@@ -1214,6 +1224,9 @@
   }
 #endif
 
+  for (i = 0; i < NUM_HASHVALUES; i++)
+    old_board_hash.hashval[i] = board_hash.hashval[i];
+
   if (liberties == 1)
     dcode = defend1(str, &xpos);
   else if (liberties == 2)
@@ -1223,6 +1236,8 @@
   else if (liberties == 4)
     dcode = defend4(str, &xpos);
 
+  ASSERT1(hashdata_is_equal(old_board_hash, board_hash), str);
+
   if (dcode) {
     READ_RETURN(FIND_DEFENSE, str, depth - stackp, move, xpos, dcode);
   }
@@ -3139,6 +3154,8 @@
   int liberties;
   int result = 0;
   int retval;
+  int i;
+  Hash_data old_board_hash;
 
   SETUP_TRACE_INFO("attack", str);
 
@@ -3193,6 +3210,9 @@
   }
 #endif
 
+  for (i = 0; i < NUM_HASHVALUES; i++)
+    old_board_hash.hashval[i] = board_hash.hashval[i];
+
   /* Treat the attack differently depending on how many liberties the 
      string at (str) has. */
   if (liberties == 1)
@@ -3209,6 +3229,7 @@
     result = attack4(str, &xpos);
 
 
+  ASSERT1(hashdata_is_equal(old_board_hash, board_hash), str);
   ASSERT1(result >= 0 && result <= WIN, str);
   
   if (result) {






reply via email to

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