游戏算法专题之PRD算法:揭秘王者荣耀荣耀水晶抽奖机制
游戏算法专题之PRD算法:揭秘王者荣耀荣耀水晶抽奖机制
PRD(Pseudo-Random Distribution)算法是游戏开发领域中常用的一种概率分布算法,主要用于控制随机事件的触发概率,使其表现得更加符合预期。相比于传统的随机数生成方法,PRD算法可以平滑地控制随机事件的触发次数,避免出现长时间未触发或频繁触发的极端情况。
以王者荣耀中的荣耀水晶为例,这种虚拟道具通常是通过抽奖方式获得的。根据官方公布的抽奖方式与概率信息,可以推测其使用的算法很可能是PRD或其变种。
基本原理
PRD算法通过调整事件发生的概率来实现分布平滑。具体来说,它会随着事件未触发的次数增加,动态提升触发的概率,直到事件发生。一旦事件触发,概率会重置为初始值,重新开始计算。
PRD算法的公式通常表示为:
$$ P(n) = \frac{1}{k-f(n)}$$
其中,$P(n)$是事件在第$n$次尝试时的概率,$k$是一个常数(通常设为1),$f(n)$是一个随尝试次数递增的函数,用于控制概率的增长。这个公式的作用是保证随着尝试次数的增加,概率不断增大,直至事件发生。
基本实现
下面通过使用PRD算法模拟抽取荣耀水晶的过程,来展示该算法的具体实现:
#include<iostream>
#include<cstdlib>
#include<ctime>
class PRDWithPity
{
private:
double initialProb; // 初始中奖概率
double increment; // 每次中奖时增加的概率
double currentProb; // 当前中奖概率
int pityLimit; // 保底次数
int currentTry; // 当前抽奖次数
public:
// 构造函数、初始化初始概率、递增概率和保底次数
PRDWithPity (double initProb = 0.05,double inc = 0.02,int pity = 10) :
initialProb(initProb),increment(inc),currentProb(initProb),pityLimit(pity),currentTry(0) {}
bool draw()
{
currentTry++;
// 达到保底,直接中奖
if (currentTry >= pityLimit)
{
reset();
return true;
}
// 生成0-1随机数
double randNum = static_cast<double>(rand()) / RAND_MAX;
// 如果随机数小于当前概率、表示中奖
if (randNum < currentProb)
{
reset();
return true;
}else
{
currentProb += increment;
return false;
}
}
// reset函数
void reset()
{
currentProb = initialProb;
currentTry = 0;
}
};
实现代码主要包含以下几个关键点:
- 初始概率与递增概率:使用PRD算法,逐步提高未中奖后的中奖概率。
- 保底次数:设置一个保底的次数上限,在达到该上限时,无论当前概率如何,玩家都会中奖。
- 中奖后重置:当玩家中奖后,概率重置为初始值,并重新开始计算。
模拟测试
下面通过一个简单的主函数来模拟抽奖过程:
int main()
{
srand(static_cast<unsigned>(time(0))); // 初始化随机数种子
PRDWithPity prd(0.000001, 0.0000002, 360); // 初始中奖概率0.05,每次未中奖增加0.02,保底次数10次
for (int i = 1; i <= 365; ++i) {
if (prd.draw()) {
std::cout << "恭喜屏幕前这位大佬第 " << i << " 次抽中一颗[荣耀水晶]" << std::endl;
} else {
std::cout << "第 " << i << " 次抽奖未中奖,幸运值+1,幸运值为: "
<< prd.getCurrentTry()
<< ",幸运值达到360必中一颗[荣耀水晶]。" << std::endl;
}
}
return 0;
}
为了确保在触发保底之前中奖的概率足够低,这里将初始中奖率设置为0.000001(十万分之一),每次抽奖后递增中奖率设置为0.0000002(百万分之一)。这样可以保证在触发保底之前玩家大概率不会抽到荣耀水晶,只能通过不断获取抽奖机会,直到抽够360次触发保底。
PRD的优点
- 平衡性:PRD通过调整概率,使得随机事件更加平衡。例如,在掉落系统中,PRD确保物品不会长时间不掉落,也不会短时间内频繁掉落。
- 易于控制:开发者可以通过调节初始概率或递增函数的参数,来控制事件的发生频率和分布特性。
- 提升用户体验:PRD可以防止用户在面对纯粹的随机系统时感到挫败,尤其是游戏中的奖励机制,通过PRD可以避免极端运气差的情况。
当然,算法并非一成不变的,具体实现还需要根据开发业务需求来决定是否对原算法进行扩展、优化或变种。例如,可以将递增值设计为动态调整,或者将概率和递增值从外部配置表中读取。
总结
对于游戏开发者而言,理解PRD算法及其应用有助于设计更公平、更吸引人的游戏机制。而对于普通玩家来说,了解这些算法原理有助于理性看待游戏中的随机事件,避免过度消费。