syd@dsinc.UUCP (Syd Weinstein) (02/13/88)
After playing mille for several weeks, I kept getting cards I thought the odds of getting were all wrong. I finally looked at card.c and determined the problem. Mille has a deck of 101 cards. Lets take the example of the roll card. There are 14 roll cards. As the first card is dealt, there is a 14/101 chance of it being a roll card. The way the card.c file works, this is correct as if a random number is between n and n+13, its a roll card. Then a count of roll cards is decremented and the game continues. However after this first card is dealt this algorithm is all wrong. Now there are 13 roll cards, the odds of the next card being a roll card are 13/100. (13 rolls left in 100 cards left). The program used the odds 14/100 as any random number in the range n..n+13 is still a roll card and then it decremented a roll card if one was left. This biases the deal heavily towards the roll cards and away from the lesser cards. It made it very difficult to get a hazard as the game went on and even more difficult to get a remedy for that hazard. I added a 'brute force' deal change to card. This fix makes the random selection be retried if that particular card number (0..100) has already been used. If so, I get another card. This makes the odds work out right as long as the number generator is really uniform. In this case it made the play much more like the real game and got rid of those often occurring 10 play shutouts that were happening. the patch in patch format is Index: card.c *** card.sav --- card.c ************** *** 47,52 /* */ /**********************************************************************/ /*********************************************************/ /* initilaizes a card_set structure with the card counts */ /*********************************************************/ --- 47,54 ----- /* */ /**********************************************************************/ + int deck_played[101]; + /*********************************************************/ /* initilaizes a card_set structure with the card counts */ /*********************************************************/ ************** *** 53,58 initialize_card_set (cards) int cards[20]; { cards[0] = 101; /* total cards */ cards[extra_tank] = 1; /* safeties */ cards[puncture_proof] = 1; --- 55,62 ----- initialize_card_set (cards) int cards[20]; { + int i, c, *pi; + cards[0] = 101; /* total cards */ cards[extra_tank] = 1; /* safeties */ cards[puncture_proof] = 1; ************** *** 73,79 cards[miles_75] = 10; cards[miles_50] = 10; cards[miles_25] = 10; - } /********************************************/ /* removes a card from the deck and returns */ --- 77,82 ----- cards[miles_75] = 10; cards[miles_50] = 10; cards[miles_25] = 10; pi = deck_played; for (c = 1; c < 20; c++) ************** *** 75,80 cards[miles_25] = 10; } /********************************************/ /* removes a card from the deck and returns */ /* card if it could, 0 if it couldn't */ --- 78,91 ----- cards[miles_50] = 10; cards[miles_25] = 10; + pi = deck_played; + for (c = 1; c < 20; c++) + { + for (i = cards[c]; --i >= 0; pi++) + *pi = 1; + } + } + /********************************************/ /* removes a card from the deck and returns */ /* card if it could, 0 if it couldn't */ ************** *** 99,104 int number; { number = number % 101; /* 0 - 100 */ if (number >= 28 && number <= 41) return(roll); if (number >= 59 && number <= 70) --- 110,118 ----- int number; { number = number % 101; /* 0 - 100 */ + if (!deck_played[number]) + return(-1); + deck_played[number] = 0; if (number >= 28 && number <= 41) return(roll); if (number >= 59 && number <= 70) ************** *** 149,155 deal_card () { int card; - int more_cards; int i; more_cards = FALSE; for (i=0; i<20; i++) --- 163,168 ----- deal_card () { int card; int i; if (deck[0]) { ************** *** 151,162 int card; int more_cards; int i; ! more_cards = FALSE; ! for (i=0; i<20; i++) ! if (deck[i] > 0) ! more_cards = TRUE; ! if (more_cards) ! while ((card = remove_card(&deck[0],get_card(rand()))) == 0) ; else card = 0; --- 164,172 ----- { int card; int i; ! if (deck[0]) ! { ! while ((card = get_card(rand())) < 0) ; card = remove_card(&deck[0],card); } ************** *** 158,163 if (more_cards) while ((card = remove_card(&deck[0],get_card(rand()))) == 0) ; else card = 0; return(card); --- 168,175 ----- { while ((card = get_card(rand())) < 0) ; + card = remove_card(&deck[0],card); + } else card = 0; return(card); -- ===================================================================== Sydney S. Weinstein, CDP, CCP Datacomp Systems, Inc. Voice: (215) 947-9900 {allegra,bellcore,bpa,vu-vlsi}!dsinc!syd FAX: (215) 938-0235