【问题标题】:Dogs go at same speed [duplicate]狗以相同的速度行驶[重复]
【发布时间】:2014-01-19 11:30:57
【问题描述】:

我正在研究 headfirst C# 的第一个实验室。我在我的程序中遇到了一个问题,即狗以相同的速度行驶。我不知道他们为什么这样做,因为在我看来,每个对象实例都会在其 X 位置添加一个随机的 1 到 5 个像素。这种随机性应该足以产生影响。

因此,因为我不想发布我的实验室 1 的全部课程,所以我重新创建了一个小型且独立的版本,只有两只狗赛跑,没有投注方面。

Form1.Designer 包含: - 两个装着猎犬的画框。 -a 开始按钮

Greyhound.cs 类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace test
{
    public class Greyhound
    {
        public int DogID;
        public PictureBox myPictureBox;
        public Point StartingPosition;
        public Point CurrentPosition;
        public Random Randomizer;

        public bool Run()
        {
            int AddDistance = Randomizer.Next(1, 7);
            CurrentPosition.X += AddDistance;
            myPictureBox.Location = CurrentPosition;

            if (CurrentPosition.X > 600)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void ReturnToStart()
        {
            CurrentPosition = StartingPosition;
            myPictureBox.Location = StartingPosition;
        }
    }
}

Form1.cs 类:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Greyhound One = new Greyhound() { DogID = 1, myPictureBox = pictureBox1, StartingPosition = pictureBox1.Location, CurrentPosition = pictureBox1.Location, Randomizer = new Random() };
            Greyhound Two = new Greyhound() { DogID = 2, myPictureBox = pictureBox2, StartingPosition = pictureBox1.Location, CurrentPosition = pictureBox2.Location, Randomizer = new Random() };
            if (One.Run())
            {
                timer1.Enabled = false;
                MessageBox.Show("Dog One WON!");

            }
            else if (Two.Run())
            {
                timer1.Enabled = false;
                MessageBox.Show("Dog Two WON!");
            }


        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }
    }
}

有人能看出它的创建方式有什么问题吗?这就是为什么狗会以相同的速度跑,而不是每次随机跑 1 到 5 个像素的原因。

【问题讨论】:

  • +1 表示创建了一个简化版本来显示问题

标签: c# performance random


【解决方案1】:

不要向每只狗传递一个新的 Random ,而是这样做:

Random rnd = new Random();
Greyhound One = new Greyhound() { DogID = 1, myPictureBox = pictureBox1, StartingPosition = pictureBox1.Location, CurrentPosition = pictureBox1.Location, Randomizer = rnd };
Greyhound Two = new Greyhound() { DogID = 2, myPictureBox = pictureBox2, StartingPosition = pictureBox1.Location, CurrentPosition = pictureBox2.Location, Randomizer = rnd  };

说明
发生这种情况是因为 Random 对象实际上是半随机的,它们会生成一系列随机数,这些随机数是使用给定的种子数计算的。 如果您使用 Random() 构造函数,则此种子会在运行时自动生成。但是,如果您按顺序创建两个 Random,就像您在代码中所做的那样,生成的种子将是相等的,两个随机器生成的数字也将是相等的。

你可以尝试一个更简单的例子:

        //Your two dogs have two new Random instantiated in sequence.
        //The two random numbers will be always the same
        bool areTheSame = new Random().Next() == new Random().Next();
        Console.WriteLine("two dogs with two Random are the same? "+ areTheSame);
        Random rnd = new Random();

        //The two dogs have now the same random object.
        //The two random numbers will be almost always different. Almost because the numbers are random and two or more equals number can occur in sequence.
        areTheSame = rnd.Next() == rnd.Next();
        Console.WriteLine("two dogs using the same random are the same? ~" + areTheSame);
        Console.ReadLine();

【讨论】:

  • 正确,但最好解释一下为什么这个解决方案有效
  • 我回答后就开始这样做了
【解决方案2】:

问题在于 Random 类。当你创建一个没有参数的新对象时,它使用system clock:

默认情况下,Random 类的无参数构造函数使用 系统时钟来生成它的种子值,而它的参数化 构造函数可以根据记号数取一个 Int32 值 当前时间。然而,由于时钟的分辨率有限, 使用无参数构造函数创建不同的 Random 对象 连续创建随机数生成器,产生 相同的随机数序列。

您应该只使用一个Random 类并插入不同的生成值作为您的起始速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    • 2012-11-30
    相关资源
    最近更新 更多