1

first post and a very noob question. I tried for many hours to get this program to work and eventually had to cheat and look up the answer from someone else.

When I run the following code, each greyhound array element receives the same random number. When I then initialized the array elements with a a random variable on the form, it then does generate different random numbers, but I don't understand why my initial code doesn't work. Can anyone please explain?

The code I had that didn't work: (relevant code)

firstly the class i made:

public class Greyhound
{
    public PictureBox MyPictureBox = new PictureBox();  //My picturebox object
    public int Location = 0;   //My location on the racetrack
    public Random Randomizer = new Random();

   public Run()
    {                                 
       Location +=  Randomizer.Next(15);
       MyPictureBox.Left = Location;

   }

}

And then the form:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
     }

     public Greyhound[] GreyhoundArray = new Greyhound[4];

     private void setupTrack()
        {
                  for (int i = 0; i < 4; i++)
            {
                GreyhoundArray[i] = new Greyhound();
            }
            GreyhoundArray[0].MyPictureBox = pictureBox1;
            GreyhoundArray[1].MyPictureBox = pictureBox2;
            GreyhoundArray[2].MyPictureBox = pictureBox3;
            GreyhoundArray[3].MyPictureBox = pictureBox4;
        }




       private void timer1_Tick(object sender, EventArgs e)
       {
           for (int i = 0; i < 4; i++)
           {
               GreyhoundArray[i].Run();
            }
       }

3 Answers 3

1

That's because by default Random constructor takes time as initial seed. If you do initialize all 4 elements at the same time, you're gonna have identical random generators. If you don't care about multi threading, make it static, so it'll be initialized once.

Sign up to request clarification or add additional context in comments.

Comments

0

You are initializing the Greyhound instances in a loop very quick. That's why all Random isntances get the same seed (using the default constructor uses the system time as seed).

MSDN - Random Constructor:

The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers

So you have to pass the Random to the constructor of Greyhound. Then use always the same Random instance in the loop.

public class Greyhound
{
    public PictureBox MyPictureBox = new PictureBox();  //My picturebox object
    public int Location = 0;   //My location on the racetrack
    private Random Randomizer = new Random();

    public Greyhound(Random randomizer)
    {
        this.Randomizer = randomizer;
    }

    public Run()
    {                                 
       Location +=  Randomizer.Next(15);
       MyPictureBox.Left = Location;
   }
}

Note that i've also made Randomizer to ensure that the constructor is used.

Here is the loop:

Random randomizer = new Random();
for (int i = 0; i < 4; i++)
{
    GreyhoundArray[i] = new Greyhound(randomizer);
}

Comments

0

The problem with your first code is that each instance of the class has its own random generator. If you create the instances close in time, then all the random generators will be seeded with the same start value, as the default seed is created using the system clock.

To use one random generator for all instances, you can create the random generator before creating the instances, and pass it to the constructor so that all instances have access to it:

public class Greyhound {

  public PictureBox MyPictureBox = new PictureBox();  //My picturebox object
  public int Location = 0;   //My location on the racetrack

  private Random Randomizer;

  public Greyhound(Random commonRandomizer) {
    Randomizer = commonRandomizer;
  }

  public Run() {                                 
    Location +=  Randomizer.Next(15);
    MyPictureBox.Left = Location;
  }

}

Usage:

Random rnd = new Random();
Greyhound[] GreyhoundArray = new Greyhound[4];
for (int i = 0; i < GreyhoundArray.Length; i++) {
  GreyhoundArray[i] = new Greyhound(rnd);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.