我正在尝试模拟野生口袋妖怪的遭遇。如公式中所述:
The rate of Pokémon encounter is determined from a simple mathematical formula:
1 in (187.5 / ( x )) per step.
Let x equal the a value which determines how rare the Pokémon is. The higher the encounter rate,
the more common the Pokémon is.
Encounter-rate Table
Encounter type Encounter rate
Very common 10
Common 8.5
Semi-rare 6.75
Rare 3.33
Very rare 1.25
我想在每次按下按钮后运行这个概率。我如何用 rand()
模拟这个?
最佳答案
我会这样做
映射 rand()
rand() / (float)RAND_MAX
Rand()
返回一个从 0 到 RAND_MAX
的值所以这个公式映射0 -> RAND_MAX
到
0 -> 1
(float) 用于生成 RAND_MAX
一个 float ,因为 rand()
返回的值是一个 int
和 int / int
在 C++ 中返回 int
(rand() / (float)RAND_MAX) * 10
如果将结果乘以 10,它将映射 rand()
来自 0 -> 10
(rand() / (float)RAND_MAX) * 187.5
这将映射rand()
来自 0 -> 187.5
187.5 分之一
我们映射了 rand()
的值来自 0 -> 187.5
现在每次我们调用rand()
它将从 0->187.5
返回一个随机数
为简化起见,假设我们映射 rand()
来自 0 -> 200
rand()
将有 1/2 的机会将返回一个小于 100 的数字,因为 0 -> 200 之间的每个数字都有相同的机会被返回(例如 rand()
可以返回 25.67 或 100.9 或 140.6)
( (rand() / (float)RAND_MAX) * 187.5 ) < 1
根据相同的原理,返回的数字小于 1 的概率为 187.5 分之一
最终解决方案
我们仍然缺少 187.5/X
中的 1要实现相遇率,您只需更改 0 -> 187.5
的映射到
0 -> 187.5 / X
我们可以看到,如果 X 大,则意味着遇到率高,187.5 变小,返回的数字更有可能小于 1,但如果遇到率低,则 X 变小,187.5 得到更大(小于 1 的可能性更低)
最终代码
srand (time(NULL)); // Init rand() with a seed
bool encountered = ( (rand() / (float)RAND_MAX) * (187.5 / x) ) < 1
优化
一位用户指出,在最后的代码中,您需要为每个事件计算 5 个 rand(),但如果我们稍微调整一下公式,您只能计算 1 个 rand()
通过使用简单的数学,您知道在 10/2 个步骤中发生一次 (1) 的事件 是在(2)中10步发生两次的事件
因此在 187.5/X 步中发生一次 (1) 的事件在 187.5 步中发生 (1 * X)
如果我们从 0 -> 187.5 映射 rand() 那么对于每个口袋妖怪,我们可以只使用一个 rand() 为它计算一个唯一的值
float randomNumber = (rand() / (float)RAND_MAX) * 187.5
bool encountedPokemon1 = randomNumber < 1 * encounter_rate_first_pokemon
bool encountedPokemon2 = randomNumber < 1 * encounter_rate_second_pokemon
关于C++ 计算事件的概率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55368486/