Как генерируется типичное семя для процедурной генерации?

Я оборачиваюсь вокруг процедурного поколения и разницы между ним и случайным поколением. Я понимаю, что разница в том, что он детерминирован, который основан на конкретном начальном значении, как и все случайные движки.

Так что в 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;
}

Чтобы быть ясным, вопрос, который я задаю:

Что я должен использовать для начального числа в процедурном генераторе в игровом контексте, и каковы его плюсы и минусы в такой манере?

1

Решение

Начните с достаточно длинной сгенерированной строки (например, «великолепный дом»).

Преобразуйте его в число (достаточно для случайного начального числа), хэшируя его.
Хеш можно получить с помощью строковые символы и их положение.

Если вы используете ту же хеш-функцию на другой стороне, ваш друг сможет использовать тот же текст и получить тот же номер (то же самое семя!).

1

Другие решения

сделать семя строковым значением. чтобы получить число для использования в строке, возьмите хеш f, как sha256

-1

По вопросам рекламы [email protected]