c# - 如何围绕 Random.Next() 限制进行设计?

标签 c# unity3d

假设我有一个具有 10 个属性的对象,所有属性都是使用预先确定的种子从基于 System.Random 的算法中随机生成的,例如:

System.Random randomNumber = new System.Random(seed);
int prop0 = randomNumber.Next(x0, y0);
int prop1 = randomNumber.Next(x1, y1);
//...
int prop9 = randomNumber.Next(x9, y9);

一切都很好,直到我决定删除 1 个属性。假设它是我调用 Next() 时的第一个属性,现在所有结果都因调用顺序的改变而改变。

  • 如果我想维护其他属性的结果怎么办?

  • 我是否只生成第一个属性并丢弃它?

  • 我将来应该如何最好地解决这个问题,以便更轻松地更新我的属性列表?

最佳答案

最明显的解决方案是生成随机值,但忽略它的结果。

另一种选择是完全摆脱 Random 并使用不同的随机生成算法。我想象的是函数 f(seed, value),它返回基于 seedvalue 的“伪随机”值,但是是可重复的。

这样一来,每个属性都会有与其关联的,并且它的随机等价物将独立于其他值的随机等价物。

我当年做的算法here可以用作这样的功能。如果您只使用 x 值,并将最后一行更改为 fromto 而不是 03 ,那么它可以像这样使用:

int prop0 = RandomX.Generate(seed, 0x45F6C854, x0, y0);
int prop1 = RandomX.Generate(seed, 0x96F4DC41, x1, y1);
//...
int prop9 = RandomX.Generate(seed, 0xFE840301, x9, y9);

因此,如果您删除或添加一个属性,它不会影响其他人。如果您在整个代码中生成数字,这也适用,因此您不必密切关注每个值的生成。

或者你可以使用类似的东西

int prop0 = RandomX.Generate(globalSeed, objectSeed, propertySeed, from, to);

3 个种子的组合将在 from .. to 范围内产生“伪随机”值

生成算法可能类似于:

public static uint bitRotate(uint x)
{
    const int bits = 16;
    return (x << bits) | (x >> (32 - bits));
}

public static UInt32 Generate(int seed1, int seed2, int seed3)
{
    // simple "hashing" algorithm
    UInt32 num = 1;
    for (uint i = 0; i < 16; i++)
    {
        // multiply by prime numbers
        num = num * 119 + (uint)seed1;
        num = bitRotate(num);
        num = num * 541 + (uint)seed2;
        num = bitRotate(num);
        num = num * 809 + (uint)seed3;
        num = bitRotate(num);
        num = num * 673 + (uint)i; // not sure if necessary
        num = bitRotate(num);
    }
    return num;
}

只需添加从完整 uint 范围数字到 from .. to 范围的转换。

关于c# - 如何围绕 Random.Next() 限制进行设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39815289/

相关文章:

c# - 只调用单一依赖方法的单元测试方法 - c#/xUnit/Moq

c# - 为什么网站项目在config中没有release模式?

c# - 无法使用 Azure Batch 帐户任务执行 powershell 脚本

c# - Unity C# 空引用异常

c# - Linq to SQL 内部 .NET Framework 数据提供程序错误 1025

unity3d - Unity AudioClip引用丢失

c# - 尝试使用 LocalEulerAngles 旋转时游戏对象的未知旋转行为

c# - 如何更改通过 PrefabUtility.InstantiatePrefab 实例化的 GameObject 的父对象?

unity3d - 编辑器窗口截图

c# - 如何使用 OpenPop 阅读 HTML 格式的电子邮件?