[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Patch: Re: [gnugo-devel] twogtp.py matches broken
From: |
Arend Bayer |
Subject: |
Patch: Re: [gnugo-devel] twogtp.py matches broken |
Date: |
Wed, 30 Apr 2003 22:15:58 +0200 (CEST) |
Dan wrote:
> Arend wrote:
>
> > Should we maybe save the random seed during a determinstic command,
> > and restore it afterwards? (There are currently 6 such commands.)
>
> This sounds like what we should do.
The patch below does that:
- global variable random_seed made private variable in gg_utils.c
- setting the random seed is now handled by separate functions in gg_utils.c
Saving the random seed and restoring them isn't quite as obvious as it
seems (or seemed to me at least):
This
int saved_random_seed = random_seed;
random_seed = 0;
do_something_fancy();
random_seed = saved_random_seed;
is _not_ sufficient. (One would need to call gg_srand(random_seed) too,
to be prepared for a possibly following update_random_seed() call.)
As I didn't want to deal with the complexity of
1. some places modifying random_seed
2. others calling gg_srand(random_seed)
3. and yet other places calling update_random_seed(),
I decided to only allow both 1. when also doing 2.
I.e. random_seed is now a private variable in gg_utils.c, that
can be set with set_random_seed(int). (which then does 1. and 2.)
Only 2. can be done by calling reuse_random_seed().
gg_utils.c seemed to be the only reasonable place for these helper
functions (utils.c is not possible).
Arend
Index: engine/genmove.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/genmove.c,v
retrieving revision 1.70
diff -u -p -r1.70 genmove.c
--- engine/genmove.c 21 Apr 2003 21:40:35 -0000 1.70
+++ engine/genmove.c 30 Apr 2003 20:02:59 -0000
@@ -73,7 +73,7 @@ reset_engine()
* actually play through them, in order to get the right random
* numbers.
*/
- gg_srand(random_seed);
+ reuse_random_seed();
/* Initialize things for hashing of positions. */
reading_cache_clear();
Index: engine/globals.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/globals.c,v
retrieving revision 1.44
diff -u -p -r1.44 globals.c
--- engine/globals.c 28 Apr 2003 17:45:04 -0000 1.44
+++ engine/globals.c 30 Apr 2003 20:02:59 -0000
@@ -102,7 +102,6 @@ int printboard = 0; /* print boa
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 fusekidb = 1; /* use fuseki database */
int disable_fuseki = 0; /* do not generate fuseki moves */
Index: engine/gnugo.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/gnugo.h,v
retrieving revision 1.93
diff -u -p -r1.93 gnugo.h
--- engine/gnugo.h 28 Apr 2003 17:45:04 -0000 1.93
+++ engine/gnugo.h 30 Apr 2003 20:03:00 -0000
@@ -45,7 +45,7 @@
/* interface.c */
/* Initialize the whole thing. Should be called once. */
-void init_gnugo(float memory);
+void init_gnugo(float memory, unsigned int random_seed);
/* ================================================================ */
@@ -193,8 +193,6 @@ int gameinfo_play_sgftree(Gameinfo *gam
/* 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.39
diff -u -p -r1.39 interface.c
--- engine/interface.c 18 Mar 2003 13:58:56 -0000 1.39
+++ engine/interface.c 30 Apr 2003 20:03:01 -0000
@@ -37,8 +37,9 @@
*/
void
-init_gnugo(float memory)
+init_gnugo(float memory, unsigned int seed)
{
+ set_random_seed(seed);
reading_cache_init(memory * 1024 * 1024);
clear_board();
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.164
diff -u -p -r1.164 liberty.h
--- engine/liberty.h 22 Apr 2003 02:48:04 -0000 1.164
+++ engine/liberty.h 30 Apr 2003 20:03:02 -0000
@@ -187,6 +187,9 @@ void start_timer(int n);
double time_report(int n, const char *occupation, int move, double mintime);
void update_random_seed(void);
+void set_random_seed(unsigned int seed);
+unsigned int get_random_seed(void);
+void reuse_random_seed(void);
/* Check for self atari. */
Index: engine/printutils.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/printutils.c,v
retrieving revision 1.34
diff -u -p -r1.34 printutils.c
--- engine/printutils.c 22 Apr 2003 02:48:05 -0000 1.34
+++ engine/printutils.c 30 Apr 2003 20:03:03 -0000
@@ -263,13 +263,14 @@ abortgo(const char *file, int line, cons
#if 0
if (sgf_root) {
- sgf_write_header(sgf_root, 1, random_seed, komi, level, chinese_rules);
+ sgf_write_header(sgf_root, 1, get_random_seed()
+ komi, level, chinese_rules);
writesgf(sgf_root, "abortgo.sgf");
}
#endif
fprintf(stderr, "\ngnugo %s (seed %d): You stepped on a bug.\n",
- gg_version(), random_seed);
+ gg_version(), get_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.25
diff -u -p -r1.25 sgffile.c
--- engine/sgffile.c 2 Jan 2003 00:23:29 -0000 1.25
+++ engine/sgffile.c 30 Apr 2003 20:03:03 -0000
@@ -163,7 +163,7 @@ sgffile_printsgf(int color_to_play, cons
sgftree_clear(&sgftree);
sgftreeCreateHeaderNode(&sgftree, board_size, relative_komi);
- sgf_write_header(sgftree.root, 1, random_seed, relative_komi,
+ sgf_write_header(sgftree.root, 1, get_random_seed(), relative_komi,
level, chinese_rules);
gg_snprintf(str, 128, "GNU Go %s load and print", gg_version());
sgfOverwriteProperty(sgftree.root, "GN", str);
Index: engine/utils.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/utils.c,v
retrieving revision 1.68
diff -u -p -r1.68 utils.c
--- engine/utils.c 28 Apr 2003 20:45:39 -0000 1.68
+++ engine/utils.c 30 Apr 2003 20:03:05 -0000
@@ -1924,19 +1924,6 @@ time_report(int n, const char *occupatio
return dt;
}
-/* Update the random seed with the current value in the random sequence. */
-void
-update_random_seed(void)
-{
- random_seed = gg_rand();
- /* Since random seed 0 has a special interpretation when given as
- * command line argument with the -r option, we make sure to avoid
- * it.
- */
- if (random_seed == 0)
- random_seed = 1;
-}
-
/*
* Local Variables:
Index: interface/main.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/main.c,v
retrieving revision 1.68
diff -u -p -r1.68 main.c
--- interface/main.c 26 Feb 2003 19:43:51 -0000 1.68
+++ interface/main.c 30 Apr 2003 20:03:07 -0000
@@ -904,14 +904,10 @@ main(int argc, char *argv[])
/* Start random number seed. */
if (!seed)
seed = time(0);
- gg_srand(seed);
- random_seed = seed;
-
/* Initialize the GNU Go engine. */
- init_gnugo(memory);
+ init_gnugo(memory, seed);
-
/* Read the infile if there is one. Also play up the position. */
if (infilename) {
if (!sgftree_readfile(&sgftree, infilename)) {
Index: interface/play_ascii.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/play_ascii.c,v
retrieving revision 1.38
diff -u -p -r1.38 play_ascii.c
--- interface/play_ascii.c 30 Mar 2003 12:09:32 -0000 1.38
+++ interface/play_ascii.c 30 Apr 2003 20:03:08 -0000
@@ -427,7 +427,8 @@ init_sgf(Gameinfo *ginfo)
return;
sgf_initialized = 1;
- sgf_write_header(sgftree.root, 1, random_seed, komi, level, chinese_rules);
+ sgf_write_header(sgftree.root, 1, get_random_seed(), komi,
+ level, chinese_rules);
sgfOverwritePropertyInt(sgftree.root, "HA", ginfo->handicap);
if (ginfo->handicap > 0)
gnugo_recordboard(sgftree.root);
Index: interface/play_gmp.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/play_gmp.c,v
retrieving revision 1.19
diff -u -p -r1.19 play_gmp.c
--- interface/play_gmp.c 18 Jan 2003 03:05:31 -0000 1.19
+++ interface/play_gmp.c 30 Apr 2003 20:03:08 -0000
@@ -121,7 +121,7 @@ play_gmp(Gameinfo *gameinfo)
}
gameinfo->computer_player = mycolor;
- sgf_write_header(sgftree.root, 1, random_seed, gnugo_get_komi(),
+ sgf_write_header(sgftree.root, 1, get_random_seed(), gnugo_get_komi(),
level, chinese_rules);
gameinfo->handicap = gnugo_sethand(gameinfo->handicap, sgftree.root);
sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap);
Index: interface/play_gtp.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/play_gtp.c,v
retrieving revision 1.115
diff -u -p -r1.115 play_gtp.c
--- interface/play_gtp.c 22 Apr 2003 02:48:05 -0000 1.115
+++ interface/play_gtp.c 30 Apr 2003 20:03:11 -0000
@@ -2144,6 +2144,7 @@ gtp_reg_genmove(char *s)
int i, j;
int color;
int n;
+ unsigned int saved_random_seed = get_random_seed();
n = gtp_decode_color(s, &color);
if (!n)
@@ -2157,9 +2158,11 @@ gtp_reg_genmove(char *s)
* number generator before calling genmove(). It is always seeded by
* 0.
*/
- random_seed = 0;
+ set_random_seed(0);
genmove_conservative(&i, &j, color);
+
+ set_random_seed(saved_random_seed);
gtp_start_response(GTP_SUCCESS);
gtp_print_vertex(i, j);
return gtp_finish_response();
@@ -2178,6 +2181,7 @@ gtp_gg_genmove(char *s)
int i, j;
int color;
int n;
+ unsigned int saved_random_seed = get_random_seed();
unsigned int seed;
n = gtp_decode_color(s, &color);
@@ -2195,9 +2199,10 @@ gtp_gg_genmove(char *s)
*/
seed = 0;
sscanf(s+n, "%u", &seed);
- random_seed = seed;
+ set_random_seed(seed);
genmove_conservative(&i, &j, color);
+ set_random_seed(saved_random_seed);
gtp_start_response(GTP_SUCCESS);
gtp_print_vertex(i, j);
return gtp_finish_response();
@@ -2216,6 +2221,7 @@ gtp_restricted_genmove(char *s)
int i, j;
int color;
int n;
+ unsigned int saved_random_seed = get_random_seed();
int allowed_moves[BOARDMAX];
int number_allowed_moves = 0;
memset(allowed_moves, 0, sizeof(allowed_moves));
@@ -2249,9 +2255,10 @@ gtp_restricted_genmove(char *s)
* number generator before calling genmove(). It is always seeded by
* 0.
*/
- random_seed = 0;
+ set_random_seed(0);
genmove_restricted(&i, &j, color, allowed_moves);
+ set_random_seed(saved_random_seed);
gtp_start_response(GTP_SUCCESS);
gtp_print_vertex(i, j);
return gtp_finish_response();
@@ -2581,6 +2588,7 @@ finish_and_score_game(int seed)
static int
gtp_final_score(char *s)
{
+ unsigned int saved_random_seed = get_random_seed();
int seed;
/* This is intended for regression purposes and should therefore be
* deterministic. The best way to ensure this is to reset the random
@@ -2590,10 +2598,12 @@ gtp_final_score(char *s)
*/
seed = 0;
sscanf(s, "%d", &seed);
- random_seed = seed;
+ set_random_seed(seed);
finish_and_score_game(seed);
+ set_random_seed(saved_random_seed);
+
gtp_start_response(GTP_SUCCESS);
if (final_score > 0.0)
gtp_printf("W+%3.1f", final_score);
@@ -2618,6 +2628,7 @@ gtp_final_status(char *s)
int n;
int ai, aj;
int k;
+ unsigned int saved_random_seed = get_random_seed();
const char *result = NULL;
n = gtp_decode_coord(s, &ai, &aj);
@@ -2632,10 +2643,11 @@ gtp_final_status(char *s)
*/
seed = 0;
sscanf(s + n, "%d", &seed);
- random_seed = seed;
+ set_random_seed(seed);
finish_and_score_game(seed);
+ set_random_seed(saved_random_seed);
for (k = 0; k < 6; k++)
if (final_status[ai][aj] == status_numbers[k]) {
result = status_names[k];
@@ -2670,6 +2682,7 @@ gtp_final_status_list(char *s)
int k;
char status_string[GTP_BUFSIZE];
int first;
+ unsigned int saved_random_seed = get_random_seed();
if (sscanf(s, "%s %n", status_string, &n) != 1)
return gtp_failure("missing status");
@@ -2690,10 +2703,12 @@ gtp_final_status_list(char *s)
*/
seed = 0;
sscanf(s + n, "%d", &seed);
- random_seed = seed;
+ set_random_seed(seed);
finish_and_score_game(seed);
+ set_random_seed(saved_random_seed);
+
gtp_start_response(GTP_SUCCESS);
first = 1;
@@ -3575,7 +3590,7 @@ static int
gtp_get_random_seed(char *s)
{
UNUSED(s);
- return gtp_success("%d", random_seed);
+ return gtp_success("%d", get_random_seed());
}
/* Function: Set the random seed
@@ -3590,7 +3605,7 @@ gtp_set_random_seed(char *s)
if (sscanf(s, "%d", &seed) < 1)
return gtp_failure("invalid seed");
- random_seed = seed;
+ set_random_seed(seed);
return gtp_success("");
}
Index: interface/play_solo.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/play_solo.c,v
retrieving revision 1.25
diff -u -p -r1.25 play_solo.c
--- interface/play_solo.c 15 Mar 2003 21:36:23 -0000 1.25
+++ interface/play_solo.c 30 Apr 2003 20:03:11 -0000
@@ -61,7 +61,8 @@ play_solo(Gameinfo *gameinfo, int moves)
sgftree_clear(&sgftree);
sgftreeCreateHeaderNode(&sgftree, gnugo_get_boardsize(), gnugo_get_komi());
- sgf_write_header(sgftree.root, 1, random_seed, 5.5, level, chinese_rules);
+ sgf_write_header(sgftree.root, 1, get_random_seed(), 5.5,
+ level, chinese_rules);
/* Generate some random moves. */
if (boardsize > 6) {
Index: utils/gg_utils.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/utils/gg_utils.c,v
retrieving revision 1.30
diff -u -p -r1.30 gg_utils.c
--- utils/gg_utils.c 22 Feb 2003 10:54:24 -0000 1.30
+++ utils/gg_utils.c 30 Apr 2003 20:03:14 -0000
@@ -25,6 +25,7 @@
#include <assert.h>
#include "gg_utils.h"
+#include "random.h"
#ifdef HAVE_GLIB_H
#include <glib.h>
@@ -504,6 +505,53 @@ inv_rotate(int i, int j, int *ri, int *r
rotate(i, j, ri, rj, bs, 1);
else
rotate(i, j, ri, rj, bs, rot);
+}
+
+
+/* Intermediate layer to random.c. gg_srand() should only be called via the
+ * functions below.
+ */
+
+/* Private variable remembering the random seed. */
+static unsigned int random_seed;
+
+unsigned int
+get_random_seed()
+{
+ return random_seed;
+}
+
+void
+set_random_seed(unsigned int seed)
+{
+ random_seed = seed;
+ gg_srand(seed);
+}
+
+/* Update the random seed with the current value in the random sequence.
+ * This should be called at the start of each new game.
+ */
+void
+update_random_seed(void)
+{
+ random_seed = gg_rand();
+ /* Since random seed 0 has a special interpretation when given as
+ * command line argument with the -r option, we make sure to avoid
+ * it.
+ */
+ if (random_seed == 0)
+ random_seed = 1;
+ gg_srand(random_seed);
+}
+
+
+/* Restart the pseudo-random sequence with the initialization given
+ * by the random seed. Should be called at each move.
+ */
+void
+reuse_random_seed()
+{
+ gg_srand(random_seed);
}