435,098 Members | 1,881 Online + Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,098 IT Pros & Developers. It's quick & easy.

dice rolling problem

 P: n/a Hello, I'm doing an exercise to simulate rolling a pair of dice 36,000 times, then count and display how many times the simulation rolls each possible sum. For some reason each time I run my simulation, one or more of my sums is zero, which is highly unlikely. So I'm sure there's a bug in my code. But I can't tell what it is, even after re-reading it several times. Can someone give me a hint? Here is my code: static void SimulateDiceRolls() { // When you roll two dice, there are 11 possible sums: // 2, 3, ..., 10, 11, 12. Define an array of 13 elements // where the first two elements are unused, but the third element // where index equals 2, corresponds to sum = 2, and so on. // make sure they're initialized to 0, which C# does by default int[] sum = new int; // for 36,000 times, roll two dice, calculate the sum, // and increment the index corresponding to that sum. int currentResult = 0; for (int numberOfRolls = 1; numberOfRolls <= 36000; ++numberOfRolls) { currentResult = RollTwoDice(); ++sum[currentResult]; } // print how many times each sum comes up and what percent of the time // to a 3 decimal precision that sum comes up for (int sumIndex = 2; sumIndex <= 12; ++sumIndex) { Console.WriteLine("{0,5} {1,5} {2:F3}", sumIndex, sum[sumIndex], (double)sum[sumIndex] / 36000 * 100); } } // return the sum of two randomly generated integers from 1 to 6 // inclusive static int RollTwoDice() { Random r = new Random(); return r.Next(1, 7) + r.Next(1, 7); } Thanks in advance, Jose Jan 5 '07 #1
17 Replies

 P: n/a I changed my code to the folllowing which fixes the problem. But I don't care about getting the program to work as much as I would like to know what I did wrong in my first example. Can anyone help explain what I did wrong in the code from my earlier post? Thanks! Working code: static void SimulateDiceRolls() { // When you roll two dice, there are 11 possible sums: // 2, 3, ..., 10, 11, 12. Define an array of 13 elements // where the first two elements are unused, but the third element // where index equals 2, corresponds to sum = 2, and so on. // make sure they're initialized to 0, which C# does by default int[] sum = new int; Random r = new Random(); // for 36,000 times, roll two dice, calculate the sum, // and increment the index corresponding to that sum. int currentResult = 0; for (int numberOfRolls = 1; numberOfRolls <= 36000; ++numberOfRolls) { currentResult += r.Next(1, 7); currentResult += r.Next(1, 7); ++sum[currentResult]; currentResult = 0; } // print how many times each sum comes up and what percent of the time // to a 2 decimal precision that sum comes up for (int sumIndex = 2; sumIndex <= 12; ++sumIndex) { Console.WriteLine("{0,5} {1,5} {2:F3}", sumIndex, sum[sumIndex], (double)sum[sumIndex] / 36000 * 100); } } Jan 5 '07 #2

 P: n/a I believe the problem is your usage of Random; for tight-loops you need to use a single instance, otherwise successive objects in a similar time interval (tiny amounts of time apart) will have the same seed. This shoud fix it: static readonly Random _rand = new Random(); static int RollTwoDice() { return _rand.Next(1,7) + _rand.Next(1,7); } Marc Jan 5 '07 #3

 P: n/a I see. So my super short loop would call RollTwoDice(), increment a counter, and then, say, before the next millisecond, it would call RollTwoDice(), perhaps many times before a new seed would be used. So given that usually two or three out of 11 dice sums never got rolled in 36,000 tries, I'd guess one number got rolled several thousand times in a row, then another number several thousand times after that, and so on. I'll make a version of my original program that will tell me if this is the case. Thanks for pointing me in what really looks like the right direction! -Jose Jan 5 '07 #4

 P: n/a I put a Console.Write() statement in my loop which tells me which number was generated i each iteration. This makes each iteration take a lot longer, but still each "random" number was generated dozens of times in a row. So you were right! Once again, thanks Marc. -Jose Jan 5 '07 #5

 P: n/a "Jose Durazo"

 P: n/a OP>Hello, I'm doing an exercise to simulate rolling a pair of dice 36,000 OP>times, For the truth you are rolling the same dice 72000 times, since the random object is always the same. The random object being the same doesn't allow you to make this statement. Mathematically, unless the dice know about eachother and the results directly influence eachother, then there is no difference in rolling one die twice versus rolling two dice once. I think therefore that the OPs statement is perfectly valid. However, given I already posted the answer to this, you could state that "many of your successive observations are based on the same roll of 2 dice, themselves separate", meaning that the OP might have observed "1+5,1+5,...1+5, 3+3, 3+3, ..., 3+3, 4+4, 4+4, ... 4+4" etc. Why you do a r.Next(1, 7) while a dice has only 6 faces? The upper number to Random.Next is exclusive; hence Next(1,7) will return a number in the range "[1,7)", or the set "{1,2,3,4,5,6}". Marc Jan 5 '07 #8

 P: n/a r.Next(x,y) returns a minimum of x and a maximum of < y, so in this case it will return 1 to 6. Fabio Z wrote: "Jose Durazo"

 P: n/a Ammendment; I see what you are trying to say in your "same dice 72000 times", but it is still incorrect; the OPs code actually rolls 36000 dice, each twice Again, at the math level it isn't going to make the slightest damned difference, but yes; to *truly* roll two dice you would need 2 Random instances - however, you would need to be very careful when initialising them, e.g. Random dice1 = new Random(), dice2 = new Random(dice1.Next()); A simple dice1 = new Random(), dice2 = new Random() would almost always end up reporting doubles each time "1+1, 5+5, 3+3" etc due to the seed and call-frequency being equal. But again: mathematically it makes no distinction (1 twice versus 2 once), *provided* Random provides a uniform distribution and lack-of-memory-function (i.e. regardless of the first roll, the second roll is still uniform [over the bigger picture; successive calls to Random are obviously predictable on a 1-by-1 basis if you know the initial seed]). Marc Jan 5 '07 #10

 P: n/a "DeveloperX"

 P: n/a "Marc Gravell" Hello, I'm doing an exercise to simulate rolling a pair of dice 36,000 OP>times, >For the truth you are rolling the same dice 72000 times, since the randomobject is always the same. The random object being the same doesn't allow you to make this statement. Mathematically, unless the dice know about eachother and the results directly influence eachother, then there is no difference in rolling one die twice versus rolling two dice once. Yes, you're right, I just like OOP, so, 2 dices = 2 objects. Jan 5 '07 #12

 P: n/a I see by the thread that you fixed the original problem. If you're interested in tidying up the code you see where you do the following? You're forcing yourself to reset currentResult to 0 simply because you used the += operator on the first assignment. int currentResult = 0; for (int numberOfRolls = 1; numberOfRolls <= 36000; ++numberOfRolls) { currentResult += r.Next(1, 7); currentResult += r.Next(1, 7); ++sum[currentResult]; currentResult = 0; } it could be this: int currentResult = 0; for (int numberOfRolls = 1; numberOfRolls <= 36000; ++numberOfRolls) { currentResult = r.Next(1, 7); currentResult += r.Next(1, 7); ++sum[currentResult]; } this: int currentResult = 0; for (int numberOfRolls = 1; numberOfRolls <= 36000; ++numberOfRolls) { currentResult = ( r.Next(1, 7) + r.Next(1, 7) ); ++sum[currentResult]; } of this eliminating currentResult altogether: for (int numberOfRolls = 1; numberOfRolls <= 36000; ++numberOfRolls) { ++sum[ ( r.Next(1, 7) + r.Next(1, 7) ) ]; } Re: the rolling of each die independently... it's a simulation you don't need to make it "real" in which case you can ask for a "Next" in the range of 2 to 12. There is no reason to ask for two random numbers which you then add. for (int numberOfRolls = 1; numberOfRolls <= 36000; ++numberOfRolls) { ++sum[ r.Next(2, 12) ]; } Now modify SimulateDiceRolls() to accept the total number of rolls as a parameter (so you could change the run size) and you're all set. "Jose Durazo"

 P: n/a "Tom Leylan"

 P: n/a Marc Gravell wrote: The random object being the same doesn't allow you to make this statement. Mathematically, unless the dice know about eachother and the results directly influence eachother, then there is no difference in rolling one die twice versus rolling two dice once. I think therefore that the OPs statement is perfectly valid. However, given I already posted the answer to this, you could state that "many of your successive observations are based on the same roll of 2 dice, themselves separate", meaning that the OP might have observed "1+5,1+5,...1+5, 3+3, 3+3, ..., 3+3, 4+4, 4+4, ... 4+4" etc. There's no particular reason I'm mentioning this, but conditional probabilities can be very difficult to explain. The Monty Hall paradox is a pretty good example that demonstrates how the wording of probability problems can mislead even the most astute math minds. Jan 5 '07 #15

 P: n/a Ah excellent point, my error, glad I wasn't be graded :-) Important to stick with the two independent rolls and the addition. I'd still eliminate the interim variable. "Fabio" Re: the rolling of each die independently... it's a simulation you don'tneed to make it "real" in which case you can ask for a "Next" in therange of 2 to 12. There is no reason to ask for two random numbers whichyou then add. This is not true. The sum of the different dices has not the same probability of a random number between 2 to 12. I.e. the most probable result of the sum is 7 because can be done with 1+6 2+5 3+4 4+3 5+2 6+1 the 2 and the 12 are the less probable because they can be done only with 1+1 6+6 For these reasons I suggested to do the 2 separated rolls. Jan 5 '07 #16

 P: n/a I just wikid; an interesting diversion, thankyou. I studied math, but never met this particular one, so I count myself indebted. I'm fairly certain that it doesn't apply in this case, though (not that you claimed it did...) ;-p Marc Jan 6 '07 #17

 P: n/a Hello all. Thanks for all of the advice! -Jose Jan 7 '07 #18

This discussion thread is closed

Replies have been disabled for this discussion. 