2012-06-28 2 views
2

내가 만든 작은 게임에 문제가 있습니다.랜덤 동일한 번호 생성

#include "stdafx.h" 
#include <iostream> 
#include <cstdlib> 
#include <ctime> 
using namespace std; 

int main() 
{ 
int span = 100; 
srand(time(0)); 
int TheNumber = static_cast<double> (rand()) /RAND_MAX * (span -1) +1; 
cout << "You need to guess the number between 1 and " << span << endl; 
int mynumber; 
int numberofAttempts = 0; 

do { 
    cout << ++numberofAttempts <<" Attempt: "; 
    cin >> mynumber; 
    if (mynumber > TheNumber) 
     cout <<"Lower!" << endl; 
    else if (mynumber < TheNumber) 
     cout <<"Higher!" << endl; 
} while (mynumber != TheNumber); 

cout << "SUCESS!!!" << endl; 
return 0; 
} 

게임은 0-100 사이의 임의의 숫자를 생성하고 추측을해야합니다. 이 코드를 실행 한 후 동일한 숫자가 심지어 8 번 (내 경우 2 번)을 생성했습니다.

나는 절대 난수가없고 어떤 수학 공식이나 무엇인가를 사용한다는 것을 알고있다. 나는 srand(time(0))을 사용하면 그것이 현재 시간에 의존한다는 것을 안다. 그러나 내가 어떻게 위에서 "더"무작위로 만들 것인지, 나는 위에서 언급 한 것들이 일어나기를 원하지 않기 때문에.

처음 실행했을 때 결과가 11이었고, 다시 실행 한 후 (올바른 숫자를 추측 한 후) 시간이 변경되었지만 여전히 11이었습니다.

+0

추측 한 후 (몇 초가 지나야 함) 마지막 부분을 방금 업데이트했습니다. 숫자는 여전히 동일합니다. – Marink

+0

TheNumber의 선언을'int TheNumber = rand() % 100 + 1;' – jrok

+1

@jrok, 나쁜 조언으로 변경하십시오. 'rand()'의 하위 비트는 랜덤하지 않습니다. –

답변

3

[ADDITION1]

당신이 진정으로 더 나은 난수 생성을 조사하고자하는 경우는, 다음이 시작하는 좋은 알고리즘 : 그 어떤 "하지만 기억

http://en.wikipedia.org/wiki/Mersenne_twister

은 Computer Generated "(즉, 수학적으로 생성 된) 난수는 단지 의사 난수입니다. Pseudo-random은 알고리즘의 출력이 정규 분포를 가지지 만 입력 시드를 알고있는 경우 진정으로 결정적이라는 것을 의미합니다. 진정한 난수는 완전히 비 결정적입니다.

[ORIGINAL] 단순히 다음 줄 중 하나를 시도해보십시오 후, 두 번에 그 결과를 캐스팅하지 않습니다,

(rand()) /RAND_MAX * (span -1) +1 

또한 :

rand() % (span + 1); // This will give 0 - 100 
rand() % span;  // this will give 0 - 99 
rand() % span + 1; // This will give 1 - 100 

대신 int에 배치하십시오.

는 또한 여기 봐 : 주석에 대한 응답으로

http://www.cplusplus.com/reference/clibrary/cstdlib/rand/

!

rand()/(span + 1); 

후 0과 100 사이의 값을 얻기 위해, 다음 랜드의 출력 값은 실제로 0 (* 100, 100) 사이해야 할 것이며, 이러한 성격은 될 것이다 : 당신이 사용하는 경우 보장. 이것은 단순한 분열 때문입니다. rand()가 101 - 201을 생성 할 때 1의 값이 본질적으로 튀어 나올 것이고, rand()가 202 - 302 등의 값을 출력 할 때 2가 나올 것입니다.

이 경우에는 100 * 100이 10000 일 때만 빠져 나갈 수 있으며 32 비트 공간에서는 이보다 큰 정수가 분명히 있지만 일반적으로 나누기를 수행하면 제공되는 전체 숫자 공간 활용!

+0

당신은 rand()/(span + 1)을 의미합니다; 왜냐하면 왼쪽 피연산자는 double을 사용하기 때문에 %를 사용할 수 없기 때문입니다. 그럼 이것도 똑같은 결과를 낳았습니다. 더 많은 시도에서 동일한 번호가 생성됩니다 (프로그램을 다시 실행해야하기 때문에 그 사이에 시간이 있습니다). – Marink

+0

아니, 내가 뭘 넣어 의미, 여기보세요! http://www.cplusplus.com/reference/clibrary/cstdlib/rand/ – trumpetlicks

+0

죄송합니다.이 웹 사이트에서 죄송합니다. static_cast 을 삭제하는 것을 잊어 버렸습니다. 이것은 트릭을 했어, 고마워. – Marink

1

먼저 rand()/RAND_MAX은 0과 1 사이의 숫자를 제공하지 않으므로 0을 반환합니다. 이는 rand_MAX가 rand()의 결과에서 0 번에 맞기 때문입니다. 둘 다 정수이므로 정수 나누기에서는 부동 소수점 숫자를 반환하지 않습니다.

둘째, RAND_MAX는 INT와 크기가 같을 수 있습니다. RAND_MAX에 무언가를 곱하면 오버플로가 발생합니다.

+1

그는'rand()'를 double 형으로 캐스팅하고 있습니다. –

+0

이 경우 rand()는 0과 RAND_MAX 사이의 난수를 제공하여 1의 범위와 span (int span = 100) 사이에 하나의 숫자를 생성하게하고, RAND_MAX로 나눕니다 (그러면 범위는 0과 1). – Marink

2

rand()에는 여러 가지 문제가 있습니다. 여러분은 그들 중 하나에 빠져 들었습니다. 처음 몇개의 값은 "무작위"가 아닙니다. rand()을 사용해야하는 경우 처음 네 개 또는 결과를 rand()에서 삭제하는 것이 좋습니다.

srand (time(0)); 
rand(); 
rand(); 
rand(); 
rand(); 

rand() 또 다른 문제는 하위 비트에도 상기 해킹 후 악명이 아닌 임의의 점이다. 일부 시스템에서는 최하위 비트가 0,1,0,1,0,1, ...로 바뀝니다. 나머지보다 몫을 사용하는 것과 같이 상위 비트를 사용하는 것이 항상 좋습니다.

기타 문제 : 비 임의성 (rand()의 대부분의 구현에는 무작위 테스트가 실패 함) 및 짧은주기. 이 모든 문제들과 함께, 가장 좋은 조언은 rand() 이외의 것을 사용하는 것입니다.