再会!
我正在学习用 C# 编程,我正在制作一个程序,它给了我两个骰子的结果。
所以我创建了一个 Dice 类并创建了两个对象 dice1 和 dice2 并调用了一个为我计算随机数的方法。
总是计算两个相等的骰子的问题。
这就是我编写 Given 类的方式:
class Dado
{
private int dado;
private Random aleatorio = new Random();
public Dado()
{
dado = 0;
}
public int Valor()
{
dado = aleatorio.Next(1, 7);
return dado;
}
}
并从表单中创建两个对象 given1 和 given2,并在一个按钮内“投掷”骰子。
private Dado dado1, dado2;
public Form1()
{
InitializeComponent();
dado1 = new Dado();
dado2 = new Dado();
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "Dado 1 salio: " + Convert.ToString(dado1.Valor()) + " y Dado 2 salio: " + Convert.ToString(dado2.Valor());
}
但是每当我按下按钮时,两个骰子落在相同的数字上,它们会改变,但它们的下落是一样的。例子:
第一次掷骰子1 = 2 和骰子2 = 2 第二次掷骰子1 = 5 和骰子2 = 5 第三次掷骰子1 = 3 和骰子2 = 3
就好像当 given2 对象调用 Value 方法时它不起作用。
非常感谢您的宝贵时间。
问候。
在这些情况下,查看文档总是很有用的: Random()。
这里告诉你:
一点澄清; 计算机在生成真正的随机值方面非常糟糕。所谓的“随机”通常实际上是伪随机的;基于初始数字(种子),一些公式用于获得以下内容。
也就是创建的对象
Random()
会根据创建的时间返回一系列值。如果创建两个具有相同初始值(=同时,或几乎)的对象,则一系列值将相同。解决方案:有两种可能的解决方案:
在执行过程中稍作停顿,至少要经过 1ms。
导致两个数字的初始化不同;例如
添加构造函数:
并在创建它们时
这使得每个骰子都有不同的种子,确保序列不会相同。
更新
转念一想,上面的解决方案有个小问题:不能保证两个连续的随机数不一样;虽然概率很小 (
1 / (2 ^ 32)
, o1 entre 4.294.967.296
),但它不是 0。如果发生这种不太可能的情况1,那么骰子将再次掷出相同的数字(同样,每 40 亿次程序执行不到一次)。所以这种变化会更好:
此外,正如我在评论中指出的那样,另一种选择是创建一个给定的对象并简单地执行更多次;在现实生活中,经常使用几个来加快滚动速度,但在程序中这不是问题。所以:
1给我们一个概念,掷两个完美骰子 10 次,每次掷骰子得到相同值的可能性为
1 entre 6 ^ 10
或1 entre 60.466.176
,远大于该错误发生的概率。aleatorio
使财产static
aleatorio
原因是 通过使字段static
两个实例共享同一个对象Random
。这样,每次调用Value都会得到一个与上一次不同的随机数。Random 类并不真正生成随机数,而是基于种子 (
seed
),通过不将种子值作为参数传递,随机数是基于当前日期生成的。如果类的两个实例
Random
连续创建,种子被初始化为相同的值,因此两个实例将生成相同的“随机数”您可以在按钮单击上使用以下代码,您会发现它非常好。