这是我第一次发帖。希望这个问题不会太混乱。我正在为一个初学者C#书的实验室工作,现在卡住了。我正在创建一个“狗赛跑模拟器”计划。当我点击“开始比赛”按钮时,狗将以1到30之间的随机整数向定时器的每个节拍移动到右边,直到它们到达终点。我尝试了大量不同的方式来编写代码,阅读数组,Random类和for循环,但出于某种原因,无论如何,狗总是以相同的速度移动。它们需要以不同的随机速率随每个刻度移动。
解决方案会很好,但我真的想知道,为什么我的代码不起作用? 不应该为每条狗分配一个不同的随机数,因为它会循环显示数组的“i”值吗?
图片可以在这里找到: http://makingspidersense.com/dograce.png
这是Form1代码:
Greyhound[] dogs = new Greyhound[4];
private void startRaceButton_Click(object sender, EventArgs e)
{
timer1.Start();
dogs[0] = new Greyhound() { MyPictureBox = dog1PictureBox };
dogs[1] = new Greyhound() { MyPictureBox = dog2PictureBox };
dogs[2] = new Greyhound() { MyPictureBox = dog3PictureBox };
dogs[3] = new Greyhound() { MyPictureBox = dog4PictureBox };
}
private void timer1_Tick(object sender, EventArgs e)
{
for (int i = 0; i < 4 ; i++)
{
if (dogs[i] != null)
{
dogs[i].Randomizer = new Random();
dogs[i].Distance = dogs[i].Randomizer.Next(1, 30);
dogs[i].Move();
}
}
}
这是Greyhound类代码:
class Greyhound
{
public PictureBox MyPictureBox;
public bool GoingForward = true;
public Random Randomizer;
public int Distance;
public void Move()
{
if (MyPictureBox != null)
{
if (GoingForward == true)
{
MyPictureBox.Left += Distance;
if (MyPictureBox.Left >= MyPictureBox.Parent.Width - MyPictureBox.Width)
{
GoingForward = false;
}
}
}
}
}
答案 0 :(得分:6)
这是一个常见问题,你不是每次迭代都创建Random
的新实例,你在同一个实例上调用Next()
,问题是因为当你创建一个新的随机属性时默认种子基于DateTime.Now
var r = new Random();
for (int i = 0; i < 4 ; i++)
{
if (dogs[i] != null)
{
dogs[i].Randomizer = r;
dogs[i].Distance = r.Next(1, 30);
dogs[i].Move();
}
}
答案 1 :(得分:2)
我建议您使用Pseudo-Random Numbers。
每次执行new Random()
时都会使用时钟进行初始化。这意味着在紧密循环中,您可以多次获得相同的值。您应该保留一个Random
实例并继续在同一实例上使用Next。有关Random number generator only generating one random number
答案 2 :(得分:1)
在紧密循环或快速连续中初始化两个随机数生成器会创建两个随机数生成器,可以生成相同的随机数序列。