Answers:
您可以通过列出损坏结果和混排的预设列表,以与Tetris相同的方式解决该问题。
假设您知道玩家将以线性分布造成0.8到1.2倍的伤害。拿列表[0.8,0.9,1.0,1.1,1.2]。随机洗牌,得到[1.2,1.0,0.8,0.9,1.1]。
玩家第一次造成伤害时,他们造成1.2倍伤害。然后1x。然后,依此类推,直到1.1倍。仅当数组为空时,才应生成并重新排列新数组。
实际上,您可能希望一次对4个以上的数组执行此操作(例如,以[0.8,0.8,0.8,0.8,0.9,0.9,0.9,0.9,...]开头)。否则,序列的周期足够短,以至于玩家可以弄清楚他们的下一个打击是否是“好”。(尽管这也可以为战斗增加更多的策略,例如在《勇者斗恶龙IX》的Hoimi表中,人们想出了如何通过查看治疗数值并进行调整直到找到保证的下降来进行探测的方法。)
我实际上写了一些代码来做到这一点。其要旨是使用统计数据来纠正不幸的条纹。您可以执行此操作的方法是跟踪事件发生的次数,并以此来偏移PRNG生成的数字。
首先,我们如何跟踪事件的百分比?幼稚的做法是将所有曾经生成的数字保存在内存中,然后将它们平均化:这虽然有效,但效率极低。经过一番思考,我提出了以下内容(基本上是一个累积移动平均线)。
采取以下PRNG样本(如果样本> = 0.5,我们将在其中进行处理):
Values: 0.1, 0.5, 0.9, 0.4, 0.8
Events: 0 , 1 , 1 , 0 , 1
Percentage: 60%
请注意,每个值占最终结果的1/5。让我们以另一种方式看待它:
Values: 0.1, 0.5
Events: 0 , 1
注意,0
贡献贡献了价值的1
50%,贡献贡献了价值的50%。更进一步:
Values: [0.1, 0.5], 0.9
Events: [0 , 1 ], 1
现在,第一个值占该值的66%,最后一个33%。我们基本上可以将其分解为以下过程:
result = // 0 or 1 depending on the result of the event that was just generated
new_samples = samples + 1
average = (average * samples / new_samples) + (result * 1 / new_samples)
// Essentially:
average = (average * samples / new_samples) + (result / new_samples)
// You might want to limit this to, say, 100.
// Leaving it to carry on increasing can lead to unfairness
// if the game draws on forever.
samples = new_samples
现在,我们需要对从PRNG采样的值的结果进行偏倚,因为我们在这里有一定百分比的机会,事情变得容易得多(例如,RTS中的随机损坏数量)。这将很难解释,因为它“只是我发生的”。如果平均值较低,则意味着我们需要增加事件发生的机会,反之亦然。所以一些例子
average = 0.1
desired = 0.5
corrected_chance = 83%
average = 0.2
desired = 0.5
corrected_chance = 71%
average = 0.5
desired = 0.5
corrected_change = 50%
现在,“发生在我身上”的是,在第一个示例中,83%只是“ 0.6中的0.5”(换句话说,“ 0.5中的0.5加0.1”)。在随机事件中,这意味着:
procced = (sample * 0.6) > 0.1
// or
procced = (sample * 0.6) <= 0.5
因此,为了生成事件,您基本上可以使用以下代码:
total = average + desired
sample = rng_sample() * total // where the RNG provides a value between 0 and 1
procced = sample <= desired
因此,您得到了我放入要点中的代码。我很确定这一切都可以在随机损坏的情况下使用,但是我还没有花时间来弄清楚这一点。
免责声明:这是所有本地统计数据,我在该领域没有任何教育。我的单元测试确实通过了。
samples
从一开始就将其最大值初始化(在这种情况下为100)。这样,RNG不需要经过99次迭代即可稳定下来。无论哪种方式,我可以用这种方法看到的一个缺点是它不能保证公平性,而只能保证恒定的平均值。
total = (average / 2) + desired
。
实际上,您要的是大多数PRNG的对立面,即非线性分布。只需在您的规则中加入某种递减的收益逻辑,假设超过1.0x的一切都是某种“严重打击”,只需说您每回合将爆击的几率提高X,直到得到然后将其重置为Y。然后每轮进行两次掷骰,一个掷骰以确定是否暴击,然后另一个掷骰确定实际的震级。
席德·迈耶(Sid Meier)在GDC 2010上就该主题和《文明游戏》发表了精彩演讲。稍后,我将尝试查找并粘贴链接。本质上,感知的随机性与真实的随机性不同。为了使事情变得公平,您需要分析以前的结果并注意玩家的心理。
不惜一切代价避免遭受不幸的连胜(如果前两回合不走运,则应保证下一回合是幸运的)。玩家应该总是比AI对手幸运。