如何为程序生成生成一个典型的种子?

时间:2016-07-05 09:56:20

标签: c++ c++11 random procedural-generation

我围绕程序生成,以及它与随机生成之间的区别。我得到的不同之处在于它是确定性的,它基于特定的种子值,就像所有随机引擎一样。

所以在C ++ 11中,我理解要获得“最佳”随机序列,应该使用std::seed_seq,并且它不需要加密安全,因此std::mt19937很好。

在这种情况下,我想要一堆世界上的对象位置,这样我就可以生成一个级别,然后我想给我的朋友发一个这个全新级别的种子,因为它非常酷。但事实上,键入189151022 140947902 1454660100 853918093 3243866855真的很烦人。那么,作为一个开发人员,我可以做些什么来确保随机性得到更多类型能力的保留?

我认为将值作为一个字符串散列然后将其反转,(但后来我记得哈希点)或者只是使用哈希本身,但这会更糟糕的种子吗?或者它甚至是重要的,我可以只使用“lol”作为我的种子,并且具有与兆字节长的完全随机数一样好的效果吗?

这是我为帮助我更好地理解它而做的快速示例。

#include <iostream>
#include <random>
#include <array>

using std::cout;
using std::endl;
using std::array;

struct pos
{
    float x, y;
    pos(float x, float y) : x(x), y(y) {}

    void print()
    {
        cout << "(" << x << " " << y << ")" << endl;
    }
};

int main()
{
    //Get seed
    std::random_device rd;
    array<unsigned long, 5> seed = { rd(), rd(), rd(), rd(), rd() };

    //Seed generator
    std::mt19937 generator;
    generator.seed(std::seed_seq(seed.begin(), seed.end()));

    //Setup distribution
    std::uniform_real_distribution<float> distribution(0, 100);

    //Generate the world (or whatever)
    pos a = pos(distribution(generator), distribution(generator));
    pos b = pos(distribution(generator), distribution(generator));
    pos c = pos(distribution(generator), distribution(generator));
    //And many, many more calls to get values from the generator

    a.print();
    b.print();
    c.print();

    //For when I want the same world back
    cout << "Seed: ";
    for (unsigned long s : seed)
    {
        cout << s << " ";
    }
    cout << endl;
}

要说清楚,我问的问题是:

我应该在游戏环境中的程序生成器中使用什么种子,以及以这种方式执行它的优点和缺点是什么?

2 个答案:

答案 0 :(得分:1)

从足够长的字符串开始(例如,华丽的房子&#39;)。

通过散列将其转换为数字(足以用于随机种子)。 可以使用string characters and their position获取哈希值。

如果您在另一侧使用相同的哈希函数,您的朋友应该能够使用相同的文本并获得相同的数字(相同的种子!)。

答案 1 :(得分:-1)

使种子成为字符串值。要从字符串中获取要使用的数字,请使用哈希值,例如sha256