/* * Monte Carlo simulation of the bingo game, as found in Pickham and * Baccarat. This assumes the games are honest, that is, number * drawing is uncorrelated with everything else. * * Output consists of one line every 1<<20 games, giving * * number of games played * number of games won * winnings * for each of the seven possible payout amounts, in order highest * to lowest, the percentage of games winning that amount * total percentage of games won (the sum of the previous seven) * expected profit per token staked, per game * * The last number, for example, is positive, meaning the player can * expect to make "money" playing the game (in contrast to real casino * games). */ #include #include #include static int combosinit[][5] = { { 0, 1, 2, 3, 4 }, { 5, 6, 7, 8, 9 }, { 10, 11, 12, 13, 14 }, { 15, 16, 17, 18, 19 }, { 20, 21, 22, 23, 24 }, { 0, 5, 10, 15, 20 }, { 1, 6, 11, 16, 21 }, { 2, 7, 12, 17, 22 }, { 3, 8, 13, 18, 23 }, { 4, 9, 14, 19, 24 }, { 0, 6, 12, 18, 24 }, { 4, 8, 12, 16, 20 } }; #define NCOMB (sizeof(combosinit)/sizeof(combosinit[0])) typedef struct cell CELL; typedef struct combo COMBO; struct cell { int n; int filled; int ncombos; COMBO *combos[4]; } ; struct combo { int nfilled; CELL *cells[5]; } ; static CELL board[25]; static COMBO combos[NCOMB]; static unsigned int list[25]; static int nlist; static void init(void) { int i; int j; CELL *c; for (i=25-1;i>=0;i--) { c = &board[i]; c->n = i; c->ncombos = 0; } for (i=NCOMB-1;i>=0;i--) { for (j=0;j<5;j++) { c = &board[combosinit[i][j]]; c->combos[c->ncombos++] = &combos[i]; combos[i].cells[j] = c; } } } static int drawnumber(int cell) { CELL *b; COMBO *c; int i; b = &board[cell]; if (b->filled) abort(); b->filled = 1; for (i=b->ncombos-1;i>=0;i--) { c = b->combos[i]; if (++c->nfilled >= 5) return(1); } return(0); } static int picklist(void) { int x; int v; x = random() % nlist; v = list[x]; nlist --; if (x != nlist) list[x] = list[nlist]; return(v); } static int onegame(void) { int i; for (i=25-1;i>=0;i--) board[i].filled = 0; for (i=NCOMB-1;i>=0;i--) combos[i].nfilled = 0; for (i=25-1;i>=0;i--) list[i] = i; list[12] = 24; nlist = 24; if (drawnumber(12)) abort(); if (drawnumber(picklist())) abort(); if (drawnumber(picklist())) abort(); if (drawnumber(picklist())) abort(); if (drawnumber(picklist())) return(400); if (drawnumber(picklist())) return(200); if (drawnumber(picklist())) return(100); if (drawnumber(picklist())) return(50); if (drawnumber(picklist())) return(25); if (drawnumber(picklist())) return(10); if (drawnumber(picklist())) return(5); return(0); } int main(void); int main(void) { long long int winnings; long long int games; long long int wongames; long long int wincounts[7]; int v; init(); srandom(time(0)); games = 0; wongames = 0; winnings = 0; for (v=7-1;v>=0;v--) wincounts[v] = 0; while (1) { games ++; v = onegame(); winnings += v; switch (v) { case 400: wincounts[0] ++; break; case 200: wincounts[1] ++; break; case 100: wincounts[2] ++; break; case 50: wincounts[3] ++; break; case 25: wincounts[4] ++; break; case 10: wincounts[5] ++; break; case 5: wincounts[6] ++; break; } if (v) wongames ++; if (! (games & 1048575)) printf("%llu %llu %llu [%g %g %g %g %g %g %g] %g %g\n",games,wongames,winnings,(wincounts[0]*100.0)/games,(wincounts[1]*100.0)/games,(wincounts[2]*100.0)/games,(wincounts[3]*100.0)/games,(wincounts[4]*100.0)/games,(wincounts[5]*100.0)/games,(wincounts[6]*100.0)/games,(wongames*100)/(double)games,(winnings-games)/(double)games); } }