C#For Loop很有气质

时间:2014-03-16 17:10:01

标签: c# for-loop graphics

由于某种原因,除非调用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();

        }


    }

2 个答案:

答案 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对象都有一个不同的种子,这意味着 在for循环重复之前至少要经过一毫秒。
  • 或者只是使用一个Random对象(它的种子是for循环的时间 开始),每次你想要一个随机数只是问同样的 对象为序列中的下一个数字。

由于第一种方法要求你减慢你的循环,这是愚蠢的,除非你没有其他选项,选择第二种解决方案,即在循环外声明Random对象。