阅读了一些C#教程后,我决定制作一个Heads / Tails迷你游戏。它生成一个随机数0或1,并写出结果。使用循环,我会重复一千遍。问题在于,它只会写“ heads”或“ tails”,具体取决于生成的是0还是1。例如,如果有535个“ 0”和465个“ 1”,则只会写下“ Heads”。这是我的代码:
//variables
int count = 0;
int tails = 0;
int heads = 0;
while(count < 1000)
{
Random rnd = new Random();
int result = rnd.Next(0,2);
if(result == 1)
{
Console.WriteLine("Tails!");
tails = tails + 1;
count = count + 1;
}
else if(result == 0)
{
Console.WriteLine("Heads!");
heads = heads + 1;
count = count + 1;
}
}
Console.WriteLine("Heads = " + heads + "Tails = " + tails + " Counts = " + count);
Console.ReadLine();
尝试将Random rnd = new Random();
移动到while循环之外:
Random rnd = new Random();
while (count < 1000)
//...
问题是计算机中没有true随机数;它们都基于先前生成的随机数列表工作。由于您要在每个循环中实例化Random
,因此基本上每次都选择相同的起始种子。通过仅使用在循环外部创建的Random
的一个实例,您的应用程序将真正发挥作用,就好像数字是随机生成的。]
EDIT:
为了回应Solal Pirelli在评论中所说的,Random
实例实际上是使用当前计算机系统的时间作为种子的(如果您在构造函数中未提供任何种子值);但是,由于循环迭代发生得如此之快,因此为每个循环迭代创建的每个实例都具有相同的种子。EDIT#2:
正如CalebB所指出的那样,通过其他构造函数向Random
实例提供自己的种子也是一种好习惯。我建议使用GUID中的哈希值:保证即使您快速连续创建新实例,每个Random rnd = new Random(Guid.NewGuid().GetHashCode());
This essentially
Random
实例的种子也总是不同的。我说必要是因为,尽管统计学上说,该概率非常低,但有两个GUID值可能相同的可能性。 using System;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
public static void Main(string[] args)
{
Random rand = new Random();
Console.WriteLine(String.Join("\n",Enumerable.Repeat(0, 1000).Select(i => rand.Next(0,2) == 1 ? "Tails" : "Heads").GroupBy(i=>i).Select(g=> g.Key + " " + g.Count())));
Console.ReadLine();
}
}
}