|
|
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 a
Length: 5359 (0x14ef)
Types: TextFile
Names: »avg.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Cubes/avg.c«
/* 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);
}