Программа Dice Rolling генерирует одинаковую последовательность случайных чисел при каждом запуске - PullRequest
2 голосов
/ 02 февраля 2012

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

Я использую IDE CodeBlocks, а компилятор - GCC. Программа прекрасно компилируется как при отладке, так и при выпуске, но независимо от того, какой вариант сборки я выберу, исполняемый файл будет возвращать одинаковые значения при каждом запуске. Я не могу иметь этого, потому что его предполагаемое использование - как настольный инструмент RPG, и для умного игрока было бы относительно легко обмануть, если бы они знали образец, по которому будут бросать кости.

Какой самый простой способ решить эту проблему?

Вот источник:

#include <iostream>     /* for input and output */
#include <cstdlib>      /* for random numbers */

using namespace std;

void rolldie() {
    cout << "How many sides to the die?" << endl << "D";
    int die;
    cin >> die;
    int roll = rand() % die +1;
    cout << endl << "The die rolled " << roll << endl << endl <<  "Roll another? (Y for yes, anything else for no; Capitalization counts) ";
}

int main() {
    rolldie();
    char again;
    cin >> again;
    while (again == 89) {
        rolldie();
        cin >> again;
    }
    return 0;
}

Ответы [ 4 ]

8 голосов
/ 02 февраля 2012

Вы не заполнили свой генератор случайных чисел.Я не собираюсь скачивать ваш zip-файл, но так как вы используете MinGW, я думаю, вы, вероятно, захотите изучить srandom(3) или srand(3).

2 голосов
/ 02 февраля 2012

Перейдите к http://www.boost.org и получите их библиотеку генератора случайных чисел. Это лучший генератор случайных чисел, который я когда-либо видел, особенно для c ++, где действительно трудно найти достойный генератор где-либо.

У них ТОНА действительно классных библиотек для всех видов вещей в с ++, поэтому я настоятельно рекомендую просмотреть их, но это должно решить проблемы, которые у вас возникают из-за слишком предсказуемого вывода. Просто убедитесь, что вы прочитали инструкцию по его использованию и сначала правильно заполнили генератор.

Что касается того, что использовать для начального числа генератора случайных чисел, наиболее распространенным для использования в c ++ является время (NULL) (встречается в time.h или ctime). Это просто возвращает число, представляющее текущее время в секундах с 1 января 1970 года. Так как оно будет возвращать другое значение при каждом запуске программы, это полезно для более простых случайных чисел, и если вы объедините это со случайным генератором boost, ваш вывод должен хорошо выглядеть.

2 голосов
/ 02 февраля 2012

Ну, во-первых, CStdLib.Rand - это не отличный PRNG. Однако я не знаю C ++ достаточно хорошо, чтобы знать, что лучше в мире C ++; Я бы посмотрел на PRNG, рекомендованные для криптографии. Это должно работать достаточно хорошо для большинства целей, не связанных с безопасностью.

Что еще более важно, вы не "посеяли" PRNG. Это не происходит автоматически, как это происходит со встроенными PRNG некоторых других языков, таких как .NET. Если он не высеян, то начальное число всегда будет постоянным (возможно, нулевым), и поэтому поток чисел, создаваемых алгоритмом PRNG, всегда будет одинаковым. Наиболее распространенное начальное число будет основано на текущем времени (предпочтительно с разрешением «тиков», поэтому трудно точно угадать, какая доля миллисекунды была получена вызовом); Другими хорошими источниками исходных данных являются положение курсора мыши, последний доступ к памяти ОЗУ или жесткого диска или действительно случайные данные, доступные с подключенного устройства (серверы для онлайн-казино часто имеют настоящие устройства RNG, которые предоставляют фактически случайные данные о среде который может быть использован для посева PRNG).

0 голосов
/ 02 февраля 2012

Простой ответ:

Вы хотите каждый раз запускать генератор случайных чисел с помощью входных данных из какого-либо источника, будь то система (например, время), пользователь, файл и т. Д.

Подробный ответ:

Генератор случайных чисел по умолчанию rand () в большинстве случаев очень посредственный, но посмотрите более подробный ответ о rand: Как правильно использовать rand () Функция в C ++?

Моя рекомендация:

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

В качестве дополнительного бонуса, она реализована в C и C ++ в различных формах, поэтому ее интеграция в любой проект очень проста.

Например: http://www -personal.umich.edu / ~ wagnerr / MersenneTwister.html

или: http://www.math.sci.hiroshima -u.ac.jp/ ~ м-мат / MT / SFMT /

...