2012-04-07 26 views
-1

私は、コンピュータがユーザが推測しなければならない乱数を選択するゲームを書いています。次に、コンピュータが推測しなければならない数字(推測する数字)を選択するのはユーザーです。問題は、ゲームの2番目の部分で使用する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

これは、スタックオーバーフローの問題の** far **コードです。問題が 'rand'と関係していると思われる場合は、問題を示すために短い(つまり<10行)テストプログラムを作成する必要があります。 –

+2

'rand'は確かにここで問題ではありません。 – ildjarn

答えて

3

あなたは交換する必要が

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

によって

computer_guess=rand()% high + low; 

あなたの例では、低= 4と高= 10を持っている。しかし、あなたは、ARをしたいです0から6の間のアンドムの数と4を加えます。0から10の間では1つではなく、14までの結果を得ることができます。上限(範囲[低、高[ )あなたは括弧内の+1を省略しなければなりません。

なぜ

ランド()非常に大きな整数値を返します。そして私たちはそれから間隔[a、b]で乱数を得たいと思っています。 rand()%5を取ると、0,1,2,3または4の数値が得られます。したがって、[0,4]の間隔からです。一般に、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"の両方を含める場合、実際には '%(high-low + 1)+ low'にする必要があります。その理由は、「x%m」は「m」の可能な値を有し(「x」および「m」が正の場合)、「低」から「高」の範囲は「高 - 低+ 1」を有するからである。要素。 –

+0

これはうまくいきますが、私の場合、(高低)+低が正しい方法である理由を説明できれば、本当に感謝します。どうもありがとうございます! – 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'の出力は'rand%9'のrsultにminを追加すると、範囲は1から10の間で変更されます。 – Kiril

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

まず、あなたのループ内srandを呼び出すことはありません。プログラムの起動時に一度呼び出すだけです。

第2に、その論理は間違っています。それは次のようになります。

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

(これはハイとローが含まれています前提として高いが10と低い場合すなわち、1である、そして1および10の両方が許容推測している。。)

+1

randを使用するときは、モジュラス演算子 '%'を使用しないでください。標準の乱数生成器は、非常に周期的な終了ビット( '%'によって返されるもの)を生成するLCGです。代わりに、整数除算 '/'を使用して最後のビットを切り捨てて、よりランダムな開始ビットを取得します。 –

+0

@Seth:+1、合意した、またはより良いですが、C++ 11/TR1の ''や[Boost.Random](http://www.boost.org/libs/random/)を使って適切な配布をしてください。 – ildjarn

+0

@SethJohnson:いずれにしても、結果として得られる分布はほとんど保証されません。あなたが気にしているならば、 'rand'は保証をしないので使用しないでください。 –

関連する問題