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 aa 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();
}
}
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.
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).
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);
}
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);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.