Thread: Problem with extremely beginner exercise

  1. #1
    Registered User
    Join Date
    May 2007
    Posts
    77

    Problem with extremely beginner exercise

    Hi. I am going through beginner exercises on a C++ tutorial. I came across the number guesser, and I was able to make a once-through program very easily. However, when I try to make a "play again" option, I get multiple playtime errors. It plays the first time, but when I guess the number (and for some reason, every time I play the program, that number is 39... is that supposed to happen?), it displays a blank line. Then, whether I input "y" or "n", it briefly displays my "win" output and asks if I want to play again before it automatically exits. I have no idea where to look.

    Here is how I set it up:

    Code:
    #include "stdafx.h"
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    
    
    using namespace std;
    
    int main()
    {
    	srand(time_t(0)); //seed random number generator
    
    	int theNumber = rand() % 100 + 1; //random number between 1 and 100
    	int tries = 0;
    	int guess;
    	char again;
    
    	cout << "Welcome to Guess My Number!\n\n";//Welcome line
    
    	do
    	{
    		cout << "You have eight tries to guess the number.\nEnter a guess: ";//Rules
    		do
    		{
    			
    			cin >> guess;//Player input
    						
    			if (guess > theNumber)
    				cout << "\nToo high! Guess again: ";
    			
    			if (guess < theNumber)
    				cout << "\nToo low! Guess again: ";
    			
    			++tries;
    			
    		} while (guess != theNumber,tries <7);//While loop, for wrong guess, and guesses number less than 8
    	
    		if (guess == theNumber)
    		{
    			cout << "\n\nYou got it!  You guessed the number in " << tries + 1 << " tries!";//Correct answer
    			cout << "\nDo you want to play again (y/n)?";//Play again option
    			cin >> again;
    		}
    
    		if (tries < 7)
    		{
    			cout << "\n\nSorry, you took too many tries.";// Wrong answer, too many guesses
    			cout << "\nDo you want to play again (y/n)?";//Play again option
    			cin >> again;
    		}
    			
    	} while (again == 'y');
    return 1;
    }
    Any help for a total noob will be greatly appreciated.

  2. #2
    Registered User
    Join Date
    May 2007
    Posts
    88
    If you seed the random generator to the same number everytime, you'll get the same pseudorandom set.
    Code:
    srand(time(NULL)); //This is the right way to seed
    Also:
    Code:
    } while (guess != theNumber,tries <7);//While loop, for wrong guess, and guesses number less than 8
    is wrong...does that even compile?

    You shouldn't return 1 from main unless there was an error. There are several other errors with that code, but start with those.
    Last edited by UMR_Student; 05-07-2007 at 09:48 PM.

  3. #3
    Registered User
    Join Date
    May 2007
    Posts
    77
    Quote Originally Posted by UMR_Student View Post
    If you seed the random generator to the same number everytime, you'll get the same pseudorandom set.
    Code:
    srand(time(NULL)); //This is the right way to seed
    Thanks, that's good to know. (edit) Though now that I have tried that, I put exactly what you gave me in there and got this warning:
    warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data
    When I put time_t back in, I still got only 39. Any suggestions?
    Also:
    Code:
    } while (guess != theNumber,tries <7);//While loop, for wrong guess, and guesses number less than 8
    is wrong...does that even compile?
    Actually, it does. I get no errors whatsoever when I compile with Visual Studio.
    You shouldn't return 1 from main unless there was an error. There are several other errors with that code, but start with those.
    Sorry, that was a mistype. I fixed that later, but then had to go back to my previous code and forgot to change that again.

    So how would I make a do...while or a while loop or whatever loop I need to be able to have to requisites?
    Last edited by Molokai; 05-07-2007 at 09:55 PM. Reason: update for solution

  4. #4
    Registered User
    Join Date
    May 2006
    Posts
    903
    Code:
    do
    {
        std::cin.ignore(1000, '\n');
        // your code
    } while(guess != theNumber && tries < 7);

  5. #5
    Registered User
    Join Date
    May 2007
    Posts
    88
    Code:
    srand(static_cast<unsigned int>(time(NULL)));
    
    //You want logical AND
    while (guess != theNumber && tries <7) //This is the correct way
    While I'm at it, try not to put arbitrary numbers like 7 in your code, make constants
    Code:
    const int NUM_TRIES = 7;
    //...
    int main()
    {
    ...
    }
    One more thing
    Code:
    //This
    if (tries < 7) 
    //Should be this
    if (tries > 7)
    Along with Desolation's suggestion, you should be close

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    903
    NULL should never be used. It's an ugly macro where 0 is always a better alternative.

  7. #7
    Registered User
    Join Date
    May 2007
    Posts
    88
    >NULL should never be used. It's an ugly macro where 0 is always a better alternative.

    That's an interesting opinion...

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data
    This warning is ok, and srand(time(0)) is what you should use rather than srand(time_t(0)). If you use time_t(0), you are just casting 0 to a time_t type and passing it to srand, which means you are always seeding srand with 0. If you use time(0), you are getting the current time, so each time you run your program you will be using a different seed. That's what you want.

    The warning is because time(0) returns a time_t, which is different than unsigned int. You can ignore the warning, or cast the value like this (I think): srand(unsigned(time(0));

    Note that there might be some debate whether that is guaranteed to always work, but in practice you should be fine. Feel free to do some searching on the topic if you are interested in the details (eternallyconfuzzled.com has information about the use of rand).

  9. #9
    Registered User
    Join Date
    May 2007
    Posts
    77

    Cool

    Yes! I got it!
    I took your suggestions, and on top of that, I moved most of the variables and constants into the do loop, most important of which was "theNumber", which made it randomize the number to guess each time. That's kind of important I think. I also had to put some manual break in there for reading the number of tries to make it not display the guess again when you went over the limit. There were also a few other small changes that I don't remember the details of.
    Here's my final code for those interested:
    Code:
    // game1.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    
    
    using namespace std;
    
    int main()
    {
    	srand(static_cast<unsigned int>(time(NULL))); //seed random number generator
    
    	char again;
    	
    	cout << "Welcome to Guess My Number!";
    
    	do
    	{
    		const int MAX_TRIES = 7;
    		int theNumber = rand() % 100 + 1; //random number between 1 and 100
    		int tries = 0, guess;
    		std::cin.ignore(1000, '\n');
    		
                    cout << "\nYou have eight tries to guess the number.\nEnter a guess: ";
    		
                    do
    		{							
    			cin >> guess;
    			++tries;			
    
    			if (tries > MAX_TRIES)
    			{
    				break;
    			}
    			if (guess > theNumber)
    			{
    				cout << "\nToo high! Guess again: ";
    			}
    			if (guess < theNumber)
    			{
    				cout << "\nToo low! Guess again: ";
    			}
    			
    		} while (guess != theNumber && tries <= MAX_TRIES);
    	
    		if (guess == theNumber)
    		{
    			cout << "\n\nYou got it!  You guessed the number in " << tries << " tries!";
    		}
    		if (tries > MAX_TRIES)
    		{
    			cout << "\n\nSorry, you took too many tries.";
    		}
    		cout << "\nDo you want to play again (y/n)?";
    		cin >> again;
    	} while (again == 'y');
    return 0;
    }
    Thanks all for your help. This has made me very happy. Any suggestions on what to work on next?

  10. #10
    Registered User
    Join Date
    May 2006
    Posts
    903
    I'd move that constant outside of the do..while loops and all that casting in srand() is really ugly. srand(time(0)) is fine, even though there is a warning.

  11. #11
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,688
    I was always taught to so it this way

    Code:
    srand((unsigned)time(0));
    But the beauty of programming encourages a multiple way to achieve the same result.
    Double Helix STL

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Prelude warns that there is no guarantee that time_t is properly convertible to unsigned int. Her solution is to hash the bytes of the time_t returned by time(). A more C++ oriented example based on her code would be:
    Code:
    unsigned int timeSeed()
    {
        using namespace std;
    
        time_t now = time(0);
        unsigned char* p = reinterpret_cast<unsigned char*>(&now);
    
        unsigned int seed = 0;
        unsigned int seed_multiplier = numeric_limits<unsigned char>::max() + 2U;
        for (size_t i = 0; i < sizeof now; ++i)
        {
            seed = seed * seed_multiplier + p[i];
        }
    
        return seed;
    }
    
    // To seed the PRNG.
    srand (timeSeed());
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Line of data input method
    By larry_2k4 in forum C Programming
    Replies: 2
    Last Post: 04-28-2009, 11:34 PM
  2. Replies: 15
    Last Post: 12-13-2008, 09:32 AM
  3. very basic beginner problem
    By sandingman1 in forum C++ Programming
    Replies: 7
    Last Post: 11-26-2005, 05:48 PM
  4. Beginner Problem
    By knoxmaddog in forum C++ Programming
    Replies: 13
    Last Post: 11-21-2005, 11:16 PM
  5. beginner function problem
    By dellebelle751 in forum C++ Programming
    Replies: 7
    Last Post: 10-30-2002, 07:12 PM