因此,我正在使用名为die的公共类创建骰子。此类具有2个构造函数和3个其他方法。当我在主程序中调用类时,它不会打印所需的(随机)结果。
首先,我尝试根据默认值在1-6之间打印出一个随机数。一旦我弄清楚了这一点,我最终想指定一个边数,并打印出一个介于1到该特定数字之间的数字。
/// Represents one die (singular of dice) with faces showing values between
/// 1 and the number of faces on the die.
public class Die
{
private int numFaces, faceValue;
public Die() => (numFaces, faceValue) = (6, 1);
public Die(int faces)
{
numFaces = faces;
if (numFaces < 3)
numFaces = 6;
faceValue = 1;
}
public void RollDie()
{
//for (int ctr = 0; ctr <= numFaces; ctr++)
var rnd = new Random();
for (int ctr = 1; ctr <= 20; ctr++)
faceValue = rnd.Next(1, numFaces + 1);
}
public int GetFaceValue() => faceValue;
public int GetNumFaces() => numFaces;
}
public class Program
{
public static void Main()
{
var myDie = new Die(1);
for (int i =0; i < 20; i++)
{
myDie.RollDie();
Console.WriteLine(myDie.GetFaceValue());
}
}
}
答案 0 :(得分:1)
由于使用无参数构造函数时,Random
是时间种子,因此,结果重复会带来非常负面的后果。
Excerpt来自API文档:
但是,由于时钟的分辨率有限,因此使用 无参数构造函数以在关闭时创建不同的Random对象 连续创建随机数生成器,它们产生相同的 随机数序列。
...
在大多数Windows系统上,彼此之间在15毫秒内创建的随机对象可能具有相同的种子值。
关于在创建和掷骰子时获得随机数的方法,这是一种更安全的方法:
public class Die
{
static int seed = Environment.TickCount;
static readonly ThreadLocal<Random> DieRandom = new ThreadLocal<Random>(()
=> new Random(Interlocked.Increment(ref seed)));
public int FaceCount { get; }
public int Value { get; private set; }
public Die() : this(6) // default to 6 faces
{
}
public Die(int faceCount)
{
if (faceCount < 3) // validate input
throw new ArgumentOutOfRangeException(nameof(faceCount));
this.FaceCount = faceCount;
}
public int Roll()
{
Value = DieRandom.Next(1, FaceCount + 1);
return Value;
}
}
编辑:按照建议的here更新了具有线程安全性的随机数。