一种伪随机算法在刷新玩法中的应用
一种伪随机算法在刷新玩法中的应用
一. 为什么需要伪随机
随机要素是游戏性的一大重要保证,也是坑钱不二法门。做过随机的策划会发现,玩家对于所谓的概率的理解是事件发生的次数,10%的概率他们会认为大概是10次发生一次。这就给需要使用概率的地方造成了一大烦恼:事件发生的次数是一个期望值,是建立在足够多的试验次数下才成立(大数定律)。所以在很多情况下,一个高概率的随机事件,有可能几次都不出,会引来玩家的极力吐槽:“不是90%的概率锻造成功吗,为什么我连续锻造了三次都没有成功?这概率是假的吧!坑爹游戏!”,同时,在卡牌游戏中,很多人品差的人,死活抽不到某卡的事情,也不是一次两次了。
针对这一问题,有两种解决方案,第一种,凡是涉及随机,根本不提具体概率值,但是在很多情况下,概率值又不得不提起,如暴击率等等。另一种方法则是,将概率的运行机制向玩家的理解倾斜,即:保证概率对应着一个较为稳定的发生次数。
这就是伪随机算法诞生的实际需要。
二. 伪随机算法(PRD)特性
这方面已经有诸多文章探讨过,本文只做简单介绍。
玩过war3的同学或许知道,剑圣的暴击的算法实际上不是真随机,而是一种伪随机算法(以下简称这种伪随机算法为PRD),实现方式为:暴击率的初始值为c,若第一次没有暴击,则下一次暴击率为c+c=2c,即:P(N)=N*C以此类推,直到暴击发生,则重置暴击几率。
PRD最大的好处就在于事件发生次数的标准差比真随机的小(通常真随机算法的事件发生次数的波动范围是PRD的两倍),因此带来了更高的事件发生次数的稳定性,从而更贴近于玩家对概率实际的理解。同时,由于概率的累加,PRD会有一个事件发生时的最大次数,即该次试验时,概率为100%。
PRD,解决了两方面的问题,其一,在保持随机的情况下,使事件发生次数更加稳定,更加符合玩家对概率的认知;其二,拥有一个事件100%发生的次数,无需额外做保底规则。
以下为PRD的一些常用值表格:
然而,对于需求的概率值无法查表得到的情况,应该如何得到需要的C呢,为此我写了一个VBA,使用模拟的办法,通过输入C,来计算所对应的P(E),通过二分法来得到需要的C。
代码如下:
Sub prd()
Dim pi(), x(),xpi(), c, length, psum, pd, e
c = [b1] '初始概率
length = Int(1 / c) + 1 '概率=100%时的次数
ReDim pi(1 To length)
ReDim x(1 To length)
ReDim xpi(1 To length)
For i = 1 To length '通过该循环计算直到该次才发生的概率
If i = 1 Then
pd = 1
pi(i) = c '第一次就是初始概率
psum = pi(i)
ElseIf i = length Then
pd = (1 - (i - 1) * c) * pd
pi(i) = 1 - psum '最后一次才发生的概率为1-前面的和
Else
pd = (1 - (i - 1) * c) * pd
pi(i) = pd * i * c '直到该次才发生的概率
psum = psum + pi(i)
End If
e = pi(i) * i + e '期望次数计算
Next
Cells(2, 2) = e
End Sub
通过以上代码,输入初始概率c,即可输出期望发生次数e。
三. 刷新玩法
可以发现,以上的讨论针对的都是二项分布的情况,然而,实际的刷新玩法中,通常对应着多个事件。
本文将以我曾经做的一个系统为例,该系统的规则为:
可被刷新的项目有绿、蓝、紫、橙、金5种品质,显然,这5中品质是互斥的,如果玩家对当前的品质不满意,则可通过刷新,重新随机一次。
随着品质的提高,其出现的概率是递减的,对于橙色和金色而言,其概率低至10%和2.5%,第一次上线时,使用真随机,经常听到的抱怨是:你这个紫色不是10%的概率吗,为什么我都刷了30次了,还没出啊?我昨天几次就刷出来了!
由于玩家的选择性观测,必须保证一个更为稳定的刷新体验(保底这种事情很容易被玩家识破,从而失去了随机带来的乐趣)。
因此,我希望将PRD引入该系统。从而使玩家刷新到各种品质的次数更加稳定,从而保证体验。
该系统拥有5种可能的结果,而不是2种可能的结果。所以需要进行处理。
我们回过头来重新看该系统的刷新规则,实际上是根据不同的刷新次数,对应不同的颜色品质期望,表格如下:
次数 | 概率 | |
绿 | 1 | - |
蓝 | 3 | 33.33% |
紫 | 10 | 10% |
橙 | 50 | 2% |
金 | 100 | 1% |
我想到了一个办法:将绿、蓝、紫、橙、金视为5个独立的事件,单独使用PRD进行判断其是否发生,但是这样没法满足互斥关系,因此,采用了如下规则:
从金色到蓝色由高到低依次判断其是否发生,若是,则初始化其品质的所有概率,其他品质的概率增加,此次随机结束;若否,则判断下一品质是否发生。如果蓝色没发生,则判定为绿色发生,此次随机结束。
这样的处理实际上会使橙色及以下品质的实际概率低于理论值,因为当有比自己品质高的颜色被刷新出来时,便不会再判断自己是否发生,默认为不发生。
因此,为了尽可能满足需求,还需使用VBA模拟刷新,对C进行一定修正,已达到需求。
以上就是我对PRD的一个实际应用,实际上PRD是一种随机思想,即:将概率的运转方式向玩家理解的方向靠拢,保证实际的事件发生次数稳定在期望次数附近。