|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 3095 (0xc17)
Types: TextFile
Names: »random.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Cubes/random.c«
/* vi:set sw=4 ts=4: */
#ifndef lint
static char sccsid[] = "@(#)random.c 5.1 (G.M. Paris) 89/01/22";
#endif lint
/*
**
** cubes 5.1 Copyright 1989 Gregory M. Paris
** Permission granted to redistribute on a no charge basis.
** All other rights are reserved.
**
*/
#include <sys/types.h>
#include <sys/time.h>
#include "cubes.h"
extern boolean jokermode;
extern char *initstate();
extern long random();
extern time_t time();
static long diestate[3][256 / sizeof(long)]; /* for die rolls */
static long numstate[256 / sizeof(long)]; /* for random numbers */
#define RANDOM() (int)((unsigned)random() >> 1) /* XXX: ensure non-neg? */
/*
** irandom: initialize random number generators
*/
irandom()
{
struct timeval tv;
struct timezone tz;
register unsigned n;
int nstate = 0;
/*
** Initialize first die rolling state.
*/
(void) gettimeofday(&tv, &tz);
n = (tv.tv_sec << 8) + ((unsigned)tv.tv_usec >> 8);
(void) initstate(n, diestate[nstate++], sizeof diestate[0]);
for(n %= 49;n != 0;--n)
(void) random();
/*
** Initialize random number state and second die rolling state.
*/
(void) gettimeofday(&tv, &tz);
n = ((tv.tv_sec << 16) | ((unsigned)tv.tv_usec >> 16)) + getpid();
(void) initstate(n, numstate, sizeof numstate);
for(n %= 17;n != 0;--n)
(void) random();
n = (unsigned)(random() + 1); /* using numstate */
(void) initstate(n, diestate[nstate++], sizeof diestate[0]);
for(n %= 13;n != 0;--n)
(void) random();
/*
** Initialize third die rolling state.
*/
(void) gettimeofday(&tv, &tz);
n = (tv.tv_sec << 4) ^ ((unsigned)tv.tv_usec >> 4);
(void) initstate(n, diestate[nstate++], sizeof diestate[0]);
for(n %= 27;n != 0;--n)
(void) random();
}
/*
** dieroll:
** if jokermode is true
** roll a trick six-sided die which may show a JOKER on
** any face every once in thirteen rolls
** else
** roll a regular six-sided die
*/
dieroll()
{
static which = 0;
#define THIRTEEN (2 * SIDES + 1)
/*
** We use three random number states for the dice because it turns out
** that the RNG is not good for producing random *strings* of numbers.
** This method does seem to increase randomness for the combinations
** involving three to five dice. Maybe we should use NDICE states,
** but how do we ensure that our seeds are different enough?
*/
(void) setstate(diestate[which++ % 3]);
if(jokermode == True) {
int s;
if((s = RANDOM() % THIRTEEN) == THIRTEEN - 1)
return JOKER;
return s % SIDES + 1;
}
return RANDOM() % SIDES + 1;
#undef THIRTEEN
}
/*
** randint: return a random integer from 1 to n
*/
randint(n)
{
if(n <= 1)
return 1;
(void) setstate(numstate);
return RANDOM() % n + 1;
}
/*
** hesitate: random hesitation in the range minv to maxv milliseconds
XXX No checking of arguments is done.
*/
hesitate(minv, maxv)
long minv, maxv;
{
long diff, t;
struct timeval tv;
if((diff = maxv - minv) <= 1)
t = minv;
else {
(void) setstate(numstate);
t = random() % diff + minv;
}
tv.tv_sec = t / 1000;
tv.tv_usec = (t % 1000) * 1000;
(void) select(32, NOSEL, NOSEL, NOSEL, &tv);
}