我是一名网络游戏开发商,但我遇到了随机数问题。假设一位玩家有20%的机会用剑获得暴击。这意味着5个匹配中有1个至关重要。问题是我在现实生活中的结果非常糟糕- 有时玩家在5次点击中获得3分,有时15次点击中没有得分。战斗时间很短(3-10次击中),因此获得良好的随机分布非常重要。
目前,我使用PHP mt_rand(),但我们只是将代码移至C ++,因此我想在游戏的新引擎中解决此问题。
mt_rand()
我不知道解决方案是某种统一的随机生成器,还是想起以前的随机状态来强制正确分配。
我同意较早的答案,即小规模游戏的真正随机性是不可取的-对于某些用例而言,这似乎太不公平了。
我用Ruby编写了一个类似于Shuffle Bag的简单实现,并做了一些测试。该实现做到了:
根据边界概率,这被认为是不公平的。例如,对于20%的概率,您可以将10%设置为下限,将40%设置为上限。
利用这些界限,我发现运行10次命中, 真正的伪随机实现产生的结果超出这些界限的时间占14.2% 。大约11%的时间,在10次尝试中得分为0。3.3%的时间中,有10次击中了5个或更多的关键命中。自然地,使用此算法(最小掷骰数为5),很少(0.03%)的“公平”运行超出范围。即使下面的实现不合适(当然,可以做得更聪明),值得注意的是,您的用户通常会感觉到使用真正的伪随机解决方案是不公平的。
这是我FairishBag用Ruby写的肉。完整的实现和快速的蒙特卡洛仿真可在此处找到(要点)。
FairishBag
def fire! hit = if @rolls >= @min_rolls && observed_probability > @unfair_high false elsif @rolls >= @min_rolls && observed_probability < @unfair_low true else rand <= @probability end @hits += 1 if hit @rolls += 1 return hit end def observed_probability @hits.to_f / @rolls end
更新: 使用此方法确实会增加受到严重打击的总体可能性,在上述范围内增加到大约22%。您可以通过将其“真实”概率设置得低一点来抵消它。进行了适度修改的概率为17.5%,观察到的长期概率约为20%,并使短期运行感觉良好。