我正在研究程序生成,以及它与随机生成之间的区别。我知道区别在于它是确定性的,它基于特定的种子值,就像所有随机引擎一样。
所以在 C++11 中,我知道要获得“最佳”随机序列,应该使用 std::seed_seq
,而且它不需要加密安全,所以std::mt19937
没问题。
在这个场景中,我想要一堆世界中物体的位置,这样我就可以生成一个关卡,然后我想把这个全新关卡的种子发给我的 friend ,因为它真的很酷。但事实上,输入 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;
}
明确地说,我要问的问题是:
在游戏环境中,我应该将什么用作程序生成器中的种子,以这种方式使用它有哪些优缺点?
我是一名优秀的程序员,十分优秀!