Question

Ok so I have a dice throw app...

When I step through the code it functions normally and 'results' contains the correct number of throw results and they appear to be random, when I leave the code to run and do exactly the same thing it produces a set of identical numbers.

I'm sure this is a logical error I cannot see but fiddling with it for hours hasnt improved the situation, so any help is much appriciated. :)

    class Dice
{

    public int[] Roll(int _throws, int _sides, int _count)
    {
        Random rnd = new Random();
        int[] results = new int[_throws];
        // for each set of dice to throw pass data to calculate method
        for (int i = 0; i < _throws; i++)
        {
            int thisThrow = Calculate(_sides, _count);
            //add each throw to a new index of array... repeat for every throw
            results[i] = thisThrow; 
        }

        return results;
    }


    private int Calculate(int _sides, int _count)
    {
        Random rnd = new Random();
        int[] result = new int[_count];
        int total = 0;
        //for each dice to throw put data into result
        for (int i = 0; i < _count; i++)
        {
            result[i] = rnd.Next(1, _sides);
        }
        //count the values in result
        for (int x = 0; x < _count; x++)
        {
            total = total + result[x];
        }
        //return total of all dice to Roll method
        return total;
    }
}
Was it helpful?

Solution

First mistake: Never use multiple instances of Random, use a single instance, and pass that along with the other parameters.

OTHER TIPS

When you create "Random rnd = new Random();" it is seeded by the current time. When you debug your code (which takes time) it will be seeded differently each time.

Create 1 instance of Random, and reference that everywhere.

You're creating a random class every time you need to create a number. Doing this will give you the nutty results.

See here: FROM MSDN

This problem can be avoided by creating a single Random object rather than multiple ones.

To improve performance, create one Random object to generate many random numbers over time, instead of repeatedly creating a new Random objects to generate one random number.

E.g. create a private instance of Random...

In addition to what has been mentioned before...

Use Random for things like dice, card games, choosing random images and so forth. If you ever need to create a random number for security sake, use System.Security.Cryptography.RandomNumberGenerator. This simple example shows creating a random integer.

        RandomNumberGenerator gen = RandomNumberGenerator.Create();
        byte[] myBytes = new byte[4];
        gen.GetBytes(myBytes);
        int myValue = (BitConverter.ToInt32(myBytes, 0));

DO NOT use this unless you have a security need. The performance is less than that of the Random class. I suppose you could use this to seed Random but that might be overkill.

EDIT: It occurred to me that I had never tested this. A quick performance test showed the following:

1,000,000 random numbers: RandomNumberGenerator: 2.6 seconds Random: .015 seconds.

So Random is about 150 times faster.

Give the constructor Random a seed. That's the problem.

http://msdn.microsoft.com/en-us/library/aa329890%28VS.71%29.aspx

Random r = new Random(DateTime.Now.Millisecond);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top