我是一名网络游戏开发人员,我遇到了随机数问题。假设一个玩家有 20% 的机会用他的剑造成致命一击。这意味着,五分之一的命中应该是关键的。问题是我在现实生活中得到了非常糟糕的结果——有时玩家在 5 次命中中得到 3 个暴击,有时在 15 次命中中没有。战斗时间很短(3-10 次命中),因此获得良好的随机分布很重要。
目前我使用 PHP mt_rand()
,但我们只是将代码移动到 C++,所以我想在我们游戏的新引擎中解决这个问题。
我不知道解决方案是否是一些统一的随机生成器,或者可能要记住以前的随机状态以强制正确分布。
原文由 Thinker 发布,翻译遵循 CC BY-SA 4.0 许可协议
我同意早期的答案,即在某些游戏的小运行中真正的随机性是不可取的——这对于某些用例来说似乎太不公平了。
我在 Ruby 中编写了一个类似 Shuffle Bag 的简单实现并进行了一些测试。实现是这样做的:
基于边界概率,它被认为是不公平的。例如,对于 20% 的概率,您可以将 10% 设置为下限,将 40% 设置为上限。
使用这些界限,我发现运行 10 次命中时, 14.2% 的时间真正的伪随机实现产生的结果超出了这些界限。大约 11% 的情况下,在 10 次尝试中得分为 0 次重击。 3.3% 的时间,10 次重击中有 5 次或更多次命中。自然地,使用这种算法(最小掷骰数为 5),“Fairish”运行的数量(0.03%)少得多。 .即使下面的实现不合适(当然可以做更聪明的事情),值得注意的是,您的用户通常会觉得真正的伪随机解决方案是不公平的。
这是我用 Ruby 编写的
FairishBag
的内容。 此处提供了整个实现和快速蒙特卡罗模拟(要点) 。更新: 使用此方法确实会增加获得致命一击的总体概率,使用上述界限将其提高到大约 22%。您可以通过将其“真实”概率设置得低一点来抵消这一点。 17.5% 的概率与公平的修改产生了大约 20% 的观察到的长期概率,并保持短期运行感觉公平。