2012-09-05 3 views
2

을 시드하지 나는 그것은 비록 시드하지 않는 주사위 게임랜덤 주사위

#include <iostream> 
#include <ctime> 
#include <cstdlib> 
#include "dice.h" 
#include "display.h" 
using namespace std; 
int die[6][10]; 
void dice(int times, int dice){ 
    int r; 
    for(int x=0;x<times;x++){ 
     for(int x=0;x<dice;x++){ 
      srand(time(0)); 
      r=(rand() % 5); 
      die[r][x]+=1; 
      cout<<"Die #"<<x+1<<" rolled a "<<r<<endl; 
     } 
    } 

} 

을위한 난수를 생성하기 위해 다음과 같은 기능을 만들었습니다. 각 다이에 동일한 번호가 출력됩니다. 아무도 내가 고칠 수있는 방법을 알고 있습니까?

+0

'rand() % 5'에는 괄호가 필요하지 않습니다. 또한이 표현식은 to에서 4까지의 값을 생성하므로 'die [5]'는 절대 적중하지 않습니다.이러한 종류의 실수를 피하려면 상수를 사용하여 (6과 5를 하드 코딩하는 대신)면의 수를 정의하고 배열 정의에서 해당 상수를 제수로 사용하십시오. –

답변

1

srand()는 반복적으로 호출되는 함수에 있거나 루프가 좋지 않습니다.

메인의 srand()에 전화를 겁니다. 프로그램 당 한 번만 호출하십시오.

+0

이 대답은 분명히 문제를 해결하지만 문제를 일으킨 원인을 설명하지는 못합니다. 문제는 'time()'이 너무 빨리 호출되어 다음 시간 값을 생성하기에 충분한 시간이 경과하지 않았기 때문에 동일한 값을 반환한다는 것입니다. 호출 사이에 더 많은 시간이 지나면 RNG를 시드하는 데 사용 된 값과'rand() '의 결과 값이 더 무작위로 보입니다. – bames53

+0

이것은 실제로 RNG를 사용하여 일련의 숫자를 생성하지는 않지만 각 시리즈에서 첫 번째 값을 얻는 것입니다. 이것은 반드시 RNG를 시드 한 다음 RNG에 의해 생성 된 연속적인 값을 검색하기 위해'rand() '를 여러 번 호출하는 것과 동일한 통계적 특성을 가질 필요는 없습니다. – bames53

+1

나는 설명하는 것이 너무 짧았다. 내 사과. 그런 식으로 말하면 조금은 사실입니다. 실제로 알려진 일부 시드 또는 전달 된 변수 시드가있는 함수에서 실수를 원할 수있는 인스턴스가 있습니다. 마음에 오는 유일한 것 ... 무작위로 생성 된 레벨로 게임을 만들었다 고합시다. 사용자가 srand에 시드를 제공하도록 허용 할 수 있으며, 제공되지 않는 경우 Linux 머신에서/dev/urandom과 같은 시간을 사용할 수 있습니다. srand는 time보다 더 좋은 방법이 많이 있지만, 당신은 이식성을 포기합니다. –

0

srand()를 한 번만 호출하려고합니다. 그래서 약간의 시간이 지나고 있습니다.()는 같은 값을 반환합니다. 따라서 난수 생성기는 같은 위치에서 시작됩니다.

가능하면 기능 전에 srand를 호출하거나 시작하십시오.

1

수행중인 모든 시뮬레이션에 대해 srand()를 한 번만 호출하려고합니다. 그 이유는 각 호출에서 rand()를 다시 시드하여 rand() 값에 바이어스를 부과하기 때문입니다. 이것은 i.i.d를 가정 할 때 특히 중요합니다.

위의 경우 srand()를 루프 밖으로 이동하려고합니다.

3

srand 및 rand 기능이 올바르게 사용되지 않습니다. 난수 생성기를 '시드'한 다음 rand()을 사용하여 RNG에서 연속 값을 검색합니다. 각 시드는 특정 임의성 기준에 맞는 특정 숫자 시퀀스를 생성합니다.

대신, 매번 난수 생성기를 시드 한 다음 임의 순서로 첫 번째 값을 검색합니다. time()이 너무 빨리 호출되어 동일한 시드를 반환하기 때문에 난수 생성기를 동일한 시퀀스의 시작 부분으로 다시 설정하므로 이전에 얻은 동일한 번호를 얻게됩니다.

time()에 의해 반환 된 값이 매번 새로운 시드를 얻을 정도로 충분히 빠르게 업데이트 되더라도 좋은 난수는 보장되지 않습니다. 난수 생성기는 시퀀스에 특정 통계적 특성이있는 일련의 숫자를 생성하도록 설계되었습니다. 그러나 동일한 속성이 다른 시퀀스에서 선택한 값보다 길다는 보장은 없습니다.

결정 성 난수 생성기를 사용하려면 생성기를 한 번만 시드 한 다음 해당 한 시드가 생성하는 값 시퀀스를 소비해야합니다.


다른 점; rand()을 구현하는 데 사용 된 난수 생성기는 역사적으로 매우 좋지 않았습니다. rand()은 재진입 또는 스레드 안전성이 아니며 rand()에 의해 생성 된 값을 원하는 분산으로 변환하는 것이 항상 쉬운 것은 아닙니다.

C++의 경우 더 나은 기능을 제공하는 <random> 라이브러리를 선호합니다. 다음은 <random>을 사용하는 예입니다.

#include <random> 
#include <iostream> 

int main() { 
    const int sides = 6; 
    int groups = 10, dice_per_group = 3; 

    std::uniform_int_distribution<> distribution(1,sides); // create an object that uses randomness from an external source (provided later) to produces random values in the given (inclusive) range 

    // create and seed the source of randomness 
    std::random_device r; 
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; 
    std::mt19937 engine(seed); 

    for (int i=0; i<groups; ++i) { 
     for (int j=0; j<dice_per_group; ++j) { 
      // use the distribution with the source of randomness 
      int r = distribution(engine); 
      std::cout << "Die #" << j+1 << " rolled a " << r << '\n'; 
     } 
     std::cout << '\n'; 
    } 
}