5 Replies - 743 Views - Last Post: 04 January 2012 - 08:34 AM Rate Topic: -----

#1 JizzaDaMan   User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 139
  • Joined: 23-May 11

Randomly selecting colour

Posted 04 January 2012 - 06:38 AM

Hi guys,
At the moment, I am writing a brick breaker game, just for practice really.

The code grabs a random colour from an array of colours and sets it as the brick colour.

However, when I run the code, it makes all the bricks a uniform colour, albeit random, but I want them to each have a random colour.

If I put a breakpoint in the code, then the code works, and each brick gets a random colour:

[attachment=27219:Untitled.png]

This is code that gives the brick its colour :
        private Color[] Colours = { Color.Red, Color.Blue, Color.Yellow, 
                                      Color.Green, Color.Orange, Color.White, 
                                      Color.Violet, Color.Pink, Color.Navy, 
                                      Color.SkyBlue, Color.Purple, Color.Chocolate, 
                                      Color.Lime, Color.Aqua };

        public Brick(int XIndex, int YIndex) : base()
        {
            Random Randomizer = new Random();

            BackColor = Colours[Randomizer.Next(Colours.Length)];
            BorderStyle = System.Windows.Forms.BorderStyle.None; // I put the breakpoint here
            Size = new Size(1255 / 10, 40);
            Location = new Point((XIndex * Size.Width) + (10 * (XIndex + 1)), 
                (YIndex * Size.Height) + (10 * (YIndex + 1)));
        }



Really confusing, and seems to be completely ilogical. Any help is welcome!
Thanks all
:boat:

Is This A Good Question/Topic? 0
  • +

Replies To: Randomly selecting colour

#2 modi123_1   User is online

  • Suitor #2
  • member icon



Reputation: 15790
  • View blog
  • Posts: 63,277
  • Joined: 12-June 08

Re: Randomly selecting colour

Posted 04 January 2012 - 07:46 AM

What is your 'brick' class, or how are you bricks being drawn on the screen?
Was This Post Helpful? 0
  • +
  • -

#3 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6537
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Randomly selecting colour

Posted 04 January 2012 - 07:46 AM

Don't keep making a new random every time you call the Brick method.
Take line 9 out of the method and just have it be a class-scoped variable.
All else remains the same.

UPDATE: I thought you were using a method for Brick, didn't see it as a class. <where's my coffee>

The problem remains the same though: All of your Random instances are being created at virtually the same time so they are returning the same random value. The breakpoint causes a delay which then lets them generate different values.

You'll need to seed the random with a different value each time you make it. Commonly that is done by taking the DateTime.Now and using the last couple digits of the millisecond value. Or you can take the ticks of the CPU since it it was last started. Or create a GUID. Or anything that would be completely unique and use it as the seed for the random

This post has been edited by tlhIn`toq: 04 January 2012 - 07:50 AM

Was This Post Helpful? 0
  • +
  • -

#4 Curtis Rutland   User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 5106
  • View blog
  • Posts: 9,283
  • Joined: 08-June 10

Re: Randomly selecting colour

Posted 04 January 2012 - 08:16 AM

I wouldn't suggest seeding the Random yourself. It's already seeded by the current time with its default constructor (the problem is it's being called faster than the most granular time interval it's using). What you should do is make your Random object a class-level variable rather than an instance variable, and mark it Static.

private static Random Randomizer = new Random();

public Brick(int XIndex, int YIndex) : base()
{
    BackColor = Colours[Randomizer.Next(Colours.Length)];
    ...
}



This way, only one instance of Random is created for your entire application. Since each time you call Next, it will generate a new random number, this will work.

The reason it wasn't working was that when you created all your bricks, it was happening so fast that each Random was seeded with the same value. Because of this, each Random object would create the same sequence of numbers when you call Next. In your case, you're only calling Next once, so they all produce the same color.

Since with my way, you're only ever creating one instance of Random, each time you call Next you're moving forward in that sequence.

Check out this link on pseudorandom number generators for more info about what's going on. Short version: computer generated random numbers aren't really "random."
Was This Post Helpful? 0
  • +
  • -

#5 JizzaDaMan   User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 139
  • Joined: 23-May 11

Re: Randomly selecting colour

Posted 04 January 2012 - 08:25 AM

Quote

What is your 'brick' class, or how are you bricks being drawn on the screen?


The brick class is a class that inherits 'Label' and just creates a label with the properties I want.

I also have a level class where the bricks are contained in a list.

I then use a foreach loop in the Form1 class to draw each brick on the screen.

Quote

What you should do is make your Random object a class-level variable rather than an instance variable, and mark it Static.


Worked a treat, thanks :D
Was This Post Helpful? 0
  • +
  • -

#6 lordofduct   User is offline

  • I'm a cheeseburger
  • member icon


Reputation: 2668
  • View blog
  • Posts: 4,786
  • Joined: 24-September 10

Re: Randomly selecting colour

Posted 04 January 2012 - 08:34 AM

Agree with Curtis Rutland

although I personally wouldn't have the Brick class generate the random colour. What if later you want to save the current pattern and then regenerate it at a later time? You can't because every time you create a Brick it defines its own colour.

Why not do something like this:

public class Brick : Label
{

	public const int COLOR_CNT = 14;

	private Color[] Colours = { Color.Red, Color.Blue, Color.Yellow, 
                              Color.Green, Color.Orange, Color.White, 
                              Color.Violet, Color.Pink, Color.Navy, 
                              Color.SkyBlue, Color.Purple, Color.Chocolate, 
                              Color.Lime, Color.Aqua };

	public Brick(int XIndex, int YIndex, int colourIndex) : base()
	{
		BackColor = Colours[colourIndex]; //may want to check the index first
		BorderStyle = System.Windows.Forms.BorderStyle.None; // I put the breakpoint here
    		Size = new Size(1255 / 10, 40);
    		Location = new Point((XIndex * Size.Width) + (10 * (XIndex + 1)), 
        		(YIndex * Size.Height) + (10 * (YIndex + 1)));
	}

//... rest of code for class

}



and when you create the brick:

Brick[] arr = new Brick[20];
Random rand = new Random();


//create 20 bricks
for (int i = 0; i < 20; i++)
{
	//create 20 bricks
	var br = new Brick(xIndex, yIndex, rand.Next(Brick.COLOR_CNT));
}



I keep the colours in the Brick class because that technically is part of the definition of a Brick... your Bricks only have so many colours allowed. Though they too can be broken out if you desired (say you want to swap out palettes... in which case you actually could create a palette class that defines palettes for use in each level).

This post has been edited by lordofduct: 04 January 2012 - 08:38 AM

Was This Post Helpful? 1
  • +
  • -

Page 1 of 1