### Search

 Search WWW Search DelphiForFun.org

As of October, 2016, Embarcadero is offering a free release of Delphi (Delphi 10.1 Berlin Starter Edition ).     There are a few restrictions, but it is a welcome step toward making more programmers aware of the joys of Delphi.  They do say "Offer may be withdrawn at any time", so don't delay if you want to check it out.  Please use the feedback link to let me know if the link stops working.

Support DFF - Shop

If you shop at Amazon anyway,  consider using this link.

We receive a few cents from each purchase.  Thanks

### Support DFF - Donate

If you benefit from the website,  in terms of knowledge, entertainment value, or something otherwise useful, consider making a donation via PayPal  to help defray the costs.  (No PayPal account necessary to donate via credit card.)  Transaction is secure.

Mensa® Daily Puzzlers

For over 15 years Mensa Page-A-Day calendars have provided several puzzles a year for my programming pleasure.  Coding "solvers" is most fun, but many programs also allow user solving, convenient for "fill in the blanks" type.  Below are Amazon  links to the two most recent years.

(Hint: If you can wait, current year calendars are usually on sale in January.)

### Contact

 Search DelphiForFun.org only

### Problem Description

If I roll six dice, what is the probability that they will all show the same number on top?

### Background & Techniques

This program originated from a user inquiry about whether he was wasting his money on a dice game at his club.  The game is to throw six dice and win \$1,000 if all six show the same number.   It costs \$1 to to play three games (rolling all 6 dice each time).   A game is fair, i.e. you  break even "in the long run", if the odds of winning, stated as 1 in X tries on average, pays you X dollars for each dollar you spend.

If we imagine throwing one die at a time, the first die can show any value.  Thereafter the chance of matching that first number is 1/6 for each remaining die and the probability that all 5 will will show the same number is P =1/6 x 1/6 x 1/6 x 1/6 x 1 /6 =  0.000129.  The units for this number are "successes per trial".  The reciprocal of P, (1/P), therefore has units "trials per win".   In this case, 1/P = 7776 trials per win,  i.e. one win on average for every 7776 games played. If we paid \$1 per game we should win \$7776 each time we won in order to break even.  Since in this case  it costs 1/3 dollar per game, we should receive 7776/3 or  \$2592 for each win if we are to break even in the long run.  Players should realize that the phrase "in the long run" can reflect a very long run indeed.

The program included here calculates experimental as well as theoretical results.  On each click of the Six of a Kind button, it generates 1,000,000 sets of 6 random numbers representing 6  thrown dice and counts the number of times that all 6 results are the same.  These results as well as the theoretical results are displayed for each button click.  Version 2 also counts the shortest and longest strings of consecutive losses between wins and the maximum drawdown, maximum winning and final winnings after the million games.  The "drawdown" represents the capital required to to keep playing while waiting for that next win.

Our "Six of a Kind" case is presented as Case 2 of four cases that are analyzed by the program:

 Case 1: Chance of throwing six of a predetermined number, six "1"s for example. Case 2: Chance that all six dice show the same number, "Six of a Kind" Case 3: If we throw the dice one at a time, the chance that the results will be 1 ,2, 3, 4 ,5, and 6  in that order. Case 4: Chance that the dice show 1,2,3,4,5, and 6 in any order.

You have enough information to calculate the odds with a calculator before running the program if you choose.  I did and got one wrong. Case 4 initially seemed similar to Case 2; the probability of any number is 1/6 so it shouldn't matter if we are looking for 1's, 2's, or 3's, etc.  Well, in this case it does. , Luckily,  the experimental results made me rethink my theory to get the correct answer.

### Programmer's Notes:

The source code includes two versions of the program.  Version 1 has about 25 lines of code for each of the four cases with about half of them adding the output lines which display results.  We'll call it Beginners level and explain the code this way:

##### Version 1:

The theoretical results were calculated manually and are displayed with explanatory text for each case.  The experimental results are calculated within a loop running one million times playing one game within each game.  Each game contains a loop to throw the  dice as follows:

For Case 1, the odds of throwing six "1"'s, we set a Target variable to 0 and then use calls to Random(6) in a loop to generate 6 random numbers between 0 and 5.  Any number that does not = 0 is enough to set a flag (OK) to false and break out of the loop.  After the loop. if OK is True then we have a winner and add one to the wins counter (Hits).

Case 2 is nearly identical except that  the Target number is the value of the first Random(6) call so may be any number from  0 to 5.  What is important is that we now only need to loop 5 times to see if the next 5 dice match the first one.  Sure enough, the odds of winning this game are 6 times better than of winning the first game.

Case 3, rolling 1,2,3,4,5,6 in order, gets a little trickier; to succeed, in our loop to generate the 6 random dice values n , the Jth Random(6) call must return value J. Like this

For J := 0 to 5 do if Random(6)<>J then begin OK:=false; break; end;

Finally, for Case 4 we must keep track of what numbers are thrown so that we know that any duplicate number counts as a loss.  We'll initialize elements of a Boolean array, Found with 6 members [0..5] set to False, then check member Random(6) each time through the loop to see if it is already set to true. If it is, we have lost that game; if not, then set that member to True.  If we get to generate 6 random numbers without any duplicates, they must have been 0,1,2,3,4,5 in some order, so we have a winner.

##### Version 2:

Version 2 has two major changes

The code to display the results for all 4 cases was was moved to a common ShowResults procedure.  A new record type is initialized with the constant string values which apply to each case.
Additional counter fields were added to the experimental results to display  these new fields:
 Longest and shortest string of consecutive losses. Assuming a fair game (\$1 to play and payout = mean number of games per win), we report the total winnings or losses after the million games. Maximum drawdown (largest negative winnings) during the million games. Maximum cumulative winnings at any point during the million games.

The calculation for these fields as well as the number of wins is common to all cases and was implemented the in a new MarkGame procedure which is passed the OK (True or False) parameter and updates all fields accordingly.

An interesting note on currency formats for the dollar amounts displayed by Version 2..  The negative dollar amounts are  displayed by default  as accountants commonly do, enclosed in parentheses.  The global variable which controls this within Delphi is NegCurrFormat, a byte value, but there is no documentation about how the byte is interpreted.  A Web search on Locale_INegCurr will point to a Microsoft page that defines the possible values and their effect on  the display.  Byte value "1" replaces the parentheses with negative-sign currency-sign value, e.g. (\$100) becomes -\$100.  I set NegCurrFormat  to 1 in the FormActivate procedure to implement this change,

Version 2 is the only version included in the executable download but I've include both versions in the source download.