需要可预测的随机发生器


151

我是一名网络游戏开发商,但我遇到了随机数问题。假设一位玩家有20%的机会用剑获得暴击。这意味着5个匹配中有1个至关重要。问题是我在现实生活中的结果非常糟糕-有时玩家在5次点击中获得3分,有时15次点击中没有得分。战斗时间很短(3-10次击中),因此获得良好的随机分布非常重要。

目前,我使用PHP mt_rand(),但是我们只是将代码移至C ++,所以我想在游戏的新引擎中解决此问题。

我不知道解决方案是某种统一的随机生成器,还是想起以前的随机状态来强制正确分配。


58
假设为真正的随机数,则连续3次关键命中和2次非关键命中的几率约为0.5%,连续15次非关键命中的概率为3.5%。
Nixuz

10
+1以上。随机数的一个特征是您会得到离群值。
ConcernedOfTunbridgeWells,2009年

44
@Nixus:不,它有3次暴击和2次非暴击的几率大约为5%,而您忘了乘以(5!/(3!* 2!))=10。乘以95%的置信度在统计上不太可能在5次打击中发生3次暴击。
erikkallen,2009年

7
起初,我认为这是一个愚蠢的问题……再一次,我被SO谦虚了。
塞尔吉奥(SergioL)2009年

Answers:


39

我同意较早的答案,即小规模游戏的真正随机性是不可取的-对于某些用例而言,这似乎太不公平了。

我用Ruby编写了一个类似于Shuffle Bag的简单实现,并做了一些测试。该实现做到了:

  • 如果看起来仍然合理,或者我们还没有达到最低限度下注的门槛,那么它会根据正常概率返回合理命中率。
  • 如果从过去的滚动观察到的概率看起来不公平,则返回“公平化”命中率。

根据边界概率,这被认为是不公平的。例如,对于20%的概率,您可以将10%设置为下限,将40%设置为上限。

利用这些界限,我发现在运行10次命中后,真正的伪随机实现产生的结果超出这些界限的时间占14.2%。大约11%的时间,在10次尝试中得分为0。3.3%的时间中,有10次击中了5个或更多关键命中。自然地,使用此算法(最小掷骰数为5),很少(0.03%)的“公平”运行超出范围。即使下面的实现不合适(当然可以做一些更聪明的事情),值得注意的是,您的用户通常会感觉到使用真正的伪随机解决方案是不公平的。

这是我FairishBag用Ruby编写的内容。完整的实现和快速的蒙特卡洛仿真可在此处找到(要点)

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%,并使短期运行感觉良好。


我认为这是最适合我需求的解决方案。最佳针对性答案中提到的洗牌袋还不错,但是需要大量计算,而且我喜欢导致目标的最简单解决方案。
思想家

史蒂夫·拉宾(Steve Rabin)写了一篇有关游戏随机性的有趣文章。简而言之,对于大多数人来说,真正的“随机”行为并不是真正“随机”的,研究已经证明了这一点。他的文章称为“针对AI决策和游戏逻辑的过滤随机性”,发表在“ AI Game Programming Wisdom 2”(2003年)中。您应该检查一下,可能对您有用。
Jeff Tucker

@IanTerrell最好指出测试的样本量有多大,即确定这些概率的战斗数量。

@ user677656:它的要点是,但它是100k
Ian Terrell

223

这意味着5个匹配中有1个至关重要。问题是我的现实生活成绩很差-有时玩家在5次点击中获得3分,有时15次点击中没有得分。

您需要一个洗牌袋。它解决了真正随机性对于游戏来说过于随机的问题。

算法大致如下:将1个严重和4个非严重命中放入袋子。然后,您可以将它们的顺序随机放入购物袋中,然后一次挑选出来。当袋子是空的时,您再次用相同的值填充并随机化。这样,您平均每5次点击可获得1次严重点击,并且连续最多获得2次关键和8次非关键点击。增加袋子中物品的数量,以增加随机性。

这是我前一段时间编写的一个实现示例(使用Java)及其测试用例


21
+1个好主意,不加批评。缩放袋子以获得更高的随机性,并处理玩家之间的关键机率差异(如果变量ofc)
TheMissingLINQ

16
您的袋子大小为10。打1命中,再有30%的几秒钟几率。如果关键机会发生变化,您可以扔掉袋子,然后重新开始。请注意,如果您(或您的对手)知道您的致命一击概率和袋子的大小,那么任何这样的计划都会带来风险,您有时可以肯定地知道,对于一定数量的掷骰,您不会再遇到其他致命一击。这可能会影响战术。
史蒂夫·杰索普

3
是的...在这种情况下,您会产生类似于纸牌计数的rick俩。我是冒着大笔钱还是去大杀...是一小组固定的潜在结果,可以减少损失的风险并增加被“猎杀”的机会
Matthew Whited

8
我喜欢随机播放袋的想法,但我认为这不符合游戏“精神”,因为您的致命一击概率为20%(这意味着您不能在10次击中中做任何事)。每5个匹配项中恰好有1个匹配项。此外,如果严重击中概率发生变化,则重新滚动球袋将在游戏中引起故障。电话号码:如果我的致命一击已经做了,我会施法对自己取得下一个评论家早
迈克尔卡彭铁尔

2
@乔纳森:把袋子放到你给它的大尺寸上实际上消除了整个袋子的想法:确保在可接受的投掷量之内发生某些事情(达到的关键)。将袋子增大到50000几乎与使用随机数生成器相同。
dstibbe

113

您对随机意味着什么有误解。

其中哪个更随机?

在此处输入图片说明 在此处输入图片说明

尽管第二个图看起来分布更均匀,但实际上第一个图的随机性更高。人类的大脑通常会随机地看到图案,因此我们将第一幅图中的团块视为图案,但并非如此-它们只是随机选择的样本的一部分。


25
很好的Numb3rs解释!
RMAAlmeida,

9
从技术上讲,您无法衡量随机性。尽管我的猜测都是通过算法生成的,但两种分布对我来说似乎都相当随意。您可以在第一个图上执行大量测试,并确定它可能来自按照均匀分布放置点的过程,但是您无法得出结论,它是随机的。作为反例,您可以使用线性同余发生器绘制类似第一个图的图形,然后使用齐纳二极管的放大噪声绘制类似第二个图的图形。尝试使用不相关的单词,而不是随机的单词。
Dietrich Epp,2009年

8
您可以测量所述分布是随机的概率。
ceejayoz


2
为了公平起见,而OP可能没有使用正确的术语,他的理解是随机数发生器给他更多的东西,如第一张图,当他想要的东西更像是第二个图,因为它感觉更加“公平”给用户。
Kip 2012年

88

鉴于您要的行为,我认为您正在随机分配错误的变量。

与其随机化命中是否关键,不如随机化转数直到出现下一个关键命中。例如,每次玩家获得关键球后,只需选择2到9之间的一个数字,然后在经过多轮之后再给他们下一个关键球。您还可以使用骰子方法来接近正态分布-例如,您将在2D4转弯中获得下一个临界点。

我相信这项技术也可以在在世界范围内遇到随机遭遇的RPG中使用-您将步数计数器随机化,然后经过许多步,您将再次受到打击。感觉要公平得多,因为您几乎永远不会被连续两次遭遇击中-即使发生一次,玩家也会变得烦躁。


我认为这是一个很好的解决方案,但是80%的机会呢?
思想家2009年

我也喜欢同时使用多维随机数生成器。命中几率+力量几率+暴击几率。就像在D&D中滚动几个不同的骰子一样
Matthew Whited

我喜欢这个主意,而您对步数计数器一词完全正确,例如,很长一段时间以来,这种方法就一直在最终幻想中使用
埃德詹姆斯

这样做的一个问题是,只有在命中之间关键的概率大致恒定时,它才起作用。假设玩家在战斗中使用了一个咒语,使他们暴击的几率翻倍。那你如何调整匝数呢?
Alex319

+1非常好,也很容易处理比20%更少的击中概率。
爱丽丝·珀塞尔

53

首先,定义“适当的”分布。随机数是随机的-您看到的结果与(伪)随机性完全一致。

在此基础上,我假设您想要的是某种“公平”的感觉,因此用户不能成功走100转。如果是这样,我将跟踪自上次成功以来的失败次数,并对产生的结果进行加权。假设您希望五分之一的卷“成功”。因此,您会随机生成一个1到5的数字,如果它是5,则很好。

如果不是,则记录失败,然后再次生成一个从1到5的数字,然后加上floor(numFailures / 2)。所以这一次,他们再次有五分之一的机会。如果失败,则下一次获胜间隔为4 5;否则,则为5。五分之二的成功机会。有了这些选择,经过8次失败,他们肯定会成功。


需要注意的是...随机数范围会影响分布...例如选择一个随机r = new Random(); r.Next(1,5)和r.Next(1,1000000)%200000
伊恩·坎贝尔

23
+1是为了查看请求背后的问题,而不是告诉OP他对随机性有误解。
Boris Callens

4
请注意,如果执行此操作,则成功的整体比例将大于5分之一。一种解决方法是(例如)从1..100范围内随机选择20个不同的数字,并预先确定成为他们的批评。不过,这需要更多的簿记。
史蒂夫·杰索普

“从长远来看,“将大于五分之一”-我是说。
史蒂夫·杰索普

您可以将起始概率降低一点,以使总比例降低到1/5。我还没有算出要减少多少,但是一切都是连续的,因此必须有一个正确的答案。
史蒂夫·杰索普

35

用这样的东西替换mt_rand()怎么样?

XKCD漫画(RFC 1149.5将4指定为标准的IEEE审查的随机数。)

(RFC 1149.5将4指定为标准的IEEE审查的随机数。)

XKCD


不错,但是这会解决OP的随机数分布问题吗?;-)
Arjan Einbu 09年

并不是的; 他要求使用非随机RNG,可以使用此功能。但是他真正想要的是可以通过当前的最佳答案(stackoverflow.com/questions/910215/910224#910224)更好地解释
柯林·皮卡德

28
这比OP希望有更多的随机
Çağdaş特勤

-1,因为RFC1149没有第5节(或者,没有1149.5);+1为公平随机性。
greyfade

34

希望本文对您有所帮助: http //web.archive.org/web/20090103063439/http //www.gamedev.net /

这种生成“随机数”的方法在rpg / mmorpg游戏中很常见。

它解决的问题是(提取):

刀片蜘蛛在你的喉咙。命中,你想念。它再次命中,您再次错过。一遍又一遍,直到你没有剩下的要打。您已经死了,尸体上有两吨重的蜘蛛蛛。不可能?不,不可能吗?是。但是,如果有足够的玩家和足够的时间,几乎不可能的事情就变得不可能了。不是说刀片蜘蛛很坚硬,那只是倒霉。真令人沮丧 这足以使玩家想退出。


1
我听到过这样的说法:“百万分之一的事件在世界人口中发生了6000次”。
ceejayoz

19

您想要的不是随机数,而是对人类而言似乎是随机的数字。其他人已经建议了可以帮助您的个别算法,例如Shuffle Bad。

有关此领域的详细,详尽的分析,请参见AI Game Programming Wisdom 2。整本书对任何游戏开发者都值得一读,“看似随机数”的概念在以下章节中介绍:

人工智能决策和博弈逻辑的滤波随机性

摘要:传统观点认为,随机数生成器越好,您的游戏就越难以预测。但是,根据心理学研究,短期内真正的随机性通常看起来对人类绝对是随机的。本文展示了如何使随机AI决策和游戏逻辑对玩家来说更加随机,同时仍保持强大的统计随机性。

您可能还会发现另一章有趣的内容:

随机数统计

摘要:一般来说,人工智能和游戏对随机数的使用最多。忽略它们的潜力就是使游戏变得可预测且无聊。错误地使用它们与完全忽略它们一样糟糕。了解随机数的生成方式,其局限性和功能可以消除在游戏中使用它们的许多困难。本文提供了对随机数,它们的生成以及区分好坏的方法的见解。


8

当然,任何随机数生成都有机会产生这样的运行?您不会在3到10卷中获得足够大的样本集,无法看到合适的百分比。

也许您想要的是一个怜悯的门槛……请记住最后10卷,如果他们没有受到重大打击,请给他们一个免费赠品。平滑吊索和随机箭头。


8

最好的解决方案可能是使用多种不同的随机方案进行游戏测试,然后选择使玩家最快乐的方案。

您也可以在给定的遭遇中尝试针对相同号码的退避策略,例如,如果玩家1在第一轮掷出a 来接受。要获得另一个,1他们需要1连续滚动2 秒。要获得三分之一,1他们需要连续3个,无限制。


7

不幸的是,您实际上要求的是非随机数生成器-因为您希望在确定下一个数字时考虑先前的结果。恐怕这不是随机数生成器的工作方式。

如果您希望每5个匹配中有1个是关键,则只需选择1到5之间的一个数字,然后说该匹配将是关键。


1
他想要游戏友好的随机数,如果在某些情况下使用严格的随机数,则最终会产生“韩国随机数”结果。这些都是随机的结果,使玩家过于生气和沮丧(询问任何血统2玩家);)
Juan Techera,2009年

因此,如果第一击是暴击,则接下来的四击不会。听起来确实是OP想要的,但是当您这样说时,它听起来很迟钝。你得到我的紫外线。
belgariontheking

-1你似乎是混乱的“随机”与“记忆” - en.wikipedia.org/wiki/Memorylessness
爱丽丝赛尔

7

mt_rand()基于Mersenne Twister实现,这意味着它会产生您可以得到的最佳随机分布之一。

显然,您想要的根本不是随机性,因此您应该一开始就明确指定您想要的。您可能会意识到自己有不同的期望-结果应该是真正随机的并且是不可预测的,但是同时它们不应该显示出所陈述的概率的局部变化-但随后就变得可预测了。如果您连续设置最多10个非得分,那么您刚刚告诉玩家“如果您连续有9个非得分,那么下一个将会以100%的确定性成为关键”。完全不用打扰。


6

在如此少量的测试中,您应该期望得到如下结果:

真正的随机性只有在巨大的设定大小下才能预测到,因此很有可能第一次掷硬币并连续3次获得正面,但是经过几百万次翻转,您最终将获得大约50-50的收益。


7
尽管仍有几百万次翻转的机会,但您仍然只会看到硬币的一侧。尽管如果发生这种情况,您可能正坐在无限可能的驱动力附近:P
格兰特·彼得斯

哈哈,是的,但是机会是如此之低,以至于数学定律说你应该看到一个均匀的分布。
埃德·詹姆斯

6

我看到很多答案,建议您跟踪以前生成的数字或改组所有可能的值。

就我个人而言,我不同意,连续3次暴击是不好的。我也不同意连续15次非批评是不好的。

我可以通过在每个数字之后自行修改暴击几率来解决问题。示例(演示想法):

int base_chance = 20;
int current_chance = base_chance;

int hit = generate_random_number(0, 100) + 1; // anything from 1 to 100
if(hit < current_chance)//Or whatever method you use to check
{
    //crit!
    if(current_chance > base_chance)
        current_chance = base_chance; // reset the chance.
    else
        current_chance *= 0.8; // decrease the crit chance for the NEXT hit.
}
else
{
    //no crit.
    if(current_chance < base_chance)
        current_chance = base_chance; // reset the chance.
    else
        current_chance *= 1.1; // increase the crit chance for the NEXT hit.
    //raise the current_chance
}

您没有暴击的时间越长-您下一次暴击的机会就越大。我提供的重置完全是可选的,需要进行测试以判断是否需要。在漫长的非暴击行动链之后,连续或多次行动都可能有更高的暴击概率。

只需投入我的2美分...


我喜欢这种方法。我可能会以其他方式这样做。从较低的机会开始,并增加到最大20%+一些增加的百分比,直到达到并再次重置为较低的数量。
马修

5

前几个答案是很好的解释,因此,我将仅关注一种算法,该算法可让您控制“不良条纹”的可能性,而不会变得确定性。我认为您应该这样做:

代替指定p,即伯努利分布的参数(可能会导致严重打击),指定ab,即beta分布的参数,即贝努利分布的“共轭先验”。您需要跟踪到目前为止的关键命中数和非关键命中数AB。

现在,要指定ab,请确保a /(a + b)= p,这是重击的机会。整洁的事情是(a + b)量化了您通常希望A /(A + B)与p的接近程度。

您可以这样采样:

p(x)β分布的概率密度函数。它在许多地方都可用,但是您可以在GSL中找到它,形式为gsl_ran_beta_pdf。

S = A+B+1
p_1 = p((A+1)/S)
p_2 = p(A/S)

通过以概率为p_1 /(p_1 + p_2)的伯努利分布进行采样来选择关键命中

如果发现随机数有太多的“不良条纹”,请按比例放大ab,但在极限情况下,随着ab达到无穷大,您将拥有前面所述的无序袋方法。

如果您执行此操作,请告诉我它的进展!


5

如果希望使用不鼓励重复值的分布,则可以使用简单的重复拒绝算法。

例如

int GetRand(int nSize)
{
    return 1 + (::rand() % nSize);
}
int GetDice()
{
    static int nPrevious=-1;
    while (1) {
        int nValue = GetRand(6);
        // only allow repeat 5% of the time
        if (nValue==nPrevious && GetRand(100)<95)
            continue;
        nPrevious = nValue;
        return nValue;
    }
}

此代码95%的时间拒绝重复值,从而使重复不太可能但并非不可能。从统计上讲这有点丑陋,但可能会产生您想要的结果。当然,它不会阻止像“ 5 4 5 4 5”这样的分布。您可能会更喜欢并拒绝倒数第二个(例如)60%的时间和倒数第二个(例如)30%的时间。

我不建议您将其作为良好的游戏设计。只是建议如何实现您想要的。


我游戏中的某些值(例如暴击)不能有超过50%的机会,因此我完全阻止重复,但是这样可以将事件的机会降低一些。
思想家2009年

4

还不清楚您想要什么。可以创建一个函数,以便在您调用它的前5次中,它以随机顺序返回数字1-5。

但这并不是真正随机的。玩家将知道在接下来的5次攻击中他将获得正5分。不过,这可能是您想要的,在这种情况下,您只需要自己编写即可。(创建一个包含数字的数组,然后将其洗牌)

另外,您可以继续使用当前方法,并假设当前结果是由不良的随机生成器引起的。请注意,您当前的号码可能没有问题。随机值是随机的。有时您会连续获得2、3或8个相同值的数据。因为它们是随机的。一个好的随机数生成器只能保证平均而言,所有数字将被平均返回。

当然,如果您使用的是错误的随机数发生器,那可能会使您的结果出现偏差,如果这样,只需切换到更好的随机数发生器即可解决此问题。(请查看Boost.Random库以获得更好的生成器)

或者,您可以记住随机函数返回的最后N个值,然后用这些值加权结果。(一个简单的示例是,“对于每次出现的新结果,我们都有50%的机会应该放弃该值并获得一个新结果”

如果我不得不猜测,我会说坚持“实际”随机性是您最好的选择。确保您使用了一个好的随机生成器,然后继续按照自己的方式进行操作。


实际上,他使用的功能与boost库中最好的RNG相同。
Michael Borgwardt,2009年

MT不是“最好的”,最后我检查了一下。它很好,简单且快速,但不能产生最佳的分布。无论如何,获取一百万个随机数并检查分布。找出您的随机函数是否实际上给您均匀分布。如果不是,请寻找更好的发电机。如果是这样,要么吸干它,接受偶尔出现的一堆糖果,要么作弊,使结果不那么随意,更可预测。
jalf

4

您可以创建一个包含1到5的数字的列表,并按随机性对它们进行排序。然后只需浏览您创建的列表。您可以保证至少每个数字都会遇到一次...当您处理完前5个数字时,只需再创建5个数字...


4

我建议像暴雪使用的渐进百分比系统:http : //www.shacknews.com/onearticle.x/57886

通常,您滚动一个RNG,然后将其与一个值进行比较以确定是否成功。可能看起来像:

if ( randNumber <= .2 ) {
   //Critical
} else {
   //Normal
}

您需要做的就是逐渐增加基本机会...

if (randNumber <= .2 + progressiveChance ) {
   progressiveChance = 0;
   //Critical
} else {
   progressiveChance += CHANCE_MODIFIER;
   //Normal hit
}

如果您需要它更精美,可以添加更多内容。您可以设置progressiveChance可以避免的机会,以避免100%的暴击率或在某些事件中将其重置。您还可以通过每次进行逐次提升而使逐行增加的量较小,例如progressiveChance + =(1-progressChance)* SCALE,SCALE <1。


4

好吧,如果您对数学有所了解,则可以尝试指数分布

例如,如果lambda = 0.5,则期望值为2(请阅读该文章!),这意味着您很可能每2圈会击中/暴击/击中任何物体(例如50%,对吧?)。但是有了这样的概率分布,您将在第0圈(已经发生了一个事件,并且turn_counter被重置了)定义完全错失(或做任何相反的事情),大概有40%的机会击中下一回合,大约为65%有机会进行第二轮(下一轮下一轮),大约有80%的机会击中第三轮,依此类推。

这种分配的全部目的是,如果某人有50%的命中率,而他连续3次未命中,那么他肯定会命中(很好,超过80%的机率,并且每下回合都会增加)。它会导致更“公平”的结果,使总体50%的机会保持不变。

冒20%的暴击几率,你有

  • 17%暴击第一回合
  • 如果所有先前的都没有暴击,则第二次暴击时提高32%。
  • 如果在之前所有暴击中均未发生暴击,则第三次暴击率为45%。
  • 如果在之前所有爆击中均未发生暴击,则有54%的暴击者第四轮暴击。
  • ...
  • 如果所有先前的暴击都没有发生,则80%的暴击率进行第8回合。

在接下来的5个回合中,它仍然有约0.2%的机率(相对于5%的机率)是3分+ 2分。并且有4次随之而来的非犯罪的可能性为14%,5、5、5%,6、0.3%,7、0.07%的机会是8次随之而来的非犯罪。我敢打赌它的“比较公平”超过41%,32%,26%,21%和16%。

希望您仍然不会感到无聊。


这与我的解决方案非常相似,除了它仅“记住”自上次严重打击以来的时间。在此解决方案下,就未来的概率而言,一串4个关键命中与一串1个关键命中是相同的。因此,如果关键命中率很好,则此解决方案将限制您的下行风险,但不会限制您的上行风险。我的解决方案会同时影响两者。
尼尔G

显然,不同的解决方案都有自己的优势。从科学的角度来看,这一主题着重于保持随机性的清洁。这并不意味着它比洗牌袋或其他任何东西都更好。这只是一个似乎值得尝试的解决方案。
黑暗

3

如何使危急机会取决于最近的N次攻击。一个简单的方案是某种马尔可夫链: http //en.wikipedia.org/wiki/Markov_chain,但是代码还是非常简单的。


IF turns_since_last_critical < M THEN 
   critial = false
   turns_since_last_critical++;
ELSE
   critial = IsCritical(chance);
   IF Critial THEN
       turns_since_last_critica = 0;
   ELSE
       turns_since_last_critica++;
   END IF;
END IF;

当然,您必须进行数学运算,因为一旦您知道自从上一轮以来已经足够的转弯,一次暴击的机会就会比一次暴击的机会低


仅考虑最后一次攻击即可获得大部分效果。令P为观察到的命中率,R为未命中后的命中率,R / 2为命中后的命中率。根据定义,您随时有机会命中P = P * R +(1-P)*(R / 2)。这意味着P = R /(2-R)
MSalters

2

OP,

几乎,如果您希望它是公平的,那么它就不会是随机的。

您的游戏的问题是实际比赛时间。匹配时间越长,您看到的随机性就越少(临界值通常为20%),并且接近您的预期值。

您有两个选择,可以根据以前的结果预先计算攻击次数。每5次攻击您将获得一次暴击(基于您的20%),但是您可以使它随机发生。

listOfFollowingAttacks = {Hit,Hit,Hit,Miss,Crit};

那就是你想要的模式。因此,使其从该列表中随机选择,直到其为空为止,他们会重新创建它。

这是我为自己的游戏创建的模式,对于我想做的事情,它运行得很好。

第二种选择是增加暴击的机会,您可能会在所有攻击的末尾看到一个更均匀的数字(假设您的比赛很快结束)。机会百分比越少,您获得的RNG越高。


2

当您可能需要正态分布时,您正在查看线性分布。

如果您还记得青年时代玩D&D的经历,您会被要求滚动多个n面骰子,然后对结果求和。

例如,滚动4个6面骰子与滚动1个24面骰子不同。


2

英雄之城实际上有一个名为“突破者”的技师,可以解决这个问题。它的工作方式是,在丢失一串与该字符串中最低命中概率有关的长度的未命中之后,保证下一次攻击是命中。例如,如果您错过了一次击中几率超过90%的攻击,那么您的下一次攻击将自动击中,但是如果您的击中几率较低,如60%,那么您将需要连续几次未击中才能触发“突破者”(我不知道确切的数字)



0

加权值怎么样?

例如,如果您有20%的几率爆击,请生成1到5之间的数字,其中一个数字表示爆击,或者生成1到100之间的数字,其中20个数字表示爆击。

但是,只要使用随机数或伪随机数,就无法避免出现当前看到的结果。这是随机性的本质。


那为什么会有什么不同呢?对两组数字都具有临界值的机会完全相等。
萨姆森(Samjudson),2009年

究竟。我只是为他提供20%的例子给他两个选择。尽管如果要处理整数百分比,则100可能会更好,因为您只需要模拟一个“骰子”即可,如果您想这样想的话。
Thomas Owens

您呈现的选项正是他已经在做的事情。
ceejayoz

2
不是他想要的。他想要一个非随机数生成器,即使他认为这被称为随机数生成器。
ceejayoz

0

关于以下问题的反应:“问题是我的现实生活成绩很差-有时玩家在5次点击中获得3分,有时在15次点击中没有获得3分。”

您有3到4%的几率在15次点击中什么都没有得到...


当您在一分钟内使3500名玩家在线与10,000场战斗时,发生在3%战斗中的问题是非常普遍的问题。
思想家

再说一次,在3%的战斗中发生的倒霉仍然只是倒霉。
MSalters,2009年

0

我将提出以下“随机延迟的回退死机”:

  • 维护两个数组,一个数组(in-array)最初填充了0到n-1的值,另一个数组(out-array)为空
  • 请求结果时:
    • 返回所有已定义的随机值值中in-array
    • 将此值从 in-array移到out-array
    • 将一个随机(包括未定义的所有元素!)元素从out-array后移到in-array

它具有以下特性:n越大,它“反应”越慢。例如,如果您希望获得20%的机会,则将n设置为5并命中0的概率要比将n设置为10并命中0或1的概率要小,而将其设置为0到199的概率几乎为零。与小样本的真实随机性无法区分。您必须将n调整为样本大小。



0

我认为您可能使用了错误的随机分布函数。您可能不希望数字均匀分布。请尝试使用正态分布,以使关键命中比“常规”命中更不常见。

我使用Java,所以不确定在哪里可以找到C ++的东西,这些东西可以为您提供具有正态分布的随机数,但是必须要有一些东西。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.