【结构与算法】—— 游戏概率常用算法整理 | 游戏中的常见概率设计分析
在游戏开发中,概率技术是非常重要的一部分。它涉及到游戏中的随机事件,如掉落物品、怪物出现、技能触发等。正确使用概率技术可以使游戏更加有趣和具有挑战性。
- 📢博客主页:肩匣与橘
- 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
- 📢本文由肩匣与橘编写,首发于CSDN🙉
- 📢生活依旧是美好而又温柔的,你也是✨
目录
在游戏开发中,概率技术是非常重要的一部分。它涉及到游戏中的随机事件,如掉落物品、怪物出现、技能触发等。正确使用概率技术可以使游戏更加有趣和具有挑战性。
一、随机数生成
在游戏中,随机数生成是非常常见的。我们需要生成随机数来模拟各种随机事件。在C++中,我们可以使用rand函数来生成随机数。rand函数返回一个介于0和RAND_MAX(通常是32767)之间的整数。我们可以使用模运算和加法来生成指定范围内的随机数。 例如,我们要生成1到100之间的随机数,可以使用以下代码:
int randomNumber = rand() % 100 + 1;
二、概率分布
在游戏中,我们经常需要使用不同的概率分布来模拟各种随机事件。以下是一些常见的概率分布:
2.1均匀分布
均匀分布是最基本的概率分布之一。在均匀分布中,每个数字出现的概率是相等的。我们可以使用rand函数来生成均匀分布。 例如,我们要生成1到6之间的随机数,可以使用以下代码:
int randomNumber = rand() % 6 + 1;
2.2正态分布
正态分布是另一个常见的概率分布。在正态分布中,大多数数字集中在平均值附近,并且随着距离平均值的增加而变得越来越少。我们可以使用Box-Muller转换来生成正态分布。 以下是一个生成具有指定平均值和标准差的正态分布的代码示例:
double normalRandomNumber(double mean, double stddev)
{
static double n2 = 0.0;
static int n2_cached = 0;
if (!n2_cached)
{
double x, y, r;
do
{
x = 2.0*rand()/RAND_MAX - 1;
y = 2.0*rand()/RAND_MAX - 1;
r = x*x + y*y;
}
while (r == 0.0 || r > 1.0);
{
double d = sqrt(-2.0*log(r)/r);
double n1 = x*d;
n2 = y*d;
double result = n1*stddev + mean;
n2_cached = 1;
return result;
}
}
else
{
n2_cached = 0;
return n2*stddev + mean;
}
}
2.3泊松分布
泊松分布是用于模拟随机事件发生的数量的分布。在泊松分布中,事件发生的概率是相等的,而事件发生的次数是随机的。我们可以使用以下代码来生成泊松分布:
int poissonRandomNumber(double lambda)
{
double L = exp(-lambda);
double p = 1.0;
int k = 0;
do
{
k++;
double u = rand()/((double)RAND_MAX + 1);
p *= u;
}
while (p > L);
return k - 1;
}
三、随机事件触发
在游戏中,我们经常需要触发各种随机事件,如掉落物品、怪物出现、技能触发等。我们可以使用概率技术来控制这些事件的触发概率。以下是一些常见的随机事件触发技术:
3.1固定概率触发
在固定概率触发中,我们使用一个固定的概率来控制事件的触发。例如,我们可以使用以下代码来控制一个事件以50%的概率触发:
bool shouldTrigger = (rand() % 2 == 0);
if (shouldTrigger)
{
// 触发事件
}
3.2基于概率分布的触发
在基于概率分布的触发中,我们使用一个特定的概率分布来控制事件的触发。例如,我们可以使用以下代码来控制一个事件以正态分布的概率触发:
double mean = 0.5;
double stddev = 0.1;
double randomNumber = normalRandomNumber(mean, stddev);
if (randomNumber > 0 && randomNumber < 1)
{
// 触发事件
}
3.3基于条件的触发
在基于条件的触发中,我们使用一个或多个条件来控制事件的触发。例如,我们可以使用以下代码来控制一个事件仅在满足一定条件时触发:
bool condition1 = true;
bool condition2 = false;
if (condition1 && !condition2)
{
// 触发事件
}
四、常见概率算法
4.1概率表
概率表是一种最简单的概率算法。它将所有的可能结果列出,并为每个结果分配一个概率值。然后,使用随机数生成器来生成一个随机数,并根据随机数选择一个结果。 例如,我们有一个掉落物品的概率表,其中掉落物品的概率分别为30%、20%和10%:
物品 | 概率 |
---|---|
物品A | 30% |
物品B | 20% |
物品C | 10% |
我们可以使用随机数生成器来生成一个随机数,例如在Java中,我们可以使用以下代码:
import java.util.Random;
public class Example {
public static void main(String[] args) {
Random random = new Random();
// 生成一个随机整数
int randomInt = random.nextInt(100);
// 判断掉落的物品
if (randomInt < 30) {
// 掉落物品A
} else if (randomInt < 50) {
// 掉落物品B
} else {
// 掉落物品C
}
}
}
上述代码中,我们生成一个0到99的随机整数,并根据随机数选择掉落的物品。
4.2权重随机
权重随机是一种更加高级的概率算法。它将所有的可能结果列出,并为每个结果分配一个权重值。然后,使用随机数生成器来生成一个随机数,并根据权重值选择一个结果。 例如,我们有一个掉落物品的权重表,其中掉落物品的权重分别为3、2和1:
物品 | 权重 |
---|---|
物品A | 3 |
物品B | 2 |
物品C | 1 |
我们可以使用随机数生成器来生成一个随机数,并根据权重值选择掉落的物品,例如在Java中,我们可以使用以下代码:
import java.util.Random;
public class Example {
public static void main(String[] args) {
Random random = new Random();
// 生成一个随机整数
int randomInt = random.nextInt(6);
// 判断掉落的物品
if (randomInt < 3) {
// 掉落物品A
} else if (randomInt < 5) {
// 掉落物品B
} else {
// 掉落物品C
}
}
}
上述代码中,我们生成一个0到5的随机整数,并根据权重值选择掉落的物品。
4.3概率分布函数
概率分布函数是一种更加复杂的概率算法。它通过一个数学函数来计算每个结果的概率值。然后,使用随机数生成器来生成一个随机数,并根据概率分布函数计算出选择的结果。 例如,我们有一个技能释放的概率分布函数,其中释放技能的概率随时间逐渐增加。我们可以使用以下的代码计算释放技能的概率,其中,time表示时间,a表示技能开始释放的时间,k表示技能释放的速率。我们可以使用随机数生成器来生成一个随机数,并使用概率分布函数计算释放技能的概率,我们可以使用以下代码:
import java.util.Random;
public class Example {
public static void main(String[] args) {
Random random = new Random();
// 生成一个随机浮点数
double randomDouble = random.nextDouble();
// 计算释放技能的概率
double time = getTime();
double a = 0.0;
double k = 1.0;
double probability = 1.0 / (1.0 + Math.exp(-k * (time - a)));
// 判断是否释放技能
if (randomDouble < probability) {
// 释放技能
}
}
private static double getTime() {
// 获取当前时间
return 0.0;
}
}
上述代码中,我们生成一个0到1的随机浮点数,并根据概率分布函数计算释放技能的概率。如果随机数小于概率值,我们就释放技能。
五、真随机和伪随机
在游戏开发中,概率是一个非常重要的概念。我们通常使用随机数进行生成,例如怪物掉落物品、技能释放概率等等。然而,在使用随机数时,开发者需要考虑到真随机和伪随机的问题。 伪随机数生成器(PRNG)是一种算法,它可以生成一个序列的数字,这些数字看起来像是随机的,但实际上是按照算法生成的。在PRNG中,种子值是非常重要的。如果我们使用相同的种子值,我们将会获得相同的随机数序列。
真随机数生成器(TRNG)是基于物理事件的,例如大气噪声、微粒衰变等等。它们可以生成真正的随机数,因为它们是由不可预测的物理事件生成的。然而,在大多数情况下,我们可以使用伪随机数生成器来模拟真随机数。
可以说,真随机是一种自然的随机机制,用代码来实现也非常容易,只需要用一个随机数与一个常量进行比较,根据大于小于等于分别触发不同的结果就行了。例如:掷色子,掷到到的值大于3触发什么奖励,小于三又是什么奖励,等于三又是另一种奖励。而伪随机则是人为创造出来的一种机制,他需要程序员写下更多的代码,也需要数值设计者做更多的计算。例如游戏的抽奖机制,当玩家抽到第90次还没有最好品质的奖励,那么第九十次必定获得该奖励,同时在获得该道具后,概率又恢复初始;亦或者是每次没有获得该道具,概率就增加,到第90次,概率是100%,必得该奖励,同时在获得该奖励后,概率又恢复初始。
在游戏开发中,概率技术是非常重要的一部分。我们可以使用随机数生成、概率分布和随机事件触发等技术来模拟各种随机事件,使游戏更加有趣和挑战性。在实际开发中,我们应该根据具体情况选择适当的技术,并进行充分的测试和优化,以确保游戏的质量和稳定性。
这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!
更多推荐
所有评论(0)