PC Review


Reply
Thread Tools Rate Thread

dice rolling problem

 
 
Jose Durazo
Guest
Posts: n/a
 
      5th Jan 2007
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[13];

// 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


 
Reply With Quote
 
 
 
 
Jose Durazo
Guest
Posts: n/a
 
      5th Jan 2007
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[13];
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);
}
}


 
Reply With Quote
 
Marc Gravell
Guest
Posts: n/a
 
      5th Jan 2007
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

 
Reply With Quote
 
Jose Durazo
Guest
Posts: n/a
 
      5th Jan 2007
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


 
Reply With Quote
 
Jose Durazo
Guest
Posts: n/a
 
      5th Jan 2007
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


 
Reply With Quote
 
Marc Gravell
Guest
Posts: n/a
 
      5th Jan 2007
An oft-found trap ;-p

Just for completeness, Jon Skeet has a StaticRandom class in one of
his tool-bags which may be of interest to anyone using occasional
random numbers (useful where this type of private Random instance is
inconvenient due to e.g. threading / scoping constraints). Assuming
your code is not threaded, then for this type of tight loop I would
recommend the solution already posted (a "local" fixed instance),
purely to avoid the overhead of locking etc associated with static
utilities; OK, an uncontested lock is still fast, but not locking at
all (where it isn't necessary) is faster. If your code *is* threaded,
then you should probably note the risk of two calls to the *same*
Random.Next at the same time, which may not be safe; in this case you
could either:
* do your own local locking in the static method
* use StaticRandom
* (my preferred option) give each thread a separate *instance* of the
DiceRoller class (or whatever), so that they don't conflict and each
has an uncontested (instance) _rand that doesn't need locking.

In the general case, static methods should be thread safe. Looking at
http://msdn2.microsoft.com/en-us/library/2dx6wyd4.aspx, it doesn't
make any claims about thread-safety, so I have to assume that it isn't
thread-safe, which means the code I posted also isn't. Oops.

http://www.yoda.arachsys.com/csharp/miscutil/
http://www.yoda.arachsys.com/csharp/threads/

Marc


 
Reply With Quote
 
Fabio Z
Guest
Posts: n/a
 
      5th Jan 2007
"Jose Durazo" <joseN-O-S-P-A-M-@josenstacy.com> ha scritto nel messaggio
news:(E-Mail Removed)...

> 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?


For the truth you are rolling the same dice 72000 times, since the random
object is always the same.

Why you do a r.Next(1, 7) while a dice has only 6 faces?


 
Reply With Quote
 
Marc Gravell
Guest
Posts: n/a
 
      5th Jan 2007
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


 
Reply With Quote
 
DeveloperX
Guest
Posts: n/a
 
      5th Jan 2007
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" <joseN-O-S-P-A-M-@josenstacy.com> ha scritto nel messaggio
> news:(E-Mail Removed)...
>
> > 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?

>
> For the truth you are rolling the same dice 72000 times, since the random
> object is always the same.
>
> Why you do a r.Next(1, 7) while a dice has only 6 faces?


 
Reply With Quote
 
Marc Gravell
Guest
Posts: n/a
 
      5th Jan 2007
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


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ke dice     *eLmEr & Šenisita hMaNiToZz 4 eVeR(K)(6)Prom07 Microsoft Access 0 7th May 2009 06:22 AM
Dice roll "problem" Markv Microsoft Excel Misc 2 12th Jun 2008 09:08 AM
Problem rolling back WMP 11 - Need Help, Please. =?Utf-8?B?R2FpbA==?= Windows XP Help 3 24th Mar 2007 05:30 AM
Dice =?Utf-8?B?U3B1ZA==?= Microsoft Excel Programming 2 26th Oct 2006 01:21 PM
Z Chart i.e. top rolling annual bottom rolling monthly middle cum. =?Utf-8?B?d2F0IHByaW4=?= Microsoft Excel Worksheet Functions 0 28th Jan 2005 03:43 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 04:07 AM.