你如何在C#中获得Random的当前种子?

时间:2011-05-13 00:31:56

标签: c# random

在我的游戏中,我将使用随机值来挑选玩家从胸部获得的奖励。问题是你可以快速保存并快速加载,这意味着他们可以继续重新加载以重新随机化,直到他们得到他们想要的东西。有没有什么方法可以获取我的Random对象的当前种子值,并且可能在加载时返回到同一点,以便它们不会滥用随机化?

8 个答案:

答案 0 :(得分:19)

这是不可能的。

相反,您可以使用二进制序列化序列化Random实例 Random[Serializable],种子和内部状态将持续存在。

但请注意,保存随机种子可让您的玩家预测未来,如果您允许在战斗中保存,这非常有用。

另请注意,用户仍然可以保存,打开胸部,加载,执行生成随机数的动作,然后从胸部获取不同的项目。

答案 1 :(得分:10)

不确定获取种子,但您可以保存为Random对象提供的值。请记住,有两个构造函数。第二个是Random(Int32),所以如果你自己设置种子(一个足够简单的值是Environment.TickCount),你可以在将它传递给构造函数之前将其存储在某处。如果您还没有阅读,请查看https://docs.microsoft.com/en-us/dotnet/api/system.random上的MSDN文档。

答案 2 :(得分:3)

确实,feed = page.fetch(fields: 'from').feed curl -i -X GET \ "https://graph.facebook.com/v2.11/{page_id}/feed?fields=from&access_token=access_token" isn't stored因为它与初始化后的算法无关。它的一个衍生产品Seed存储在mj中,您可以使用Reflection来检查它是否比较两个SeedArray个实例:

Random

所以你要做的就是检查int subtraction = (Seed == Int32.MinValue) ? Int32.MaxValue : Math.Abs(Seed); mj = MSEED - subtraction; SeedArray[55]=mj; 中的最后一个元素(索引55)。这是唯一使用SeedArray的地方。

[从已删除的问题How to determine if two Random instances have the same seed?移动答案]

答案 3 :(得分:2)

这只与切线相关,但如果有人想知道为什么Random没有名为Seed的属性或名为GetSeed()的方法,我愿意打赌这可能是出于安全问题:您是否希望将“随机”号码生成器的内部工作方式暴露给外界?绝对不!否则,一些客户端代码可能会四处寻找,直到它获得您正在使用的值,然后用它们做出令人讨厌和无意识的事情。

答案 4 :(得分:1)

我可能只是根据MSDN使用它:http://msdn.microsoft.com/en-us/library/ctssatww.aspx

Random(seed)

其中种子是我从存储中加载的值。

答案 5 :(得分:0)

您可以将随机奖励计算为以下的哈希函数:

  1. 在您开始游戏时分配的种子,并保存在已保存的游戏中;和
  2. 胸部的一些恒定属性,在所有游戏中都是不变的(例如,固定的ID,或者如果它从未移动的话,它的位置)。
  3. 这种方法的优势在于,无论您保存和重放多少次,给定的胸部总会在给定的游戏中产生相同的奖励,即使胸部按不同的顺序打开,或者其他“随机”事件被触发以不同的顺序。此外,每个胸部的奖励都独立于其他胸部的奖励,只要哈希中使用的胸部属性是独立的。

    在以下示例中,GetRewardId生成奖励ID作为与胸部的x坐标异或的游戏种子的散列。它使用Random来执行哈希,将哈希输入用作Random对象的种子,并将第一个随机生成的数字作为输出。

    private static int GetRewardId(int seed, float coord, int numRewards)
    {
        int tempSeed = BitConverter.ToInt32(BitConverter.GetBytes(coord), 0) ^ seed;
        return new Random(tempSeed).Next(numRewards);
    }
    
    int seed  = new Random().Next();
    int numDifferentRewards = 5;
    float xCoordinate = chest.Position.X;
    int rewardId = GetRewardId(seed, xCoordinate, numDifferentRewards);
    

    如果您的许多箱子可能在sace中对齐,您可能想要选择不同的属性,或使用其他尺寸,通过与y和/或z坐标进行异或。

答案 6 :(得分:0)

不幸的是,在Microsoft的参考实现中,甚至没有保存no arg ctor的种子值,更不用说暴露访问: http://referencesource.microsoft.com/#mscorlib/system/random.cs,bb77e610694e64ca

但是,正如您在参考实现中所看到的那样,您可以传入的值(可能应该 - 我知道我这样做),就像它们一样:Environment.TickCount

所以将它保存到变量中,然后将该变量传递给带有arg的ctor,你现在知道了种子。事实并非如此,但无论您的意图是什么,这都应该足够了。

答案 7 :(得分:-3)

我建议您生成一个随机数,并将其用作真实随机数生成器的种子数。通过此方法,您有一个实际上是随机数的种子编号,您可以保存种子编号以供进一步使用。