简体   繁体   English

在数组中生成随机数

[英]Generating random numbers in an array

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. 这是因为默认情况下, Random构造函数需要时间作为初始种子。 If you do initialize all 4 elements at the same time, you're gonna have identical random generators. 如果您确实同时初始化所有4个元素,那么您将拥有相同的随机生成器。 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. 您将非常快速地初始化Greyhound实例。 That's why all Random isntances get the same seed (using the default constructor uses the system time as seed). 这就是为什么所有Random对象都获得相同种子的原因(使用默认构造函数将系统时间用作种子)。

MSDN - Random Constructor: MSDN-随机构造函数:

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 结果,通过调用默认构造函数紧密连续创建的不同Random对象将具有相同的默认种子值 ,因此将产生相同的随机数集

So you have to pass the Random to the constructor of Greyhound . 因此,您必须将Random传递给Greyhound的构造函数。 Then use always the same Random instance in the loop. 然后在循环中始终使用相同的Random实例。

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. 请注意,我还做了Randomizer以确保使用了构造函数。

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM