Tanuj Wadhwa
Tanuj Wadhwa

Reputation: 2045

Problems in generating random colors

I want to generate some random colors in wpf and store them in an array.

Random r;
Color[] colarr = new Color[6];
for (int i = 0; i < colarr.Length; i++)
{
   Color c=new Color();
   r=new Random();
   r.Next();
   c.R = (byte)r.Next(1, 255);
   c.G = (byte)r.Next(1, 255);
   c.B = (byte)r.Next(1, 255);
   c.A = (byte)r.Next(1, 255);
   c.B = (byte)r.Next(1, 255);          
   colarr[i] = c;
}

but all the elements of the array represent one single color. When I debugged the code, I found random colors for every element, but when the code is executed(not in debug mode) same color is generated. This makes clear that the code is correct, there is some problem while execution.

EDIT :

How can I increase the randomness of the colors generated?

Upvotes: 2

Views: 1163

Answers (3)

keyboardP
keyboardP

Reputation: 69362

If you want a different approach to selecting random colours, you could use reflection. You'd have to compare performance depending on how often it's called but it might return less similar results. Note the rnd value is not stored within the function otherwise you'll have the same problem as you had in your original question of the same value being returned when the method is called in quick succession (such as from a for loop).

Random rnd = new Random();

private Color GetRandomColour()
{
    var colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public);
    var colors = colorProperties.Select(prop => (Color)prop.GetValue(null, null));

    int index = rnd.Next(colors.Count());

    return colors.ElementAt(index);
}

You can use it like this

for (int i = 0; i < colarr.Length; i++)
{          
   colarr[i] = GetRandomColour();
}

Upvotes: 2

Soner G&#246;n&#252;l
Soner G&#246;n&#252;l

Reputation: 98740

Try like this;

Random r = new Random();
Color[] colarr = new Color[6];
for (int i = 0; i < colarr.Length; i++)
{
   Color c=new Color();
   c.R = (byte)r.Next(0, 256);
   c.G = (byte)r.Next(0, 256);
   c.B = (byte)r.Next(0, 256);
   c.A = (byte)r.Next(0, 256);
   c.B = (byte)r.Next(0, 256);          
   colarr[i] = c;
}

From Marc's answer;

Every time you do new Random() it is initialized using the clock. This means that in a tight loop you get the same value lots of times. You should keep a single Random instance and keep using Next on the same instance.

Read: Random number generator only generating one random number

Upvotes: 3

antonijn
antonijn

Reputation: 5760

The problem is that you are making a new instance of random each run. You should set it once.

The default seed for a Random is the system time, which will be the same if you repeat a very fast loop; the time won't change a lot. If you only set it at the start, the Random will work as expected.

I would also suggest you use r.Next(0, 256), since that will give you any value ranging from 0 to 255.

Also, the call to r.Next() after the definition of Color c is completely unnecessary, since you don't use its value.

Random r = new Random();
Color[] colarr = new Color[6];
for (int i = 0; i < colarr.Length; i++)
{
   Color c=new Color();
   c.R = (byte)r.Next(0, 256);
   c.G = (byte)r.Next(0, 256);
   c.B = (byte)r.Next(0, 256);
   c.A = (byte)r.Next(0, 256);
   //c.B = (byte)r.Next(1, 255);  This line isn't needed btw        
   colarr[i] = c;
}

Upvotes: 4

Related Questions