/* Monte Carlo simulation of Baby Blackjack for CPSC 641 */ /* */ /* Written by Carey Williamson, University of Calgary */ /* */ /* Usage: cc -o baby baby.c */ /* ./baby */ #include #include #include #define NUMGAMES 10 /* Number of games to simulate */ #define WAGER 1 /* Fixed wager amount on each play */ #define WIN_VALUE 2 /* Amount you win if successful */ /* #define SINGLE 1 /* Single deck dealer */ /* Set the Blackjack parameters */ #define TARGET 7 #define THRESHOLD 5 /* Constrain the deck size */ #define LOW_RANK 1 #define HIGH_RANK 3 #define RANKS (HIGH_RANK - LOW_RANK + 1) /* Debugging output */ #define DEBUG 1 /* Global variable */ static int dealt[RANKS*4]; /***********************************************************************/ /* RANDOM NUMBER GENERATION STUFF */ /***********************************************************************/ /* Parameters for random number generation. */ #define MAX_INT 2147483647 /* Maximum positive integer 2^31 - 1 */ /* Generate a random floating point value uniformly distributed in [0,1] */ float Uniform01() { float randnum; /* get a random positive integer from random() */ randnum = (float) 1.0 * random(); /* divide by max int to get something in 0..1 */ randnum = (float) randnum / (1.0 * MAX_INT); return( randnum ); } /* Generate a random integer uniformly distributed in [low,high] */ int EquiLikely(low, high) int low, high; { float randnum; int answer; randnum = Uniform01(); answer = low + randnum*(high-low+1); #ifdef DEBUG printf("EquiLikely(%d,%d) uses %8.6f to return %d\n", low, high, randnum, answer); #endif return( answer ); } /* Deal a card at random from an infinite set of shuffled decks */ int DrawCardFromInfiniteDeckDealer() { int card, suit, rank; char rankchar; char suitstring[10]; card = EquiLikely(0,RANKS*4-1); suit = card / RANKS; if( suit == 0 ) strcpy(suitstring, "Clubs"); else if( suit == 1 ) strcpy(suitstring, "Diamonds"); else if( suit == 2 ) strcpy(suitstring, "Hearts"); else if( suit == 3 ) strcpy(suitstring, "Spades"); else strcpy(suitstring, "Unknown?"); rank = card % RANKS; if( rank == 0 ) rankchar = 'A'; else if( rank == 10 ) rankchar = 'J'; else if( rank == 11 ) rankchar = 'Q'; else if( rank == 12 ) rankchar = 'K'; else rankchar = '1' + rank; #ifdef DEBUG if( rank == 9 ) printf("Card from dealer is the 10 of %s\n", suitstring); else printf("Card from dealer is the %c of %s\n", rankchar, suitstring); #endif return( card ); } /* Deal a card at random from a single shuffled deck */ int DrawCardFromSingleDeckDealer() { int card, suit, rank; char rankchar; char suitstring[10]; card = EquiLikely(0,RANKS*4-1); while( dealt[card] > 0 ) { #ifdef DEBUG printf("Sorry, but I can't use that one. Drawing another card...\n"); #endif card = EquiLikely(0,RANKS*4-1); } dealt[card]++; suit = card / RANKS; if( suit == 0 ) strcpy(suitstring, "Clubs"); else if( suit == 1 ) strcpy(suitstring, "Diamonds"); else if( suit == 2 ) strcpy(suitstring, "Hearts"); else if( suit == 3 ) strcpy(suitstring, "Spades"); else strcpy(suitstring, "Unknown?"); rank = card % RANKS; if( rank == 0 ) rankchar = 'A'; else if( rank == 10 ) rankchar = 'J'; else if( rank == 11 ) rankchar = 'Q'; else if( rank == 12 ) rankchar = 'K'; else rankchar = '1' + rank; #ifdef DEBUG if( rank == 9 ) printf("Card from dealer is the 10 of %s\n", suitstring); else printf("Card from dealer is the %c of %s\n", rankchar, suitstring); #endif return( card ); } /***********************************************************************/ /* MAIN PROGRAM */ /***********************************************************************/ int main() { int i, games, wins, ties, losses, card, winnings; int mysum, dealersum; int myhist[THRESHOLD+RANKS+1], dhist[THRESHOLD+RANKS+1]; /* Initialization */ srandom(1234567); games = 0; wins = 0; ties = 0; losses = 0; winnings = 0; for( i = 0; i <= THRESHOLD+RANKS; i++ ) { myhist[i] = 0; dhist[i] = 0; } while( games < NUMGAMES ) { #ifdef SINGLE for( i = 0; i < RANKS*4; i++ ) dealt[i] = 0; #endif mysum = 0; while( mysum <= THRESHOLD ) { #ifdef SINGLE card = DrawCardFromSingleDeckDealer(); #else card = DrawCardFromInfiniteDeckDealer(); #endif if( (card % RANKS) > 9 ) card = 9; mysum += (card % RANKS) + 1; } #ifdef DEBUG printf("My hand: %d\n", mysum); #endif myhist[mysum]++; dealersum = 0; while( dealersum <= THRESHOLD ) { #ifdef SINGLE card = DrawCardFromSingleDeckDealer(); #else card = DrawCardFromInfiniteDeckDealer(); #endif if( (card % RANKS) > 9 ) card = 9; dealersum += (card % RANKS) + 1; } dhist[dealersum]++; #ifdef DEBUG printf("Dealer hand: %d\n", dealersum); #endif /* check outcome of game */ if( mysum > TARGET ) { #ifdef DEBUG printf("Loser!\n"); #endif losses++; } else if( dealersum > TARGET ) { #ifdef DEBUG printf("Winner!\n"); #endif wins++; winnings += WIN_VALUE; } else if( mysum > dealersum ) { #ifdef DEBUG printf("Winner!\n"); #endif wins++; winnings += WIN_VALUE; } else if( mysum == dealersum ) { #ifdef DEBUG printf("TIE!\n"); #endif ties++; winnings += WIN_VALUE/2; } else { #ifdef DEBUG printf("Loser!\n"); #endif losses++; } games++; } printf("\n"); printf("Casino Card Game: Baby Blackjack\n"); printf("Number of trials: %d\n", NUMGAMES); printf("Number of wins: %d\n", wins); printf("Number of ties: %d\n", ties); printf("Number of losses: %d\n", losses); printf("Estimated probability of winning: %8.6f\n", 1.0*wins/games); printf("Amount wagered: %d\n", games*WAGER); printf("Amount won: %d\n", winnings); printf("Estimated winnings per play: %8.6f\n", (1.0*winnings - games)/games); printf("Statistical summary of hands:\nSum Player Dealer\n"); for( i = 0; i <= THRESHOLD+RANKS; i++ ) printf(" %d : %d %d\n", i, myhist[i], dhist[i]); }