由于某种原因,除非调用MessageBox.Show,否则循环仅向面板打印1-3个圆圈。它应该打印用户输入到文本框中的圆圈数。我不明白为什么MessageBox被调用很重要,为什么如果没有调用Box,循环决定不要做几个圆圈。它应该围绕问题做完全数量的循环。
private void button2_Click(object sender, EventArgs e)
{
if (NumberCirclesText.Text != "" && Convert.ToInt32(NumberCirclesText.Text) < 100)
for (int x = 0; x < Convert.ToInt32(NumberCirclesText.Text); x++)
{
int y = x + 1;
Random myrandom = new Random();
int xcoord;
int ycoord;
ycoord = myrandom.Next(DrawSpace.Width);
xcoord = myrandom.Next(DrawSpace.Height);
int r = myrandom.Next(255);
SolidBrush mybrush = new SolidBrush(Color.FromArgb(myrandom.Next(255), myrandom.Next(255), myrandom.Next(255)));
System.Drawing.Graphics graphics = DrawSpace.CreateGraphics();
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(ycoord, xcoord, 30, 30);
graphics.DrawEllipse(System.Drawing.Pens.Transparent, rectangle);
graphics.FillEllipse(mybrush, rectangle);
//MessageBox.Show("There are " + y + " circles on the panel.");
NoOfCircles.Text = y.ToString();
}
}
答案 0 :(得分:3)
消息框是一个红色的鲱鱼:事实上,消息框会导致事情起作用的非平凡延迟。您每次迭代都会创建一个新的Random
对象,但每次迭代都非常快,对象将产生相同的“随机”序列。使用相同的“随机”输入,圆圈显示(大部分)重叠。
然后,简单的修复就是在循环外声明并创建Random
对象。
答案 1 :(得分:1)
TL; DR版本:只需在循环前添加
Random myrandom = new Random();
行。
要了解其原因,首先需要了解计算机如何生成随机数:
由于计算机不是一个非常随机的机器,它不能生成真正的随机数,它只能生成伪随机数字 - 似乎随机的数字。计算机执行此操作的方式是,当给定起始值(称为a seed
)时,它们会应用一些一年级数学,并获得伪随机数字。当被要求生成另一个号码时,他们只是将他们对起始值所做的操作应用于先前生成的号码。
既然您知道计算机如何生成看似随机的数字,您可能会遇到一个问题 - 起始值来自何处?
好吧,因为当给出相同的起始值时,计算机将生成相同的随机数序列,我们需要一些不断变化的值。什么改变了什么?时间!计算机使用自纪元(通常是1970年1月1日)以来的毫秒数作为生成随机数的种子。
在.NET(包括C#)中,告诉计算机使用时间生成随机序列的方法是创建一个新的Random对象Random myrandom = new Random();
要获得序列中的下一个数字,请拨打myrandom.Next();
。
由于你的代码在每次迭代时循环并创建一个新的Random对象,并且因为每次迭代都足够快以至于时间不会改变,所以每个新的Random对象都具有相同的seed
,所以当你&#39;再问它一个随机数,它给你第一个序列。因为所有Random对象的种子是相同的,所以每个随机数生成的第一个随机数将是相同的。
现在,在您了解了问题后,解决方案:
为了在每次以下之后获得不同的随机数:
由于第一种方法要求你减慢你的循环,这是愚蠢的,除非你没有其他选项,选择第二种解决方案,即在循环外声明Random对象。