如何正确地开发概率系统

How do I properly develop a Probability System?

本文关键字:概率系统 开发 正确地      更新时间:2023-10-16

所以我正在开发一款在线游戏,这款游戏的一个功能(就像许多其他MMORPG一样)是掉落系统&升级系统。

掉落系统决定怪物被杀时掉落的物品。升级系统决定项目是否能成功升级到下一个级别。

他们都需要能够使用概率来确定是否:

  1. 物品掉落
  2. 项目升级成功

我开发了一个系统,可以生成0到100000之间的随机数。在该系统中,上述任何一种情况发生的1%概率将由1000表示。同样,0.5%是500…50%是50000。

这是这个代码的核心。。。

int RandomValueInRange(const int start, const int end)
{
   std::random_device rd;
   std::mt19937 generator(rd());
   const int stable_end = ((end < start) ? start : end);
   std::uniform_int_distribution<int> distribution(start, stable_end);
   return distribution(generator);
}

现在,为了在物品掉落或升级成功的情况下进行皮肤剥除,我所要做的就是。。。

const int random_value = RandomValueInRange(0, 100000);
const int probability = item.GetProbability();//This simply returns an integer stored in a config file which represents the probability of this item being dropped/upgraded.
if(random_value <= probability)
{
    std::cout << "Probability Success!" << endl;
}
else
{
    std::cout << "Probability Failed!" << endl;
}

我希望以上内容能够奏效,但无论出于何种原因,它似乎都有缺陷。。。玩家可以轻松获得概率为0.1%的物品(这几乎不应该发生!)。

有人知道有更好的系统吗?或者我如何改进这个系统,以真正遵循概率准则。。。。

std::random_device rd;
std::mt19937 generator(rd());
...
return distribution(generator);

我认为这里的问题是,std c++ library给了你均匀分布如果重复使用random_device和mt19937,但每次都重新创建它们,这不是应该如何使用它们。将此std::random_device rd、此std::mt19937和此distribution 保存在某个位置

好的,所以代码的问题是您选择了一个0到100000之间的随机数。只要运气好,任何人都可以得到1到100,因为如果你仔细想想,100是一个很大的数字,应该不会太难得到。

此外,如果你回到小学/小学(或者你想怎么称呼它)的学校数学书籍,你会在"概率和机会"一章中看到一些问题,比如:

如果一个袋子里有6个球,3个红色,1个绿色和2个蓝色,那么选择蓝色的机会有多大?

当然,你会回答2/6或1/3。在C++中,可以将其更改为以下内容:

#include <iostream>
#include <ctime>
#include <algorithm>
#include <random>
using namespace std;

// Be sure to have this in to get a truly random number
class MoreProbability {

    // Be sure to have this in to get a truly random number

    void GetProbability(int min, int max, int probability) {
        const int arrayMax = max;
        int probabilityArray[100000];
        for (int i = 0; i < max; i++) {
            if (i >= 0 && i <= probability) {
                probabilityArray[i] = 1;
            }
            else {
                probabilityArray[i] = 0;
            }
        }
        // Arrays go from 0 to max-1 to account for the 0
        std::random_shuffle(&probabilityArray[0], &probabilityArray[max - 1]);
        // Check if the first element of the randomly shufffled array is equal to 1
        if (probabilityArray[0] == 1) {
            cout << "Probability Successful" << endl;
        }
        else {
            cout << "Probability Failed" << endl;
        }
    }
    int main() {
        srand(time(0));
        GetProbability(0, 100000, 100);
        return 0;
    }
};

它可能会给出StackOverflowException。要解决此问题,只需增加"堆栈保留大小"即可。

编辑:


在根据结果将代码更改一点以返回1或0,并将其放入一个重复1000次的for循环中(我建议不要这样做,因为这需要一段时间才能完成)后,我得到了1的输出,清楚地表明这段代码工作得很好。