gnugo-devel
[Top][All Lists]
Advanced

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

Re: [gnugo-devel] arend_1_30.2: random seed in crash report


From: Gunnar Farneback
Subject: Re: [gnugo-devel] arend_1_30.2: random seed in crash report
Date: Sat, 30 Mar 2002 12:25:39 +0100
User-agent: EMH/1.14.1 SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.3 Emacs/20.7 (sparc-sun-solaris2.7) (with unibyte mode)

Arend wrote:
>  - "stepped on a bug" message now reports random seed
>  
> I don't think there is more to say about this patch.

The solution of storing the last seed used in a call to gg_srand()
within the random number generator is not so good. For example, if we
should decide to use fixed "random" numbers for the Zobrist hashing,
as is today already done when TRACE_READ_RESULTS is set to 1 (see
hash.c line 93), the wrong seed may be reported. Besides, I really
don't think it's good design to add such a function to random.c. If
the caller wants to remember how it called gg_srand(), it should do
that itself.

The appended patch instead moves the random seed out from the gameinfo
struct and makes it a global variable. I know some people may find
this backwards, but in my opinion it's a better solution.

The patch also changes the use of randomness so that only the random
seed determines which random numbers are used in the move generation.
In the current code, the random seed _plus_ the number of previously
generated moves, affected the random numbers. Clearly the current
behaviour is worse for reproducability. Some people may worry that the
change makes the games less varied than before, but that is not the
case. Hmm, unless multiple games are played in the same GTP session.
That can be solved but has to wait for another patch.

- seed field removed from Gameinfo struct
- new global variable random_seed
- same set of random number used for all moves generated in the same game
- doc revision

/Gunnar

Index: doc/api.texi
===================================================================
RCS file: /cvsroot/gnugo/gnugo/doc/api.texi,v
retrieving revision 1.7
diff -u -r1.7 api.texi
--- doc/api.texi        20 Mar 2002 20:55:30 -0000      1.7
+++ doc/api.texi        30 Mar 2002 10:52:20 -0000
@@ -356,7 +356,6 @@
   int       to_move;            /* whose move it currently is */
   SGFTree   game_record;        /* Game record in sgf format. */
 
-  int       seed;               /* random seed */
   int       computer_player;    /* BLACK, WHITE, or EMPTY (used as BOTH) */
 
   char      outfilename[128];   /* Trickle file */
@@ -373,14 +372,8 @@
 game, including a header node which contains, among other things, komi
 and handicap.
 
-If one or both of the opponents is the computer, the fields @code{seed}
-and @code{computer_player} are used. Otherwise they can be
-ignored. @code{seed} is used to store the number used to seed the random
-number generator. Given the same moves from the opponent, GNU Go will
-try to vary its game somewhat using a random function. But if the random
-generator is given the same seed, GNU Go will always play the same
-move. This is good, e.g. when we debug the engine but could also be used
-for other purposes.
+If one or both of the opponents is the computer, the field
address@hidden is used. Otherwise it can be ignored.
 
 GNU Go can use a trickle file to continuously save all the moves of an
 ongoing game. This file can also contain information about internal
Index: engine/globals.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/globals.c,v
retrieving revision 1.23
diff -u -r1.23 globals.c
--- engine/globals.c    22 Mar 2002 08:18:32 -0000      1.23
+++ engine/globals.c    30 Mar 2002 10:52:21 -0000
@@ -102,6 +102,7 @@
 int count_variations = 0;  /* used by decide_string */
 int sgf_dump         = 0;  /* used by decide_string */
 SGFTree *sgf_dumptree = NULL;
+int random_seed      = 0;  /* random seed */
 int loading          = 0;  /* TRUE if last loaded move comes from file */
 int life             = 0;  /* use eye reading code */
 int life_eyesize     = 0;  /* max eyesize for life code */
Index: engine/gnugo.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/gnugo.h,v
retrieving revision 1.48
diff -u -r1.48 gnugo.h
--- engine/gnugo.h      22 Mar 2002 08:18:32 -0000      1.48
+++ engine/gnugo.h      30 Mar 2002 10:52:21 -0000
@@ -162,7 +162,6 @@
   int       to_move;           /* whose move it currently is */
   SGFTree   game_record;       /* Game record in sgf format. */
 
-  int       seed;              /* random seed */
   int       computer_player;   /* BLACK, WHITE, or EMPTY (used as BOTH) */
 
   char      outfilename[128];  /* Trickle file */
@@ -183,6 +182,8 @@
 /*                           global variables                       */
 /* ================================================================ */
 
+/* Random seed */
+extern int random_seed;
 
 /* Miscellaneous debug options. */
 extern int quiet;              /* Minimal output. */
Index: engine/interface.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/interface.c,v
retrieving revision 1.16
diff -u -r1.16 interface.c
--- engine/interface.c  10 Mar 2002 14:05:07 -0000      1.16
+++ engine/interface.c  30 Mar 2002 10:52:21 -0000
@@ -385,7 +385,6 @@
   sgftree_clear(&ginfo->game_record);
 
   /* Info relevant to the computer player. */
-  ginfo->seed = 0;
   ginfo->computer_player = WHITE; /* Make an assumption. */
 
   ginfo->outfilename[0] = '\0';
Index: engine/move_reasons.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.c,v
retrieving revision 1.72
diff -u -r1.72 move_reasons.c
--- engine/move_reasons.c       25 Mar 2002 07:39:18 -0000      1.72
+++ engine/move_reasons.c       30 Mar 2002 10:52:21 -0000
@@ -103,6 +103,19 @@
   next_all = 0;
   next_eye = 0;
   next_lunch = 0;
+
+  /* To improve the reproducability of games, we restart the random
+   * number generator with the same seed for each move. Thus we don't
+   * have to know how many previous moves have been played, nor
+   * actually play through them, in order to get the right random
+   * numbers.
+   *
+   * Comment: This means we could set these numbers only once instead
+   *          of before each move. It's probably not worth the minor
+   *          increase in code complexity to split off this
+   *          initialization, though.
+   */
+  gg_srand(random_seed);
   
   for (i = 0; i < board_size; i++)
     for (j = 0; j < board_size; j++) {
Index: engine/printutils.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/printutils.c,v
retrieving revision 1.21
diff -u -r1.21 printutils.c
--- engine/printutils.c 25 Mar 2002 07:39:18 -0000      1.21
+++ engine/printutils.c 30 Mar 2002 10:52:21 -0000
@@ -251,13 +251,13 @@
 
 #if 0
   if (sgf_root) {
-    /* FIXME: How should we get seed and komi in here? */
-    sgf_write_header(sgf_root, 1, 0, 0.0);
+    sgf_write_header(sgf_root, 1, random_seed, komi, level);
     writesgf(sgf_root, "abortgo.sgf");
   }
 #endif
 
-  fprintf(stderr, "\ngnugo %s: You stepped on a bug.\n", gg_version());
+  fprintf(stderr, "\ngnugo %s (seed %d): You stepped on a bug.\n",
+          gg_version(), random_seed);
   if (board_size >= 9 && board_size <= 19) {
     fprintf(stderr, "\
 Please save this game as an sgf file and mail it to address@hidden
Index: engine/sgffile.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/sgffile.c,v
retrieving revision 1.13
diff -u -r1.13 sgffile.c
--- engine/sgffile.c    7 Mar 2002 05:35:28 -0000       1.13
+++ engine/sgffile.c    30 Mar 2002 10:52:22 -0000
@@ -205,7 +205,7 @@
   fprintf(sgfout, "HA[%d]", ginfo->handicap);
   fprintf(sgfout, "KM[%.1f]", komi);
   fprintf(sgfout, "GN[GNU Go %s %s ", VERSION, gametype);
-  fprintf(sgfout, "Random Seed %d", ginfo->seed);
+  fprintf(sgfout, "Random Seed %d", random_seed);
   fprintf(sgfout, "] ");
   fprintf(sgfout, "\n");
   
Index: interface/main.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/main.c,v
retrieving revision 1.35
diff -u -r1.35 main.c
--- interface/main.c    25 Mar 2002 04:47:27 -0000      1.35
+++ interface/main.c    30 Mar 2002 10:52:22 -0000
@@ -824,7 +824,7 @@
   if (!seed)
     seed = time(0);
   gg_srand(seed);
-  gameinfo.seed = seed;
+  random_seed = seed;
 
   
   /* Initialize the GNU Go engine. */
Index: interface/play_ascii.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/play_ascii.c,v
retrieving revision 1.15
diff -u -r1.15 play_ascii.c
--- interface/play_ascii.c      7 Mar 2002 05:35:28 -0000       1.15
+++ interface/play_ascii.c      30 Mar 2002 10:52:22 -0000
@@ -894,7 +894,7 @@
          if (tmpstring) {
            /* discard newline */
            tmpstring[strlen(tmpstring)-1] = 0;
-           sgf_write_header(sgftree.root, 1, gameinfo->seed, komi, level);
+           sgf_write_header(sgftree.root, 1, random_seed, komi, level);
            writesgf(sgftree.root, tmpstring);
            sgf_initialized = 0;
            printf("You may resume the game");
@@ -961,7 +961,7 @@
        if (tmpstring) {
          /* discard newline */
          tmpstring[strlen(tmpstring)-1] = 0;
-         sgf_write_header(sgftree.root, 1, gameinfo->seed, komi, level);
+         sgf_write_header(sgftree.root, 1, random_seed, komi, level);
          writesgf(sgftree.root, tmpstring);
            sgf_initialized = 0;
        }




reply via email to

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