aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Recipe4
-rw-r--r--cube.c6
-rw-r--r--fifteen.c6
-rw-r--r--gtk.c6
-rw-r--r--midend.c11
-rw-r--r--misc.c17
-rw-r--r--net.c4
-rw-r--r--nullgame.c2
-rw-r--r--puzzles.h6
-rw-r--r--random.c10
-rw-r--r--sixteen.c4
-rw-r--r--windows.c8
12 files changed, 39 insertions, 45 deletions
diff --git a/Recipe b/Recipe
index a2a5bfc..9d7c1e9 100644
--- a/Recipe
+++ b/Recipe
@@ -13,8 +13,8 @@
!makefile cygwin Makefile.cyg
WINDOWS = windows user32.lib gdi32.lib comctl32.lib
-COMMON = midend misc malloc
-NET = net random tree234
+COMMON = midend misc malloc random
+NET = net tree234
net : [X] gtk COMMON NET
cube : [X] gtk COMMON cube
diff --git a/cube.c b/cube.c
index 6c2658f..ccc8689 100644
--- a/cube.c
+++ b/cube.c
@@ -560,7 +560,7 @@ static void classify_grid_square_callback(void *ctx, struct grid_square *sq)
data->squareindex++;
}
-char *new_game_seed(game_params *params)
+char *new_game_seed(game_params *params, random_state *rs)
{
struct grid_data data;
int i, j, k, m, area, facesperclass;
@@ -605,7 +605,7 @@ char *new_game_seed(game_params *params)
for (i = 0; i < data.nclasses; i++) {
for (j = 0; j < facesperclass; j++) {
- int n = rand_upto(data.nsquares[i]);
+ int n = random_upto(rs, data.nsquares[i]);
assert(!flags[data.gridptrs[i][n]]);
flags[data.gridptrs[i][n]] = TRUE;
@@ -653,7 +653,7 @@ char *new_game_seed(game_params *params)
/*
* Choose a non-blue square for the polyhedron.
*/
- sprintf(p, ":%d", data.gridptrs[0][rand_upto(m)]);
+ sprintf(p, ":%d", data.gridptrs[0][random_upto(rs, m)]);
sfree(data.gridptrs[0]);
sfree(flags);
diff --git a/fifteen.c b/fifteen.c
index 74fd4fc..3965844 100644
--- a/fifteen.c
+++ b/fifteen.c
@@ -131,7 +131,7 @@ int perm_parity(int *perm, int n)
return ret;
}
-char *new_game_seed(game_params *params)
+char *new_game_seed(game_params *params, random_state *rs)
{
int gap, n, i, x;
int x1, x2, p1, p2, parity;
@@ -149,7 +149,7 @@ char *new_game_seed(game_params *params)
used[i] = FALSE;
}
- gap = rand_upto(n);
+ gap = random_upto(rs, n);
tiles[gap] = 0;
used[0] = TRUE;
@@ -157,7 +157,7 @@ char *new_game_seed(game_params *params)
* Place everything else except the last two tiles.
*/
for (x = 0, i = n-1; i > 2; i--) {
- int k = rand_upto(i);
+ int k = random_upto(rs, i);
int j;
for (j = 0; j < n; j++)
diff --git a/gtk.c b/gtk.c
index 6906f6c..5cbdbe4 100644
--- a/gtk.c
+++ b/gtk.c
@@ -688,10 +688,12 @@ static frontend *new_window(void)
GtkBox *vbox;
GtkWidget *menubar, *menu, *menuitem;
int x, y, n;
+ time_t t;
fe = snew(frontend);
- fe->me = midend_new(fe);
+ time(&t);
+ fe->me = midend_new(fe, &t, sizeof(t));
midend_new_game(fe->me);
fe->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -855,8 +857,6 @@ static frontend *new_window(void)
int main(int argc, char **argv)
{
- srand(time(NULL));
-
gtk_init(&argc, &argv);
(void) new_window();
gtk_main();
diff --git a/midend.c b/midend.c
index 818b278..cacd66e 100644
--- a/midend.c
+++ b/midend.c
@@ -13,6 +13,8 @@
struct midend_data {
frontend *frontend;
+ random_state *random;
+
char *seed;
int fresh_seed;
int nstates, statesize, statepos;
@@ -36,11 +38,12 @@ struct midend_data {
} \
} while (0)
-midend_data *midend_new(frontend *frontend)
+midend_data *midend_new(frontend *fe, void *randseed, int randseedsize)
{
midend_data *me = snew(midend_data);
- me->frontend = frontend;
+ me->frontend = fe;
+ me->random = random_init(randseed, randseedsize);
me->nstates = me->statesize = me->statepos = 0;
me->states = NULL;
me->params = default_params();
@@ -88,7 +91,7 @@ void midend_new_game(midend_data *me)
if (!me->fresh_seed) {
sfree(me->seed);
- me->seed = new_game_seed(me->params);
+ me->seed = new_game_seed(me->params, me->random);
} else
me->fresh_seed = FALSE;
@@ -252,7 +255,7 @@ float *midend_colours(midend_data *me, int *ncolours)
float *ret;
if (me->nstates == 0) {
- char *seed = new_game_seed(me->params);
+ char *seed = new_game_seed(me->params, me->random);
state = new_game(me->params, seed);
sfree(seed);
} else
diff --git a/misc.c b/misc.c
index 48088da..73b9a7b 100644
--- a/misc.c
+++ b/misc.c
@@ -7,23 +7,6 @@
#include "puzzles.h"
-int rand_upto(int limit)
-{
- unsigned long divisor = RAND_MAX / (unsigned)limit;
- unsigned long max = divisor * (unsigned)limit;
- unsigned long n;
-
- assert(limit > 0);
-
- do {
- n = rand();
- } while (n >= max);
-
- n /= divisor;
-
- return (int)n;
-}
-
void free_cfg(config_item *cfg)
{
config_item *i;
diff --git a/net.c b/net.c
index cf3fe3d..8b74e7b 100644
--- a/net.c
+++ b/net.c
@@ -254,7 +254,7 @@ char *validate_params(game_params *params)
* Randomly select a new game seed.
*/
-char *new_game_seed(game_params *params)
+char *new_game_seed(game_params *params, random_state *rs)
{
/*
* The full description of a Net game is far too large to
@@ -268,7 +268,7 @@ char *new_game_seed(game_params *params)
* understand it and do something completely different.)
*/
char buf[40];
- sprintf(buf, "%d", rand());
+ sprintf(buf, "%lu", random_bits(rs, 32));
return dupstr(buf);
}
diff --git a/nullgame.c b/nullgame.c
index bc0c386..8df09e9 100644
--- a/nullgame.c
+++ b/nullgame.c
@@ -76,7 +76,7 @@ char *validate_params(game_params *params)
return NULL;
}
-char *new_game_seed(game_params *params)
+char *new_game_seed(game_params *params, random_state *rs)
{
return dupstr("FIXME");
}
diff --git a/puzzles.h b/puzzles.h
index 10250a0..035ff24 100644
--- a/puzzles.h
+++ b/puzzles.h
@@ -103,7 +103,7 @@ void status_bar(frontend *fe, char *text);
/*
* midend.c
*/
-midend_data *midend_new(frontend *fe);
+midend_data *midend_new(frontend *fe, void *randseed, int randseedsize);
void midend_free(midend_data *me);
void midend_set_params(midend_data *me, game_params *params);
void midend_size(midend_data *me, int *x, int *y);
@@ -138,13 +138,13 @@ char *dupstr(char *s);
/*
* misc.c
*/
-int rand_upto(int limit);
void free_cfg(config_item *cfg);
/*
* random.c
*/
random_state *random_init(char *seed, int len);
+unsigned long random_bits(random_state *state, int bits);
unsigned long random_upto(random_state *state, unsigned long limit);
void random_free(random_state *state);
@@ -160,7 +160,7 @@ game_params *dup_params(game_params *params);
config_item *game_configure(game_params *params);
game_params *custom_params(config_item *cfg);
char *validate_params(game_params *params);
-char *new_game_seed(game_params *params);
+char *new_game_seed(game_params *params, random_state *rs);
char *validate_seed(game_params *params, char *seed);
game_state *new_game(game_params *params, char *seed);
game_state *dup_game(game_state *state);
diff --git a/random.c b/random.c
index e0a179e..664b11c 100644
--- a/random.c
+++ b/random.c
@@ -231,7 +231,7 @@ random_state *random_init(char *seed, int len)
unsigned long random_bits(random_state *state, int bits)
{
- int ret = 0;
+ unsigned long ret = 0;
int n;
for (n = 0; n < bits; n += 8) {
@@ -251,7 +251,13 @@ unsigned long random_bits(random_state *state, int bits)
ret = (ret << 8) | state->databuf[state->pos++];
}
- ret &= (1 << bits) - 1;
+ /*
+ * `(1 << bits) - 1' is not good enough, since if bits==32 on a
+ * 32-bit machine, behaviour is undefined and Intel has a nasty
+ * habit of shifting left by zero instead. We'll shift by
+ * bits-1 and then separately shift by one.
+ */
+ ret &= (1 << (bits-1)) * 2 - 1;
return ret;
}
diff --git a/sixteen.c b/sixteen.c
index 78bd851..f0acff5 100644
--- a/sixteen.c
+++ b/sixteen.c
@@ -151,7 +151,7 @@ int perm_parity(int *perm, int n)
return ret;
}
-char *new_game_seed(game_params *params)
+char *new_game_seed(game_params *params, random_state *rs)
{
int stop, n, i, x;
int x1, x2, p1, p2;
@@ -181,7 +181,7 @@ char *new_game_seed(game_params *params)
* Place everything except (possibly) the last two tiles.
*/
for (x = 0, i = n; i > stop; i--) {
- int k = i > 1 ? rand_upto(i) : 0;
+ int k = i > 1 ? random_upto(rs, i) : 0;
int j;
for (j = 0; j < n; j++)
diff --git a/windows.c b/windows.c
index 8fbcf8e..87f4284 100644
--- a/windows.c
+++ b/windows.c
@@ -311,9 +311,13 @@ static frontend *new_window(HINSTANCE inst)
int x, y;
RECT r, sr;
HDC hdc;
+ time_t t;
fe = snew(frontend);
- fe->me = midend_new(fe);
+
+ time(&t);
+ fe->me = midend_new(fe, &t, sizeof(t));
+
fe->inst = inst;
midend_new_game(fe->me);
midend_size(fe->me, &x, &y);
@@ -950,8 +954,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
{
MSG msg;
- srand(time(NULL));
-
InitCommonControls();
if (!prev) {