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