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 a

⟦7f8ee62c4⟧ TextFile

    Length: 5359 (0x14ef)
    Types: TextFile
    Names: »avg.c«

Derivation

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

TextFile

/*	vi:set sw=4 ts=4: */
#ifndef	lint
static char	sccsid[] = "@(#)avg.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	<stdio.h>
#include	"cubes.h"

boolean			jokermode	= False;

extern int		optind;
extern int		opterr;
extern char	   *optarg;
extern long		atol();

#define	ROLLS		1000000L	/* one million trials */

enum t_c {
	T_AOK,		/* 5	/* all of a kind */
	T_STR,		/* 5	/* straight */
	T_ASMSTR,	/* 5	/* assembled straight */
	T_4OK1S,	/* 5	/* four of a kind w/ one single */
	T_SMSTR1S,	/* 5	/* small straight w/ one single */
	T_3OK2S,	/* 5	/* three of a kind w/ two singles */
	T_5S,		/* 5	/* five singles */
	T_4OK,		/* 4	/* four of a kind */
	T_SMSTR,	/* 4	/* small straight */
	T_3OK1S,	/* 4	/* three of a kind w/one single */
	T_4S,		/* 4	/* four singles */
	T_3OK,		/* 3	/* three of a kind */
	T_3S,		/* 3	/* three singles */
	T_2S,		/* 2	/* two singles */
	T_1S,		/* 1	/* one single */
	T_ZIP,		/* 0	/* nothing */
	T_SIZE
};

static char	   *t_name[]	= {
	"all of a kind",
	"straight",
	"assembled straight",
	"four of a kind w/ one single",
	"small straight w/ one single",
	"three of a kind w/ two singles",
	"five singles",
	"four of a kind",
	"small straight",
	"three of a kind w/one single",
	"four singles",
	"three of a kind",
	"three singles",
	"two singles",
	"one single",
	"nothing",
	""
};

main(ac, av)
char   *av[];
{
	register diceset   *pd;
	register enum t_c	t;
	register int		d, singles, c, r;
	diceset				dice;
	long				cnt[(int)T_SIZE];
	long				pts[(int)T_SIZE];
	long				tpts;
	long				rolls			= ROLLS;
	boolean				aces_are_fives	= False;
	int					haces			= 0;
	int					held			= 0;

	opterr = 0;
	while((c = getopt(ac, av, "jfa:h:r:")) >= 0) {
		switch(c) {
		case 'j':	/* toggle jokermode */
			jokermode = (jokermode == True) ? False : True;
			break;
		case 'f':	/* toggle aces_are_fives */
			aces_are_fives = aces_are_fives == True ? False : True;
			break;
		case 'a':	/* number of aces held */
			if((haces = atoi(optarg)) < 0 || haces >= NDICE) {
				fprintf(stderr,
					"avg: aces must be in range 0 to %d\n", NDICE-1);
				exit(1);
			}
			break;
		case 'h':	/* number of generic dice held */
			if((held = atoi(optarg)) < 0 || held >= NDICE) {
				fprintf(stderr,
					"avg: held must be in range 0 to %d\n", NDICE-1);
				exit(1);
			}
			break;
		case 'r':	/* number of trials */
			if((rolls = atol(optarg)) <= 0) {
				fprintf(stderr, "avg: rolls must be positive\n");
				exit(1);
			}
			break;
		default:
			fprintf(stderr,
				"usage -- avg [-j] [-r rolls] [[-f] -a aces] [-h held]\n");
			exit(1);
		}
	}

	if(haces + held >= NDICE) {
		fprintf(stderr, "avg: aces plus held must be less than %d\n", NDICE);
		exit(1);
	}

	/*
	**	Initialize.
	*/
	irandom();
	pd = &dice;
	for(c = 0;c < (int)T_SIZE;++c)
		cnt[c] = pts[c] = 0;

	/*
	**	Roll and tally.
	*/
	for(r = 0;r < rolls;++r) {
		initdice(pd);
		if(aces_are_fives == True) {
			for(d = 0;d < haces;++d) {
				pd->d_stat[d] = Held, pd->d_comb[d] = Previous;
				pd->d_face[d] = FIVE;
			}
		} else {
			for(d = 0;d < haces;++d) {
				pd->d_stat[d] = Held, pd->d_comb[d] = Previous;
				pd->d_face[d] = ACE;
			}
		}
		for(;d < haces + held;++d) {
			pd->d_stat[d] = Held, pd->d_comb[d] = Previous;
			pd->d_face[d] = BADFACE;
		}

		rolldice(pd);
		evaluate(pd);

		/*
		**	Count singles.
		*/
		switch(pd->d_best) {
		case All_of_a_kind:
		case Straight:
		case Asm_straight:
			singles = 0;
			break;
		default:
			for(singles = d = 0;d < NDICE;++d) {
				switch(pd->d_comb[d]) {
				case Ace:
				case Five:
				case Joker:
					++singles;
					break;
				default:
					break;
				}
			}
			break;
		}

		/*
		**	Figure out which tallied combination this is.
		*/
		switch(pd->d_best) {
		default:			continue;
		case Nothing:		t = T_ZIP; break;
		case All_of_a_kind:	t = T_AOK; break;
		case Straight:		t = T_STR; break;
		case Asm_straight:	t = T_ASMSTR; break;
		case Four_of_a_kind:t = singles ? T_4OK1S : T_4OK; break;
		case Small_straight:t = singles ? T_SMSTR1S : T_SMSTR; break;
		case Three_of_a_kind:
			switch(singles) {
			case 2: t = T_3OK2S; break;
			case 1: t = T_3OK1S; break;
			case 0: t = T_3OK; break;
			}
			break;
		case Ace:
		case Five:
		case Joker:
			switch(singles) {
			case 5:	t = T_5S; break;
			case 4:	t = T_4S; break;
			case 3:	t = T_3S; break;
			case 2:	t = T_2S; break;
			case 1:	t = T_1S; break;
			}
			break;
		}

		/*
		**	The value of d_pts_roll is taken as the expectation value of the roll.
		**	In the case of All_of_a_kind and Asm_straight, the value must be corrected
		**	by subtracting the value of previously held dice.
		*/
		scoredice(pd);
		if(t == T_AOK || t == T_ASMSTR)
			pd->d_pts_roll -= haces * (aces_are_fives==True ? P_FIVE : P_ACE);
		pts[(int)t] += pd->d_pts_roll;
		++cnt[(int)t];
	}

	/*
	**	Print a summary.
	*/
	tpts = 0;
	printf("%-40s %6s %6s %8s\n",
		jokermode==True ? "Combination (with Jokers)" : "Combination (no Jokers)",
		"Ptsper", "Expect", "Count");
	for(c = 0;c < (int)T_SIZE;++c) {
		if(cnt[c] != 0) {
			tpts += pts[c];
			printf("%-40s %6ld %6ld %8ld\n",
				t_name[c], pts[c] / cnt[c], pts[c] / rolls, cnt[c]);
		}
	}
	printf("%-40s %6s %6ld %8ld\n", "Total", "", tpts / rolls, rolls);

	exit(0);
}