【发布时间】:2013-08-26 16:19:48
【问题描述】:
再次,我在这里需要一些帮助,今天我正在做一个 c# 作业,基本上包括创建一个可以总结 2 次掷骰子结果的方法,到目前为止,太好了!,没有什么难的事。 .. 但是,当我运行我的代码时,会发生一些非常奇怪的事情,我会让我的代码和结果自己说话:
using System;
class Program
{
public static String GetTimestamp()
{
DateTime saveNow = DateTime.Now;
return saveNow.ToString("yyyyMMddHHmmssffff");
}
public static int ThrowDice()
{
int randVal1, randVal2;
string TS1, TS2;
Random rand = new Random();
randVal1 = rand.Next(1,6);
TS1 = GetTimestamp();
randVal2 = rand.Next(1,6);
TS2 = GetTimestamp();
Console.WriteLine("Dice 1: \t" + randVal1 + ' ' + TS1);
Console.WriteLine("Dice 2: \t" + randVal2 + ' ' + TS2);
Console.WriteLine("-----------------");
return randVal1 + randVal2;
}
static void Main()
{
for(int i = 1; i<=10;i++)
{
Console.WriteLine("Dice Roll #" + i);
Console.WriteLine("Dice Sum:\t" + ThrowDice());
Console.WriteLine();
}
}
}
现在,这是我运行它时得到的:
掷骰子#1
骰子 1:1 / 时间戳:201308260146259075
骰子 2:2 / 时间戳:201308260146259131
骰子总和:3
掷骰子#2
骰子 1:2 / 时间戳:201308260146259135
骰子 2:5 / 时间戳:201308260146259135
骰子总和:7
掷骰子#3
骰子 1:2 / 时间戳:201308260146259135
骰子 2:5 / 时间戳:201308260146259135
骰子总和:7
掷骰子#4
骰子 1:2 / 时间戳:201308260146259135
骰子 2:5 / 时间戳:201308260146259135
骰子总和:7
掷骰子#5
骰子 1:2 / 时间戳:201308260146259135
骰子 2:5 / 时间戳:201308260146259135
骰子总和:7
掷骰子#6
骰子 1:2 / 时间戳:201308260146259135
骰子 2:5 / 时间戳:201308260146259135
骰子总和:7
掷骰子#7
骰子 1:2 / 时间戳:201308260146259135
骰子 2:5 / 时间戳:201308260146259135
骰子总和:7
掷骰子#8
骰子 1:2 / 时间戳:201308260146259135
骰子 2:5 / 时间戳:201308260146259135
骰子总和:7
掷骰子#9
骰子 1:2 / 时间戳:201308260146259135
骰子 2:5 / 时间戳:201308260146259135
骰子总和:7
掷骰子 #10
骰子 1:2 / 时间戳:201308260146259135
骰子 2:5 / 时间戳:201308260146259135
骰子总和:7
-第一卷很完美
-掷 2/骰子 1...完美,
-掷 2/骰子 2...WTH???
这些结果真的很奇怪,我期望在每卷上得到不同的时间戳和不同的值。时间戳是我想出的一个主意来检查这些数字的生成时间,看起来两个“骰子”同时滚动,看起来“随机”使用时钟生成种子。
我什至尝试使用 DiceRoll() 方法为骰子创建一个完整的类,但即使在两个完全不同的对象那里我只是一遍又一遍地得到相同的结果..
我该如何解决这个问题?有什么想法吗?
【问题讨论】:
-
几乎每天都有人问这个问题。 API 设计者注意:这种设计是一个制造混乱的机器!
-
@EricLippert 那么您将如何设计 API?你会用不同的东西作为种子吗?强制用户始终提供自己的种子?有一个静态的“默认”
Random实例用于“正常”使用(不禁止创建其他实例)? -
@Servy:这是个好问题;在 500 个字符的评论中很难详细说明每种方法的所有优缺点。 :-) 我的倾向是在第一个
new Random上播种当前时间,然后保持一个线程安全计数器,在每个后续new Random上增加一个种子。这为您提供了合理的熵来源,并保证任何两个实例都有不同的种子,而不会产生巨大的性能成本。 -
@EricLippert 在这种情况下实际上会导致非随机行为。如果您从每个后续种子中获取第一个值,
Random不会保留其随机外观。
标签: c# datetime random timestamp