Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!husc6!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request
From: games-request@tekred.TEK.COM
Newsgroups: comp.sources.games
Subject: v01i066:  roll - automatic dice roller
Message-ID: <1356@tekred.TEK.COM>
Date: Mon, 29-Jun-87 19:47:13 EDT
Article-I.D.: tekred.1356
Posted: Mon Jun 29 19:47:13 1987
Date-Received: Wed, 1-Jul-87 04:57:24 EDT
Expires: Wed, 29-Jul-87 19:45:54 EDT
Sender: billr@tekred.TEK.COM
Lines: 393
Approved: billr@tekred.TEK.COM

Submitted by: Bruce Holloway 
Comp.sources.games: Volume 1, Issue 66
Archive-name: roll

	[I haven't tried this, so you're on your own.  -br]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh README <<'END_OF_README'
XThe Ultimate Dice Roller! Should be transportable to most systems that
Xcan run 'C' and have the standard library.
X
XThis dice roller is random, even if the random number generator isn't very
Xrandom.
X
XUsage: (options included in braces):
X
Xroll {numrep@}{{bestroll,}numroll x}{{bestdice,}numdice d}{sides}
X
Xnumrep   [1]       = number of times to repeat the rolling sequence.
Xbestroll [numroll] = print the best "bestroll" rolls.
Xnumroll  [1]       = number of rolls to do.
Xbestdice [numdice] = use the "bestdice" highest rolling dice.
Xnumdice  [1]       = number of dice to use per roll.
Xsides    [100]     = number of sides on the dice.
X
XExamples:
X	roll
X		d100 = 65 
X	roll 6
X		d6 = 3 
X	roll 4d10
X		4d10 = 11 
X	roll 5,10d8
X		5,10d8 = 28 
X	roll 6x3d6
X		6x3d6 = 17 12 11 11 10 6 
X	roll 6x3,4d6
X		6x3,4d6 = 18 15 10 10 7 6 
X	roll 5,10x4d4
X		5,10x4d4 = 14 13 12 12 10 
X	roll 3@6,10x3,4d6
X		6,10x3,4d6 = 17 17 15 15 14 14 
X		6,10x3,4d6 = 18 15 15 15 14 14 
X		6,10x3,4d6 = 16 14 13 13 11 11 
X
END_OF_README
if test 985 -ne `wc -c Makefile <<'END_OF_Makefile'
X#	Makefile for ROLL
X#
X#	Comment out the BSD line if you're on System V
X#	Comment out the SYSV line if you're using Berkely Unix.
X
X# SYSTEM = -DSYSV
XSYSTEM = -DBSD
X
XCFLAGS = -O $(SYSTEM)
X
Xroll:	roll.c
X	cc -o roll $(CFLAGS) roll.c
END_OF_Makefile
if test 229 -ne `wc -c roll.c <<'END_OF_roll.c'
X/*****************************************************************************
X*	ROLL - Rolls dice - lots of them - and really randomly.
X*
X*
X*	Usage: (options included in braces):
X*
X*	roll {numrep@}{{bestroll,}numroll x}{{bestdice,}numdice d}{sides}
X*
X*	numrep   [1]       = number of times to repeat the rolling sequence.
X*	bestroll [numroll] = print the best "bestroll" rolls.
X*	numroll  [1]       = number of rolls to do.
X*	bestdice [numdice] = use the "bestdice" highest rolling dice.
X*	numdice  [1]       = number of dice to use per roll.
X*	sides    [100]     = number of sides on the dice.
X*
X*	Examples:
X*		roll
X*			d100 = 65 
X*		roll 6
X*			d6 = 3 
X*		roll 4d10
X*			4d10 = 11 
X*		roll 5,10d8
X*			5,10d8 = 28 
X*		roll 6x3d6
X*			6x3d6 = 17 12 11 11 10 6 
X*		roll 6x3,4d6
X*			6x3,4d6 = 18 15 10 10 7 6 
X*		roll 5,10x4d4
X*			5,10x4d4 = 14 13 12 12 10 
X*		roll 3@6,10x3,4d6
X*			6,10x3,4d6 = 17 17 15 15 14 14 
X*			6,10x3,4d6 = 18 15 15 15 14 14 
X*			6,10x3,4d6 = 16 14 13 13 11 11 
X******************************************************************************/
X
X#include 
X#include 
X
X#define	NUMREDUX	5
X
X#ifdef SYSV
X#define	index	strchr
X#define	rindex	strrchr
X#define	srandom	srand
X#define	random	rand
X#endif
X
Xextern char *index(), *rindex();
Xextern char *malloc();
Xextern void free();
X
Xint numroll = 1, bestroll = 1;		/* Number of rolls to roll and keep */
Xint numdice = 1, bestdice = 1;		/* Number of dice to roll and keep */
Xint sides = 100;			/* Number of sides on each die */
X
Xint *ar_rolls;				/* Array of rolls */
Xint *ar_dice;				/* Array of dice */
Xint *ar_side;				/* Array of side data */
X
Xchar *show();				/* Routine to format output */
X
Xchar iline[80];				/* To parse the roll */
Xchar aroll[80];				/* When rolls are repeated */
X
Xmain(acnt,avar)
Xint acnt;
Xchar *avar[];
X{
X    int i, j, k, val;
X    char *s, *s1;
X
X/*    if(acnt < 2){
X	printf("usage: roll {numroll x }{numdice d }{numsides}\n");
X	printf("\tExample: roll 100 ; roll 3d8 ; roll 6x3d8\n");
X	return;
X	}
X*/
X    srandom(time(0L));			/* Randomize */
X
X    if(acnt <= 1)			/* Default: Roll 1d100 */
X	roll("");
X    else
X	for(i=0; ++i < acnt;){		/* For each argument */
X	    s = avar[i];
X	    if(s1 = index(s,'@')){	/* Repeat the roll? */
X		*s1 = 0;
X		j = atoi(s);		/* Get repetition */
X		if(j < 1){
X		    printf("roll: Repetition count must be greater than zero.\n");
X		    return;
X		    }
X		s = s1+1;		/* Advance pointer past it */
X		}
X	    else j = 1;			/* Default: Only one time. */
X	    strcpy(aroll,s);		/* Save it. */
X	    while(j--){
X		strcpy(s,aroll);
X		roll(s);		/* Do the roll */
X		}
X	    }
X}
X
Xroll(inline)
Xchar *inline;
X{
X    int i, j, k, val, r;
X    char *s, *s1;
X
X    numroll = bestroll = bestdice = numdice = 1; /* Set defaults. */
X    sides = 100;
X
X    for(s=inline; *s; ++s)			/* Convert to lower case */
X	if(isupper(*s))
X	    *s = tolower(*s);
X
X    s = inline;
X    if(s1 = index(s,'x')){			/* Get number of rolls */
X	*s1 = 0;
X	parse(s,&numroll,&bestroll);
X	s = s1+1;
X	}
X    if(s1 = index(s,'d')){			/* Get number of dice */
X	*s1 = 0;
X	parse(s,&numdice,&bestdice);
X	s = s1+1;
X	}
X    if(*s) sides = atoi(s);			/* get number of sides */
X
X    if(error()) return;				/* Check sanity */
X
X    if(numroll > 1) printf("%sx",show(iline,bestroll,numroll));
X    if(numdice > 1) printf("%s",show(iline,bestdice,numdice));
X    printf("d%d = ",sides);
X    fflush(stdout);				/* Echo the command */
X
X/* Allocate the arrays - one to keep all the rolls, one to keep each roll
X   by the die roll, and one to make sure the dice are rolled RANDOMLY.
X*/
X    ar_rolls = (int *)malloc(sizeof(int) * numroll);
X    ar_dice = (int *)malloc(sizeof(int) * numdice);
X    ar_side = (int *)malloc(sizeof(int) * NUMREDUX * sides);
X
X/* Get out if we couldn't allocate the arrays */
X
X    if(!ar_rolls || !ar_dice || !ar_side){
X	printf("*** Out of memory ***\n");
X	if(ar_rolls) free(ar_rolls);
X	if(ar_dice) free(ar_dice);
X	if(ar_side) free(ar_side);
X	return;
X	}
X
X/* Make an array filled with the possible side values. Several times. So
X   that even if the random number generator isn't completely random, it
X   has a chance to produce random values when indexing into the array.
X*/
X    for(i=j=0; i numroll){
X	fprintf(stderr,"roll: Number of rolls to keep must be greater than zero,\n");
X	fprintf(stderr,"      less than the total number of rolls.\n");
X	++iserr;
X	}
X
X    if(numdice <= 0){
X	fprintf(stderr,"roll: Number of dice to roll must be greater than zero.\n");
X	++iserr;
X	}
X
X    if(bestdice < 1 || bestdice > numdice){
X	fprintf(stderr,"roll: Number of dice to keep must be greater than zero,\n");
X	fprintf(stderr,"      less than the number of dice.\n");
X	++iserr;
X	}
X
X    if(sides <= 1){
X	fprintf(stderr,"roll: Dice must have at least two sides.\n");
X	++iserr;
X	}
X
X    return(iserr);
X}
X
X/*****************************************************************************
X*	SHOW
X*
X*	Format some output.
X******************************************************************************/
X
Xchar *show(s,b,n)
Xchar *s;
Xint b, n;
X{
X    if(b == n)
X	sprintf(s,"%d",n);
X    else
X	sprintf(s,"%d,%d",b,n);
X    return(s);
X}
END_OF_roll.c
if test 7305 -ne `wc -c