SHEEP_REALMS
事情的起因是这样的,我有一个网页游戏项目需要通过 JavaScript 实现一种数据存取过程,想通过种子来去除不必要的可演算的数据,于是我翻阅相关文档,发现了一个问题:JavaScript 的 Math.random() 方法不能带种子随机,但事实上其内部逻辑是可以带种子随机的,是的,它不给你用。











于是我决定自己实现带种子随机,具体方法是从网上抄一个下来。我首先在百度上查相关内容,果不其然一点屁用都没有,于是我查阅了谷歌,找到了一串有用的代码,并根据自己的需求加以修改,完成了下面这个方法:











注意,这个截图是从一个类当中截取的,因此方法的声明方式不太一样。

首先是第 1 行,接受三个输入参数:最大值、最小值、种子。
第 2 行,判断种子是否为空,这里有更好的判断方式,但是我懒了。
第 3 行,如果种子为空,则随机生成种子。为什么要乘以 2^53?因为浮点精度问题,如果仅仅只是乘以 10^N,会有很大概率导致末位是 0,而 2^53 则是 JavaScript 在不损失精度的情况下所能接受的最大数字。
第 4 行,重点来了,这里通过线性同余算法,根据输入的种子生成了一个介于 0 ~ 1 之间的浮点数,此刻便可替代 Math.random() 方法。
后续的过程其实并不重要,只是为了顺带实现指定数值范围。

为什么是 9301、49297、233280 这三个数字?别问我,我不知道,我只是站在了巨人的肩膀上。

有了带种子随机这把钥匙,可以帮助我打开很多扇大门,例如地图生成、战利品生成、随机运动等等,这些数据在存档后使用种子也能正确复原。

最后附上代码:

function random(max = 1, min = 0, seed = 0) {
    if (seed == 0 || seed == '' || seed == undefined) {
        seed = Math.random() * Math.pow(2, 53);
    }

    let rnd = ((seed * 9301 + 49297) % 233280) / 233280.0;
   
    return Math.ceil( min + rnd * (max - min) );
}复制代码

第一页 上一页 下一页 最后一页