如何掷半个骰子

2020-08-18 09:12:52

假设您正在设计一个游戏,为了确定一个动作的成功,您要掷骰子20(20个面的骰子)。即使您正在制作一款没有骰子的数字游戏,这也是一个将概率与上下文关联起来的有用工具。我们中的大多数人以前都掷过骰子,所以我们大多数人都直观地知道这种随机的机会是什么感觉。

现在假设您想让一个角色“幸运”。不是滚动一个d20,而是滚动两个d20并获得最高的结果。你现在有两倍(差不多)的机会掷出20美元!但是你有20倍的机会掷出1(现在掷1的唯一方法是让两个骰子都掷1,这是1/400的机会!)。这个角色当然非常幸运,他几乎不会在他想要做的事情上失败。

但是你怎么才能得到介于两者之间的东西呢?也许你希望一个角色稍微幸运一点,但不会幸运到他们基本上从来不会掷出1。你希望赔率对他们有利,但仍然希望他们有合理的失败几率。这是我前几天需要解决的一个游戏设计问题。所以我很好奇,如果你能掷“1个半骰子”而不是2个呢?这意味着什么,后果会是什么?

因此,让我们检查一下关于这个主题的现有数学文献。这里有一篇关于如何抛出“半枚硬币”的论文。这里的主要结构是,抛出2个“半硬币”与抛出一个硬币的预期结果相匹配(1个正面的几率为50%,1个反面的几率为50%),这类似于在计算结果中的正反两面数时,抛“2个硬币两次”与抛“4个硬币”是一样的。那么半枚硬币是什么样子的呢?嗯,这是一枚无限边的硬币,击中特定边的几率可能是负的。哪个是…?呃…。

负概率怎么可能说得通呢?除了奇怪的理论数学,也许还有量子力学之外,基本上不是这样的。你可以用一些奇怪的数学结构来做到这一点,这很酷,但在处理游戏设计时,这实际上对你没有任何帮助。因此,让我们回过头来试着找出更多的…。呃…。可以理解。

现在我最初的想法是“1.5d20”可能意味着50%的几率滚动1d20,50%的几率滚动2d20。基本上,抛硬币决定你这一轮是否“幸运”。(一些游戏,如DND,将这样的额外轮数称为“优势”)。这几乎就是我想要的。这可以很好地推广到任何类型的分数掷骰子,1.1d20,7.8d20,随便你怎么说。见鬼,如果你只把“-2d20”当作第二卷的意思,然后取最低的,你甚至可以把它扩展到负数。

但我在这里并不完全满意。这让人觉得这可能不是“数学上正确的”方法。此外,在代码中实现这意味着需要一个for循环,在该循环中,您将获取一大堆随机数并返回最大值。如果你想做疯狂的数字,比如1000000d20怎么办?获得一百万个数字的最大值比获得几个数字的最大值要昂贵得多。我在这里的动机与其说是性能,不如说是想找到一个闭合形式的公式,给出与掷多个骰子相同的分布,希望它能以一种更数学上令人满意的方式映射到小数值。

所以我开始试着想办法解决这个问题。这里有一条快速的相关信息:要使用代码计算某个范围内的随机整数,首先获取一个介于0.0和1.0之间的随机实数(独占,您可以恰好得到0,但不能恰好得到1),然后将该数字映射到您想要的范围(要将其映射到1到20的范围,您可以乘以20再加1,现在您就得到了一个介于1和21之间的数字(但不是正好是21),然后截断小数点,得到一个介于1和20之间的整数)。

现在,您应该能够首先通过一个函数(我将其称为“随机结果修改器函数”)运行初始随机数(介于0和1之间),然后当您将其映射到“1-20”时,每个数字的概率都不同。您将其映射到的范围在这里实际上并不重要,因为无论您如何映射它(只是更粗),分布的形状看起来都是一样的,所以我现在只使用这些从0到1的连续范围。

让我们快速查看一下这些分布在直方图中的样子。这是我写的一个快速应用程序,可以模拟一吨的连续掷骰子,然后以直方图的形式显示结果。没有显示单位,因为它实际上只是形状(但是左侧是0,右侧是1,并且曲线下的面积总是等于1(概率,哟!))。请注意,当您掷骰子时,曲线是一条平坦的线(每个选项的概率相等)。当你掷2个骰子时,你会得到一条递增的线(掷出更高数字的几率更高)。

现在你应该注意到的是,这基本上每次都是一个简单的多项式!掷骰子1的时候,图形看起来像x⁰,掷骰子2的时候看起来像x?,掷骰子3的时候看起来像x²,以此类推。一个简单的指数公式,它是分数的自然扩展!所以让我们试一试,好吗?让我们只取原始随机数,并将其提升到n-1的幂(其中n是要掷的骰子数)。呃…。

是的,这不是很有效,它的原因是,表示我们想要的分布的函数没有映射到我们用来直接修改原始随机数的函数。这里显然有一些微积分关系,这是有意义的,因为曲线下的面积在这里是一个相关值。还有一种相反的关系,这是有意义的,因为如果我们的函数喜欢将值拉向0(如x²在此范围内所做的那样),这意味着较低的值将更加常见。可能有一些严格的数学方法可以将期望的分布函数转换为随机结果修正函数,但我决定尝试并出错。如果我们把它提高到1/n的幂,我们就会得到我们想要的东西。

这里的主要问题是,掷1.1骰子往往真的会切断低掷的机会,比“10%的运气”所暗示的要多得多。平直线和直线之间的函数会是一些看起来奇怪的方形曲线,这让人感觉很奇怪。虽然我认为这可能是我们能得到的“数学上准确的”部分掷骰子的最好结果,但我也认为,从游戏设计的角度来看,它有点达不到你想要的效果。

所以,让我们回去检查一下我对部分骰子掷骰子的最初想法。掷1.5个骰子意味着50%的机会掷一个骰子,50%的机会掷两个骰子。此方法的概率分布如下所示:

哦,实际上那看起来好多了。介于两者之间的值实际上看起来像是在整数值之间结束的函数。当骰子数为整数时,考虑到幂版本与此一致,我们也可以半封闭地形成它,因此,一旦我们知道需要多少个“整数卷”,我们仍然可以使用它。一卷确定要使用多少卷,然后一卷通过幂函数推入,以获得结果。甜!。这种方法也可以很好地推广到其他形式的掷骰子(例如,将多个掷骰子的结果相加)。

事实证明,在游戏设计的上下文中,“数学上正确”的方法并不是真正正确的方法。我可能把时间浪费在探索这些东西上了。但至少现在我知道了!

那么,要回答这篇文章标题提出的问题,如何掷半个骰子呢?很简单。如果正面掷骰子,抛硬币。如果是反面,就不要。