Проблемы при вызове srand(time(NULL)) внутри функции rollDice

Когда я сначала использовал функцию srand(time(NULL)) в функции rollDice(), это не сработало. Но когда я ставлю его в main, он работает. Это почему? Можете ли вы сказать мне логику?

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int rollDice(void) {
    return (1+rand()%6) + (1+rand()%6);
}
int main(void) {
    int roll;
    srand(time(NULL));          
    roll = rollDice();
    printf("You rolled %d.\n", roll);

    enum Gamestatus {WON,LOST,CONTINUE};
    enum Gamestatus status;

    while(status==CONTINUE){
        printf("You are rolling again: \n");
        printf("You rolled %d\n", roll = rollDice());

        if (targetPoint==roll){
            printf("You win!");
            status=WON;
        }
        else if(7==roll){
            printf("You lost!");
            status=LOST;
        }
        else
            status=CONTINUE;
    }
    return 0;
}

person Lyrk    schedule 22.03.2013    source источник
comment
Что вы имеете в виду под не работает?   -  person ziu    schedule 22.03.2013
comment
Ваша проблема связана с тем, с чем сталкиваются многие, многие люди, впервые пытающиеся использовать интерфейсы случайных чисел, и она была задают снова и снова в Stack Overflow (это не все дубликаты, но почти половина из них).   -  person dmckee --- ex-moderator kitten    schedule 22.03.2013
comment
Когда я сначала помещал srand в rollDice, он каждый раз возвращал 7, но когда я помещал его в main, он давал мне разные результаты, как и ожидалось.   -  person Lyrk    schedule 22.03.2013
comment
Сколько бросков, прежде чем пользователь начнет точно угадывать результат? ;)   -  person autistic    schedule 22.03.2013


Ответы (3)


Допустим, у вас есть миллионы книг с рядами случайных чисел. Прежде чем вы получите случайное число, вам нужно выбрать книгу.

После того, как у вас есть книга, чтобы получить случайные числа, последовательно читайте числа из книги. Смена книги приводит к другой последовательности случайных чисел.
Смена той же книги перезапускает последовательность с первого числа в книге.

srand() выбирает книгу и запускает случайные числа с начала
rand() читает следующее число из выбранной книги

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

Решение: выберите 1 книгу один раз и продолжайте читать числа из нее вечно.

В программе на C, если вы не "выбираете книгу", случайные числа берутся из книги №1 или, другими словами, при отсутствии вызова srand() функция rand() ведет себя так, как будто был вызван srand(1).

person pmg    schedule 22.03.2013
comment
srand(time(NULL)) выбрал бы книгу #1363958819, если бы она была выпущена прямо сейчас :) - person pmg; 22.03.2013

Когда вы выполняете заполнение внутри функции rollDice, а затем вызываете эту функцию в цикле, вы не только заполняете чаще, чем должны, но цикл настолько быстр, что вы задаете одно и то же значение (в одно и то же время). ), что приводит к тому, что rand() возвращает то же значение:

Функцияsrand() устанавливает свой аргумент в качестве исходного для новой последовательности псевдо - случайные целые числа, которые будут возвращены rand(). Эти последовательности можно повторить, вызвавsrand()с тем же начальным значением.

Эмпирическое правило: заполнять только один раз.

Стоит взглянуть на предыдущие вопросы, посвященные этой проблеме:
srand(time(NULL)) не изменяет начальное значение достаточно быстро
Всегда повторяющиеся числа, заданные функцией rand()
функция srand возвращает те же значения и т. д.

person LihO    schedule 22.03.2013

Проблема в том, что функция srand() заполняет генератор случайных чисел, а вы заполняете его текущим временем, которое имеет разрешение в 1 секунду. Таким образом, когда вы вызываете srand() из функции rollDICE(), вы получаете один и тот же результат от rand() при каждом вызове, происходящем в одну и ту же секунду. Когда сработает второй, вы получите результат, отличный от rand().

Вызов srand() внутри main означает, что вы вызываете его только один раз, прежде чем начнете прокручивать, а затем rand() вернет вам последовательность случайных чисел.

person K Scott Piel    schedule 22.03.2013
comment
Но если он запускается один раз, когда я ввожу его в main, почему он дает разные результаты? Я думаю, поскольку он называется одним в главном, он должен давать одно и то же снова и снова. Когда я помещаю его внутрь rollDice, поскольку rollDice вызывается в разное время, он должен выдавать разные числа. Но ситуация не такая.??? - person Lyrk; 22.03.2013
comment
srand() запускает генератор случайных чисел. то есть... он устанавливает псевдослучайную последовательность чисел, которую rand() позже вернет вам. Если вы запустите генератор случайных чисел несколько раз с одним и тем же числом, вы всегда получите один и тот же результат от rand(). Если вы вызываете srand() внутри rollDice() и передаете текущее время, то вы перезапускаете генератор случайных чисел с одним и тем же значением каждый раз, пока время не изменится (секундная стрелка тикает). Когда вы вызываете srand() в main, вы запускаете генератор только один раз, и каждый последующий вызов rand() возвращает новый результат. - person K Scott Piel; 22.03.2013
comment
Большое спасибо за объяснение - person Lyrk; 22.03.2013