2012-04-07 4 views
-1

컴퓨터에서 사용자가 추측해야하는 임의의 숫자를 선택하는 게임을 작성 중입니다. 그런 다음 컴퓨터가 추측해야하는 숫자 (추측 한 숫자)를 선택하는 것은 사용자입니다. 문제는 내가 게임의 두 번째 부분에서 사용하는 rand() 함수가 때로는 새 범위 밖의 숫자를 제공한다는 것입니다. 예를 들어, 새로운 범위가 low = 4이고 high = 10 인 경우, rand()는 12를 제공하는데 이는 올바르지 않습니다. 나는 왜 그 오류를 이해하려고 노력하고 있지만 그것을 찾을 수 없습니다. 나는 Dev-C++에서 글을 쓰고 있습니다. 코드 바로 아래에 출력이 있습니다. 도와 주셔서 감사합니다.rand() 함수가 C++에서 제대로 작동하지 않습니다.

#include<iostream> 
#include<conio.h> 
#include<stdlib.h> 
#include<time.h> 




using namespace std; 

int main() 
{ 
    int computer_guess, nbr, nbrguesses, count_user_guess=0, count_computer_guess=0; 
    char user_comparison; 

    int low=1, high=99; //initialize low to the lower boundary and high to the higher  boundary 

    srand(time(0)); 
    nbr=rand()% 99 + 1; //computer chooses a random number between 1 and 99... 

    do 
    { 
    cout << "guess a number now! " << endl; 
    cin >> nbrguesses;  //user enters the number he guessed... 
    if (nbrguesses>nbr) 
     cout << "too big" <<endl; 
    else if (nbrguesses<nbr) 
     cout << "too small" << endl; 
    else if (nbrguesses==nbr) 
     cout << " you found the correct number! " <<endl; 

    count_user_guess++; //count the number of guesses from the user 
    } 
    while (nbrguesses!=nbr); 

    cout << "you tried " << count_user_guess <<" times to find the right number " <<  endl<<endl; 

    cout << "----------------------------------------------------------------------" << endl; 
    cout << "Now, the computer will guess your number " << endl; 

    do 
    { 
    srand(time(0)); 
    computer_guess=rand()% high + low; //computer guesses the number 
    cout << "computer guess: " << computer_guess <<endl; 
    cout << "is it the correct number?" << endl; 
    cin >> user_comparison;  //if user enter 
    if (user_comparison=='>') // character '>' it means the number guessed by computer is too big 
    { 
     cout << "too big" <<endl; 
     high= computer_guess-1; //high is given a new boundary 
     cout << "***Current value of high = " << high << " and low = " << low << endl; //display current boundaries 

    } 
    else if (user_comparison=='<') //the number guessed by computer is too small 
    { 
     cout << "too small" << endl; 
     low= computer_guess+1; //low is given a new boundary 
     cout << "***Current value of low = " << low << " and high = " << high << endl; //display current boundaries 

    } 
    else if (user_comparison=='=') 
     cout << "Computer found the correct number! " <<endl; 

    count_computer_guess++; //count number of guesses from computer 
    } 
    while (user_comparison!='='); 

    cout << "The computer tried " << count_computer_guess <<" times to find the right number " << endl; 

    cout << "The Game is over now, have a good day!" << endl; 
    getch(); 

    return 0; 

} 

//**************Output****************************************** 

guess a number now! 
50 
too big 
guess a number now! 
25 
you found the correct number! 
you tried 2 times to find the right number 

---------------------------------------------------------------------- 
Now, the computer will guess your number 
computer guess: 11 
is it the correct number? 
> 
too big 
***Current value of high = 10 and low = 1 
computer guess: 3 
is it the correct number? 
< 
too small 
***Current value of low = 4 and high = 10 
computer guess: 12 
is it the correct number? 
+5

그건 스택 오버플로 질문에 대한 ** 너무 많은 코드입니다. 문제가'rand '와 관련된다고 생각된다면 문제를 설명하기 위해 짧은 (즉, <10 줄) 테스트 프로그램을 만들어야합니다. –

+2

'rand'는 확실히 여기서 문제가되지 않습니다. – ildjarn

답변

3

당신은 교체해야 당신의 예에서

computer_guess=rand()%(high- low + 1) + low; 

에 의해

computer_guess=rand()% high + low; 

당신은 낮은 = 4, 10 = 고하지만 당신은 아칸소 싶어했다 0과 6 사이의 andom 번호를 추가하고 4를 더합니다. 0에서 10 사이가 아니므로 최대 14 개까지 결과를 얻을 수 있습니다. 상한선을 포함시키지 않으려면 (간격 [낮음, 높음 [낮은, 높음]) 괄호 안에 +1을 생략해야합니다.

랜드()가 꽤 큰 정수를 반환하는 이유. 그리고 우리는 간격 [a, b]에서 임의의 숫자를 얻고 싶습니다. 우리가 rand() % 5를 취하면, 0,1,2,3 또는 4이므로, [0,4] 간격에서 numer를 얻습니다. 일반적으로 rand() % C는 [0, C-1] 간격으로 난수를 제공합니다.

예를 들어. Rand() % C + D, 간격은 이동합니다 : [D, C-1 + D]. 문제로 돌아가서 간격을 [a, b]로합니다. 그러므로 더 낮은 결합에 대해서는 a = D, 상한에 대해서는 C-1 + D = b를 원한다. 이것을 C = b-D + 1 = b-a + 1로 변환 할 수 있습니다. 그래서 우리는 rand() % (b-a + 1) + a를 사용하고자합니다.

희망 사항은 어떻게 작동하는지 조금 설명하겠습니다.

+0

나는 computer_guess = rand() % high + low 대신에 computer_guess = rand() % (high low) + low를 사용해야하는 이유는 무엇인가? (값 % 100 + 1) ? 나는 그 정의를 따르고 있다고 생각했다. 죄송합니다. 귀하의 솔루션을 이해하려고합니다. – T4000

+1

'low'와 'high'둘 다 포함하려면 'rand() % (high-low + 1) + low'이어야합니다. 그 이유는 'x % m'은 'm'이 가능한 값이고 'x'와 'm'이 양수인 경우 'low'에서 'high'까지 'high-low + 1' 집단. –

+0

그것은 작동하지만, 왜 (높은 - 낮은) + 낮은 경우 내 경우에 rand() 사용하는 올바른 방법입니다 몇 가지 설명을 할 수 있으면 정말 감사하겠습니다. 정말 고맙습니다! – T4000

1

당신은 아주 가까이,하지만이 시도 :

rand()%(high-low)+low;

+0

그것은 그 해결책과 함께 작동합니다. 더 높은 설명이 왜 가능할까요? (높음 - 낮음) + 낮음, 높음 + 낮음. 감사! – T4000

+0

@ T4000 : 무례하지 말고 생각 해보셨습니까? 'rand' 인 척하고 각 숫자를 살펴보고 함수의 출력이 무엇인지 확인하십시오. 아주 분명해야합니다. – ildjarn

+0

@ T4000, ildjarn의 제안은 꽤 좋으므로 단계별로 실행하고 작동 방식을 확인하십시오.어쨌든 그것을 보자.'rand'는 0과 32767보다 큰 숫자 사이의 숫자를 준다. 최대 값이 10이고 min이 1이면 10-1 = 9이므로'rand % 9'의 결과는 0과 9 사이의 숫자 여야합니다. 'rand % 9'의 rsult에 min을 추가하면 범위가 1에서 10 사이가됩니다. – Kiril

1
srand(time(0)); 
computer_guess=rand()% high + low; //computer guesses the number 

먼저, 루프 내에서 srand를 호출하지 않습니다. 프로그램이 시작될 때 한 번만 호출하십시오.

둘째, 그 논리가 잘못되었습니다. 그것은해야한다 :

computer_guess=low + (rand() % (high-low+1)); 

(이 높은 가정 낮음이 포함됩니다 (10)과 저 모두 1 (10)가 허용 추측이다 후, 1 높은 경우 즉,..)

+1

rand를 사용할 때 모듈러스 연산자 '%'를 사용하지 마십시오. 표준 난수 생성기는 매우주기적인 끝 비트 ('%'에 의해 반환되는 비트)를 생성하는 LCG입니다. 대신, 더 많은 랜덤 시작 비트를 얻기 위해 정수 나누기'/'를 사용하여 마지막 비트를 자릅니다. –

+0

@Seth : +1, 동의 또는 더 나은 아직 C/11/TR1의 ''또는 [Boost.Random] (http://www.boost.org/libs/random/) 적절한 배포판을 사용하십시오. – ildjarn

+0

@SethJohnson : 어느 쪽이든, 결과 배포에 대한 보장은 거의 없습니다. 만약 당신이 신경 쓰면,'rand'는 보장을하지 않기 때문에'rand'를 사용해서는 안됩니다. –

관련 문제