/【雷火UX数据产品】为什么抽卡时你是非酋?带你揭秘随机数到底是怎么生成的

【雷火UX数据产品】为什么抽卡时你是非酋?带你揭秘随机数到底是怎么生成的

你是否有时候会好奇游戏中抽卡的奥秘,假设抽到SSR的概率是5%,但是游戏是怎么实现这5%的概率的呢?本文会从最底层的算法向你揭秘随机的奥秘,不仅会介绍最常用的随机数生成的原理,也会用生动的例子带你手动生成“随机数”。虽然本文会涉及到一些数论的知识,但是相信我,你只需要运用小学数学的知识就能看懂本文。

1
余数还有这么神奇的性质?
在这里,我们先做1道非常简单的数学题,设三个数字A,B,M分别为4,7,9,然后我们随便取一个数字,就取3,把它叫种子,用X0表示。
● 代入到如下公式中:

● 其中mod的意思就是取余数,那么

● 把这个得到的余数1代入到上述公式中,就得到了一个新的余数:


● 再把这个得到的余数2代入到上述公式中,又得到一个新的余数,以此类推


我们把这个序列算出来就是3,1,2,6,4,5,0,7,8,3。除去最后的3,聪明的你也许已经发现这个序列很神奇的性质,就是包含了0-8所有的数字,且都只出现了一次,而且看起来出现顺序不像有什么明显规律,这是不是说明余数可以某种程度上代表随机呢?为了验证这个事情,我们进入下一个阶段。


2
0-1的随机数原来是这样生成的

首先,我们把A,B,M提到非常大,大到什么程度呢?
让M=232=4294967296,让A=1664525,让B=1013904223。我们再随便取一个种子X0,还是取3好了,再代入到公式中:

得到:

由于数字太大了,我们很难有直观感受这些数字意味着什么,由于这些是232的余数,所以取值范围在[0,232)之间,我们将这些数除以232,得到一组新的数值为0-1之间的序列手算毕竟太累了,让程序替我们完成算到X1000吧,得到的数字示例如下图所示:

你作为读者虽然知道这些数是计算出来的,但是看起来是不是就真的很像随机数的感觉?进一步验证,将这1000个0-1序列的数做出分布图,如下所示:

太神奇了,这1000个数居然真的保证了0-1之间的均匀性,也许你觉得0.4-0.5之间的数有些多,但这也是随机性的体现,而且毕竟1000个数量还不够大,我们生成100000个数试试,他们的随机分布图如下:

每个区间真的几乎一样多,满足大数定律,所以余数某种程度上真的可以表示随机


但是这好像还不够,因为我们一旦确定了三个参数A,B,M,以及种子数据X0,那么我就可以预测接下来的“随机数”了,因为序列已经确定了,这太可怕了。A,B,M的设置因为会关系到随机数的质量不太改变,就只能从X0下手了。所以尽可能将X0设置为动态值,或者对每个人是不一样的,这样随着随机的次数增多,才不容易被发现规律,因此绝大部分随机算法都会用到时间戳来设置X0,因为具有动态性,就很难被破解,也有一些游戏会用到玩家的游戏数字id来设置X0,这可能也是号有欧号和非号的由来。这套完整方法就是线性同余法,是随机数生成器中最常用的一种,本质上就是通过余数的随机性来完成。


3
建一个纯随机的抽卡系统
我们现在就用这套随机数生成器来做纯随机的抽卡系统,假设抽到SSR的概率为5%,SR概率为10%,R概率为85%的抽卡系统就很简单了,一次抽卡分为3步即可实现:

● 提前设置好A、B、M,并即时生成X0参数;

 根据参数通过上述方法生成一个0-1均匀分布随机数(用算出来的余数除以X0);

 判断这个数的范围在0-0.05之间,则认为抽到了SSR,在0.05-0.15之间则认为抽到了SR,在0.15-1之间则认为抽到了R;
一套非常简单的抽卡系统就这么做出来了,但是这样的抽卡系统能满足需求吗?会不会有什么样的问题呢?假设我们就用这套抽卡系统来给玩家抽卡,有1万名玩家,每个玩家都抽100次,那么大家抽卡的结果是什么样的呢?我们通过程序模拟出这种情况,得到大家抽到SSR的分布如下图所示:

也就是说在完全随机的情况下,哪怕SSR抽取的概率为5%,也会有63个人一个SSR也抽不到,有317个人只能抽到1个SSR。而有3个真正的欧皇,每个人可以抽到14次SSR,平均来看确实是每个玩家5.0146个SSR,但这是你想要的抽卡系统吗?


有没有什么方法可以让随机更具“人性化”,或者说更加满足玩家期望的随机?限于篇幅原因,不在此篇讲述,有机会作者将在下一篇文章中跟大家分享!

往期推荐


本文来自微信公众号“网易雷火UX用户体验中心”(ID:LeihuoUX)。大作社经授权转载,该文观点仅代表作者本人,大作社平台仅提供信息存储空间服务。