随机玩法在游戏中十分常见。最广泛的例如抽卡、暴击、多次触发概率事件……这些随机玩法为了保证玩家的游戏体验,通常并不会采用均匀随机的方法——毕竟均匀随机意味着玩家在游戏过程中有机会遇到极差的体验。对于抽卡游戏而言,超出设计值的抽数会直接让玩家损失金钱;对于竞技游戏而言,连续暴击vs连续不暴击的巨大收益差会直接让游戏丧失竞技性。
因此,我们通常需要引入一些机制来保证玩家在游戏过程中不会遇到极端体验,常见的方法就是加入保底。
伪随机?真随机?#
在进入正题之前,我们先对这些网上流传的概念正本清源。在互联网上,很多人把“随机”二分为“真随机”和“伪随机”,然后用计算机不能生成真随机数作为论据说明游戏中的随机都是假的,以此来证明“垫刀”等游戏玄学的合理性,这无疑是荒谬的。在这里我们需要明确这些概念:
- 真随机:由物理过程产生的随机数。这样的随机数发生器称为真随机数发生器(TRNG)。例如掷理想骰子、抛理想硬币、测量大气热噪声,猴子敲键盘等。这些随机数无法预测,也无法通过算法生成。如果你认为这些过程的随机性仍然存疑,那这就上升到哲学问题了。我们暂且认为上帝掷骰子,真随机性在现实世界中存在。
- 伪随机:由算法生成的随机数。伪随机数生成器(PRNG)通过算法生成随机数,这些随机数看似随机,但实际上是可预测的。伪随机数生成器通常通过一个种子(seed)来生成随机数,如果种子相同,那么生成的随机数序列也相同。
- 均匀随机:随机数在所有可能的结果中出现的概率相同。例如,掷理想六面骰子得到1-6的概率都是1/6。
- 非均匀随机:随机数在所有可能的结果中出现的概率不同。带有保底机制的随机数就是非均匀随机,正态分布的随机数也是非均匀随机。
真和伪仅仅是描述随机数生成器的随机数产生源,无论是TRNG还是PRNG,生成的随机数既可以是均匀随机的,也可以不是。而游戏语境下的“真假”随机事实上指随机数的均匀性,指其是否带有保底,垫刀甚至仓检等机制,这与真随机/伪随机无关,它们事实上是两个独立的维度。
楔子#
在进入正题之前,我们先来一个简化的例子。
考虑一个抽卡游戏,稀有卡牌保底为 $N$,平均抽数为 $E$,我们希望设计一个随机数生成器使其生成一个随机序列 $\mathcal{R}(n)$,其中 $\mathcal{R}(i)$ 为第 $i$ 次抽卡的结果,$0$ 代表没抽中,$1$ 代表抽中,那么这个随机数生成器该如何设计?
简单分析#
由于平均抽数为 $E$,因此根据大数定律,我们可以写出下面的等式:
$$ \lim_{n\to\infty}\frac{\sum_{i=1}^n \mathcal{R}(i)}{n} = \frac{1}{E} $$
【1.1】抽中的总概率 $p_\infty = 1/E$。
保底意味着如果连续 $N-1$ 次没有抽中,那么第 $N$ 次必定抽中;如果在前 $N-1$ 次里抽中了,那就重新计算保底。为了描述这个性质,我们将 $\mathcal{R}(n)$ 按照每个保底累计区间拆分为多个有限长度的序列,其中第 $m$ 个记作 $\mathcal{R}_m(n)$,其长度记作 $|\mathcal{R}_m|$,则这些序列满足:
$$ \begin{cases} |\mathcal{R}_m| \le {N} \\ \mathcal{R}_m = \set {0, \cdots, 0, 1} \end{cases} $$
【1.2】每个保底累计区间的长度不大于 $N$,且每个保底累计区间中只有一次抽中,该次抽中即为序列的最后一个。
同时,根据 $\mathcal{R}_m$ 和 $\mathcal{R}$ 的关系,我们还能写出:
$$ \sum_{i=1}^{|\mathcal{R}_m|} \mathcal{R}_m(i) = 1 $$
以及
$$ \sum_{i=1}^{m}\sum_{j=1}^{|\mathcal{R}{j}|} \mathcal{R}m(j) =\sum{i=1}^{\sum{j=1}^m{|\mathcal{R}_j|}} \mathcal{R}(i) $$
于是可以得到
$$ m = \sum_{i=1}^{\sum_{j=1}^m{|\mathcal{R}m|}} \mathcal{R}(i) = \sum{i=1}^{m}\sum_{j=1}^{|\mathcal{R}i|} \mathcal{R}(j+ \sum{k=1}^{i}|\mathcal{R_k}|) $$
再结合【1.1】,我们可以得到:
$$ \lim_{m\to\infty}\frac{\sum_{i=1}^{\sum_{j=1}^m{|\mathcal{R}m|}} \mathcal{R}(i)}{\sum{j=1}^m{|\mathcal{R}_m|}} = \frac{1}{E} $$