|
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); }