Problem with a number guessing game

Started by
15 comments, last by Poro 16 years, 1 month ago
Hello! So now that I have had the enumerator problem solved, I have another problem. I tried to make a number guessing game, where the computer tries to guess the number that player chooses. It just seems that computer never guesses it. I think I have seen it guessing the right number, but the game does not finish. Here is the code:
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    int number;
    
    
    cout << "Welcome to number guessing game. In this game, you will make up a number ";
    cout << "and the computer will try to guess it. Pick a number between 1-100\n" ;
    do
    {
    cout << "\nYour number: ";
    cin  >> number;
    if ( 1> number || number >100 )
       cout << "Your must be between 1-100!";
} while ( 100< number || number <1   );
    
    int tries = 0, compGuess;
   
         
    do
    {
          srand(time(0));
         int compGuess = rand () % 100 +1;
         cout << "\nComputer guesses: " << compGuess << endl;
         ++tries;
         
         if (compGuess > number)
            cout << "Computer guessed too high!\n";
            
         if (compGuess < number)
            cout << "Computer guessed too low!\n";
} while ( compGuess != number);

cout << "\nComputer got your number right! It took " << tries << " guesses! \n";
system("pause");

return 0;
} 
Advertisement
You enter a number b/w 1 & 100
Computer randomly guesses a number between 1 & 100
If it is wrong, it randomly guessess a new number b/w 1&100.

Think about it - that chances of guess correct are 1 in 100 (roughly). So very low. That is probably why you never see it guess correctly, even though it can do many, many iterations. I'm not sure about how well distributed rand() is, so it might infrequently be genereating a certain set of numbers, making it less likely to guess your answer

If you change it to 'tweak' its guess based on if it is too low or too high, then you'll see it quickly guess your number.
I don't think that's the answer I tried it and it can choose the right number but never exits the loop. For example, try changing the range it guesses from 1-2 and choose that as your number, even when it picks the right number it's not breaking the loop. It's not obvious as to why either, because if I print out the two right before the end of the loop it says they are the same, but it won't break the loop.

if you add :
if (compGuess==number)
{
cout <<"equal guess \n";
break;
}

it works.

Also, you don't need to seed the random number generator on every loop, I actually think that makes it less likely to be random since on some occasions the time(0) returns the same value, causing it to pick the same number multiple times.
Your problem is that you create the variable compGuess twice. First you make it outside the guessing loop, where you should, with this line:
int tries = 0, compGuess;
Then you make it inside the loop with this line:
int compGuess = rand() % 100 +1;
You store the guess in the one inside the loop, which is destroyed before
while ( compGuess != number);
is evaluated, so that line references the one you made outside the loop, which is never changed. Your program should work much better if you just change
int compGuess = rand() % 100 +1;
to
compGuess = rand() % 100 +1;
Hmmm yeah, just tried playing with it. If you don't reseed every iteration and add an
 		if(compGuess == number)			break; 
it then works like a charm...I have no idea why that isn't being caught in the while condition though...

Quote:Your problem is that you create the variable compGuess twice.

omg, I can't believe I missed that. But yes, that is definitely the answer
Got it working now, after I removed the int from int compGuess = rand () % 100 +1;. I also moved the random number generator seed outside from the loop, as you suggested , and now the computer gets the number with far less tries. Thanks!
OK, so you've got "something working", but I think you've missed the point of the exercise. Don't feel bad; almost everyone seems to end up with something like this.

But think about it: when you guess the computer's number, do you know what it is? No? So, the computer shouldn't know the number when it's guessing, either. Instead, you pick the number. It's not a variable stored in the program, just like the computer's random number selection isn't a "variable" stored in your brain when you're doing the guessing.

Now, how do you make your decisions for guessing? Based off of what the computer tells you (too high/too low), yes? So, if you want the computer to play "properly", then you need to be able to tell it if its guess is too high or too low. That is, each time the computer guesses, it will prompt for input, and you type in whether it's too high or too low. The program has to read the response, interpret it (potentially the tricky part - depending on exactly what you're willing to accept as a "valid" response from the user), and make its next guess.

Finally, how exactly do you make your decision, once you've been told "too high" or "too low"? If it's too high, you guess something lower; if it's too low, you guess something higher. But you also respect any previous information you got. Basically, at the start, you know a minimum and maximum possible value for the number, and you guess something in between. Based on what you're told, you can revise either your minimum or your maximum, and then guess something in that range. So, try programming in that logic.
Good point, Zahlman. I decided to fix the things you told in your post, and also decided to extend my number game a little bit. I encoutered many problems that I can't understand.

First, I can't understand why the computer replaces my while loop with a smilie? Also, it exits the loop even when input is invalid or N, but I am not sure if that is related to the smilie thing. http://www.imagebam.com/image/a1dabc3489194
while(true)    {              cout << "\nAre you ready? Y for yes and N for no: ";              cin >> ready;                            if(ready = 'y' || 'Y')              {                       cout << ready << endl;                        break;              }                            if(ready = 'n' || 'N')              {                       cout << ready << endl;                       continue;              }                            if(ready != 'n' || 'N' || 'y' || 'Y' )              {                       cout << "Invalid answer!" << endl;              }    }


Then I have problem with my Do loop. It exits from the loop even when it should not. For example, I press L and it exits the loop, even though there is no Break; command and the loop condition is set to True.

do    {    cout << "Did the computer guess your number? H for too high, ";    cout << "R for right number, and L" << endl << "for too low." << endl;    cin >> answer;        if(answer = 'r' || 'R' )              break;    if(answer = 'l' || 'L')    {              compGuess = rand() % compGuess +1;              cout << "Computer guessed: " << compGuess << endl;              tries++;              continue;    }    if(answer = 'h' || 'H')    {              compGuess = rand () % compGuess +50;              cout << "Computer guessed: " << compGuess << endl;              tries++;              continue;    }} while(true);


Then I have a problem with mathematics. I think I have the low part working correctly, so that the computer guesses lower if user says the number is lower, but I am not quite sure about the higher one. So how would I get the computer guessing higher number than the previous, but still under 100? I am currently using
compGuess = rand () % compGuess +51;
, but I very much think that won't work.

Here is the whole code:
#include <iostream>#include <cstdlib>#include <ctime>using namespace std;int main(){    int number;    char ready;        cout << "Welcome to number guessing game. In this game, you will make up a number ";    cout << "and thecomputer will try to guess it. Think about a number between 1-100\n";        while(true)    {              cout << "\nAre you ready? Y for yes and N for no: ";              cin >> ready;                            if(ready = 'y' || 'Y')              {                       cout << ready << endl;                        break;              }                            if(ready = 'n' || 'N')              {                       cout << ready << endl;                       continue;              }                            if(ready != 'n' || 'N' || 'y' || 'Y' )              {                       cout << "Invalid answer!" << endl;              }    }        int tries = 0, compGuess;             srand(time(0));    char answer = 'h';        compGuess = rand () % 100 +1;    cout << "\nComputer guesses: " << compGuess << endl;    ++tries;        do    {    cout << "Did the computer guess your number? H for too high, ";    cout << "R for right number, and L" << endl << "for too low." << endl;    cin >> answer;        if(answer = 'r' || 'R' )              break;    if(answer = 'l' || 'L')    {              compGuess = rand() % compGuess +1;              cout << "Computer guessed: " << compGuess << endl;              tries++;              continue;    }    if(answer = 'h' || 'H')    {              compGuess = rand () % compGuess +50;              cout << "Computer guessed: " << compGuess << endl;              tries++;              continue;    }} while(true);        if(tries != 1)    cout << "Computer guessed your number with " << tries << "guesses!" << endl;    else    cout << "Computer guessed your number with his first guess!" << endl;        system("pause");    return 0;}    


Thanks in advance!
Quote:Original post by Poro
Good point, Zahlman. I decided to fix the things you told in your post, and also decided to extend my number game a little bit. I encoutered many problems that I can't understand.

First, I can't understand why the computer replaces my while loop with a smilie? Also, it exits the loop even when input is invalid or N, but I am not sure if that is related to the smilie thing. http://www.imagebam.com/image/a1dabc3489194
*** Source Snippet Removed ***

Then I have problem with my Do loop. It exits from the loop even when it should not. For example, I press L and it exits the loop, even though there is no Break; command and the loop condition is set to True.

*** Source Snippet Removed ***

Then I have a problem with mathematics. I think I have the low part working correctly, so that the computer guesses lower if user says the number is lower, but I am not quite sure about the higher one. So how would I get the computer guessing higher number than the previous, but still under 100? I am currently using *** Source Snippet Removed ***, but I very much think that won't work.

Here is the whole code:
*** Source Snippet Removed ***

Thanks in advance!


I have no idea what you mean by 'replaces my while loop with a smilie' so can't help you there.

Most of your other problems are because conditionals don't work like they do in english and that's throwing you off. In real life you can say "I don't want to go to the store, the park, or the school" but in C++ you need to say something more like "i dont' want to go to the store or I don't want to go to the park or I don't want to to go the school". So the first if statement in your post

if(ready = 'y' || 'Y')

should really be

if(read == 'y' || ready == 'Y')

Note you also used the 'assignment operator' instead of the 'equality operator'. That is '=' doesn't compare two things against each other it copies the right-handed thing to the left-handed thing. To make it more confusing, due to operator precedence the first part of your if statement to 'run' is just

'y' || 'Y' which is a boolean comparison. 'y' and 'Y' are converted to boolean values (true in this case), then ||'ed with each other. true || true is true. Next ready is assigned true. I recommend revisiting the section on operator precedence in your chosen reference source.

Most of your problems given should be as a result of your confusion. Fix those conditionals and it should work, if not 'fine' at least 'better'. Hope this helps.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

one thing you could do(however this could be horribly inefficient) is add each number to a vector, shuffle the vector, than use an interator to go through the vector and check each iteration to be equal to the user's number.

I did a guessing game same way as you, cept it was between 1-10.

To your current code, makesure you do use the == inside the if statements or any other comparison. Also where you have the:
if(answer = 'h' || 'H')

Replace with:
if(answer == 'h' || answer == 'H')

I know in java, one needs the left variable after an or/and statement. I've always done it that way, so maybe yours works fine in c++.


Also, why are you using while(true)? That will just create an infinite loop. You'll want to rework them as do loops with a proper while condition, much like this:
do    {              cout << "\nAre you ready? Y for yes and N for no: ";              cin >> ready;                            if(ready = 'y' || 'Y')              {                       cout << ready << endl;                        break;              }                            if(ready = 'n' || 'N')              {                       cout << ready << endl;                       continue;              }                            if(ready != 'n' || 'N' || 'y' || 'Y' )              {                       cout << "Invalid answer!" << endl;              }    }while (ready != 'y' || ready != 'Y');


This topic is closed to new replies.

Advertisement