DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T r

⟦0f902871d⟧ TextFile

    Length: 3095 (0xc17)
    Types: TextFile
    Names: »random.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Cubes/random.c« 

TextFile

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