Thread: Second Program

  1. #16
    Registered User cyberCLoWn's Avatar
    Join Date
    Dec 2003
    Location
    South Africa
    Posts
    124
    I'm not too sure why you say that int y is uninitialized.

    I was also wondering about the endl thing. One tutorial I read used it all the time, othertimes it used \n. The book I'm reading now uses \n and in future efforts I will use \n.

    What else could I use besides system ("cls");? Remember, this is only my second program.

  2. #17
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I'm not too sure why you say that int y is uninitialized.
    When you declare a local variable (eg.)
    Code:
    int main()
    {
      int y;
    }
    The contents of that variable are indeterminate, you have no idea what's there and any attempt to access the variable at this point would be illegal. You can assign to it, but you can't read from it. In other words:
    Code:
    int main()
    {
      int y;
      int x = 4;
    
      while ( y != x ) {
        // Do something
      }
    }
    The test y != x reads accesses y illegally since y is still uninitialized. x is okay though because we put the value of 4 in it. One way to fix this is to just give y a value that is assured not to be x until you can get to a point where y gets a value you can really use:
    Code:
    int main()
    {
      int y = -1;
      int x = 4; // Never less than 0
    
      while ( y != x ) {
        cout<<"Enter y: ";
        cin>> y;
    
        // Do something
      }
    }
    >What else could I use besides system ("cls");?
    Do you really need to clear the screen? Like I said, most of the time it isn't a necessity and can be avoided. If you do then you've already stepped into the realm of nonportability, so you should work on performance and damage control. Performance can be acquired through the use of compiler extensions. It's up to you to read the documentation and figure out what your implementation is capable of. However, since this is your second program I can be a little more tolerant of performance. Concerning damage control when it comes to portability, you want to separate any nonportable constructs from the rest of the program so that they are easier to port to different implementations. The most trivial way is to use a separate function to hide the implementation of actually clearing the screen:
    Code:
    #include <cstdlib>
    
    // Easily changed
    void screen_clear()
    {
      system ( "CLS" );
    }
    
    int main()
    {
      clear(); // Calls clear a lot, but that's okay. Porting is easier
    }
    My best code is written with the delete key.

  3. #18
    Registered User cyberCLoWn's Avatar
    Join Date
    Dec 2003
    Location
    South Africa
    Posts
    124
    Code:
    // THE GUESSING GAME by CC
    // This is a simple game that will randomly
    // pick a number that the user must try to
    // guess. The user gets 5 tries. My second
    // program actually. 
    // Last updated: 08/12/2003
    //
    // Changes:
    //          Added score system
    //          Code cleanups
    //          Added 'tries'
    //          Changes suggested by CBoard
    //              -Use new header files
    //              -Remove int Count
    //              -Changed RNG a bit
    //          Rearranged variables
    //          Moved system("cls") to it's own function
    //          Initialised variable y
    
    #include <ctime>
    #include <cstdlib>
    #include <iostream> 
    using namespace std;
    
    //Prototypes
    void screen_clear();
    
    // Global variables for RNG
    const int LOW = 0;
    const int HIGH = 100; 
    
    int main()
    {   
        char again = 'y';
        int x, y, final, limit;
        int score = 0; // Starting value of user's score
        int tries = 0; // How many times user has played
        y = -1;
        
        ////////// RANDOM NUMBER GENERATOR ///////////
        srand(static_cast<unsigned int>(time(0))); 
        //////////////////////////////////////////////
        
        // The main loop   
        while (again == 'y')
        {   
            limit = 0;    // limit needs to be reset every loop repeat
              
            screen_clear();
            cout << ":: THE GUESSING GAME ::\n";
            cout << "I'm going to think of a number and you must try to guess it.\n";
            cout << "You have five guesses. Don't worry, I'll give you a hint if you go wrong.\n\n";
            cout << "The number is between 0 and 100. Ready? Let's go...";
            cout << "\n\n|| Your score is: " << score << '\n';
            cout << "|| Tries: " << tries << "\n\n";
            
            x = rand() % (HIGH - LOW + 1) + LOW;
            
            while ((y != x) && (limit < 5)) 
            {
                    cout << limit + 1 << ". Enter your guess: "; cin >> y;
                    
                    if (y > x)
                    {
                                    cout << "The number: " << y << " is TOO HIGH!\n\n";
                    }
                    else if (y < x)
                    {
                                    cout << "The number: " << y << " is TOO LOW!\n\n";
                    }
            limit++;
            } 
            
            if (y == x)
            {
                    cout << "\nCongrads! You guessed the number.";
                    score++;
            }
            else
            {
                    cout << "Sorry, you didn't get it.\n";
                    cout << "The number was: " << x;
                    score--;
                    // Keeping score always positive or equal
                    if (score < 0)
                    {
                                    score = 0;
                    }
            }
    
            cout << "\n\n\nWould you like to play again? [y/n]\n"; 
            cin >> again;
            tries++;
        }     
        return 0;
    }
    
    void screen_clear()
    {
        system ( "CLS" );
    }
    Everything better?

    I'm just wondering, when this program asks for you to enter your guess and you enter a letter it goes all haywire. This makes sense as it's expecting an interger not a character. How could I prevent the program from doing this?
    Last edited by cyberCLoWn; 12-07-2003 at 05:27 PM.

  4. #19
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >How could I prevent the program from doing this?
    You can check cin for success:
    Code:
    #include <limits> // Add this for numeric_limits
    
    ...
    
    if ( !( cin>> y ) ) {
      cin.clear(); // Clear the errors
      cin.ignore ( numeric_limits<streamsize>::max(), '\n' );
      cerr<<"Invalid input, try again: ";
    }
    My best code is written with the delete key.

  5. #20
    Registered User cyberCLoWn's Avatar
    Join Date
    Dec 2003
    Location
    South Africa
    Posts
    124
    Now that's funky. Lemme go play with it.

  6. #21
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Now that's funky.
    Indeed.
    My best code is written with the delete key.

  7. #22
    Registered User cyberCLoWn's Avatar
    Join Date
    Dec 2003
    Location
    South Africa
    Posts
    124
    Code:
            while ((y != x) && (limit < 5)) 
            {
                    cout << limit + 1 << ". Enter your guess: "; cin >> y;
    
                    while ( !( cin >> y ) )  
                    {
                                    cin.clear();
                                    cin.ignore ( numeric_limits<streamsize>::max(), '\n');
                                    cerr << "\nInvalid input, try again... \n";
                                    cout << "Enter a valid guess: "; cin >> y;
                    }
                                                               
                    if (y > x)
                    {
                                    cout << "The number: " << y << " is TOO HIGH!\n\n";
                    }
                    else if (y < x)
                    {
                                    cout << "The number: " << y << " is TOO LOW!\n\n";
                    }                  
                    
            limit++;
            }
    That is what the code looks like at the moment. It's very late now and I cannot work out why it's not working. See, I type in a number, then nothing happens. When I type in a number again it moves onto the if and else if statement. When I type in a letter it enters the loop, and when a valid number is entered as requested by the loop, it is required to be entered twice before moving out of the loop. Any ideas? Hope this makes sense.

  8. #23
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Code:
    cout << limit + 1 << ". Enter your guess: "; cin >> y;
    while ( !( cin >> y ) )
    {
      ...
      cout << "Enter a valid guess: "; cin >> y;
    }
    You have two redundant calls to cin>>, the second call (in red) is protected by your l33t (too much megatokyo there, Prelude) safe input loop. This is the one you want to keep. The two you don't want are colored blue.
    My best code is written with the delete key.

  9. #24
    Registered User cyberCLoWn's Avatar
    Join Date
    Dec 2003
    Location
    South Africa
    Posts
    124
    *bow*

    Well I am going to bed now. This thread has been amazingy fruitful for me. Thanks everyone!

    ^5 Prelude

  10. #25
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Which shows that every statement should be on its own line.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #26
    Registered User cyberCLoWn's Avatar
    Join Date
    Dec 2003
    Location
    South Africa
    Posts
    124
    Agreed CornedBee.

    Here is what I have done today.

    Code:
    // THE GUESSING GAME by CC
    // This is a simple game that will randomly
    // pick a number that the user must try to
    // guess. The user gets 5 tries. My second
    // program actually. 
    // Last updated: 08/12/2003
    //
    // Changes:
    //          Added score system
    //          Code cleanups
    //          Added 'tries'
    //          Changes suggested by CBoard
    //              -Use new header files
    //              -Remove int Count
    //              -Changed RNG a bit
    //          Rearranged variables
    //          Moved system("cls") to it's own function
    //          Initialised variable y
    //          Added check for non-number guesses (thanks Prelude)
    //          Made numeric_check function
    //          Removed things out of main and into functions
    
    #include <limits>
    #include <ctime>
    #include <cstdlib>
    #include <iostream> 
    using namespace std;
    
    //Prototypes
    void screen_clear();
    void numeric_check(int y);
    void intro();
    void score_tries(int score, int tries);
    void high_low(int x, int y);
    int play_again(char again);
    int enter_guess(int y);
    int compare_x_y(int x, int y, int limit);
    int right_wrong (int y, int score, int x);
    
    // Global variables for RNG
    const int LOW = 0;
    const int HIGH = 100; 
    
    int main()
    {   
        char again = 'y';
        int x, y, final, limit;
        int score = 0; // Starting value of user's score
        int tries = 0; // How many times user has played
        y = -1;        // Giving y an arbitrary value
        
        ////////// RANDOM NUMBER GENERATOR ///////////
        srand(static_cast<unsigned int>(time(0))); 
        //////////////////////////////////////////////
        
        // The main loop   
        while (again == 'y')
        {   
            limit = 0;    // limit needs to be reset every loop repeat
              
            screen_clear();
            intro();
            score_tries(score, tries);
            
            // Part of the RNG
            x = rand() % (HIGH - LOW + 1) + LOW;
            
            y = compare_x_y(x, y, limit);
            score = right_wrong(y, score, x);
            again = play_again(again);
            
            tries++;
        }     
        return 0;
    }
    
    void screen_clear()
    {
        system ( "CLS" );
    }
    
    void numeric_check(int y)
    {
        cin.clear();
        cin.ignore ( numeric_limits<streamsize>::max(), '\n');
        cerr << "\nInvalid input. Enter a valid guess: ";
    }
    
    int right_wrong(int y, int score, int x)
    {
        if (y == x)
        {
            cout << "\nCongrads! You guessed the number.";
            score++;
        }
        else
        {
        cout << "Sorry, you didn't get it.\n";
        cout << "The number was: " << x;
        score--;
        // Keeping score always positive or equal
            if (score < 0)
            {
                    score = 0;
            }
        }
        return score;
    }
    
    void intro()
    {
        cout << ":: THE GUESSING GAME ::\n";
        cout << "I'm going to think of a number and you must try to guess it.\n";
        cout << "You have five guesses. Don't worry, I'll give you a hint if you go wrong.\n\n";
        cout << "The natural number is between 0 and 100. Ready? Let's go...";
    }
    
    int play_again(char again)
    {
        cout << "\n\n\nWould you like to play again? [y/n]\n"; 
        cin >> again;
        return again;
    }
    
    void score_tries(int score, int tries)
    {
        cout << "\n\n|| Your score is: " << score << '\n';
        cout << "|| Tries: " << tries << "\n\n";
    }
    
    void high_low(int x, int y)
    {
        if (y > x)
        {
            cout << "The number: " << y << " is TOO HIGH!\n\n";
        }
        else if (y < x)
        {
            cout << "The number: " << y << " is TOO LOW!\n\n";
        }
    }
    
    int enter_guess(int y)
    { 
        while ( !(cin >> y) )
        {
            numeric_check(y);
        }
        
        return y;
    }
    
    int compare_x_y(int x, int y, int limit)
    {
        while ((y != x) && (limit < 5)) 
        {
            cout << limit + 1 << ". Enter your guess: ";
                    
            y = enter_guess(y);
            high_low(x, y);                
            limit++;
        } 
        return y;
    }

  12. #27
    Registered User
    Join Date
    Nov 2003
    Posts
    53
    also new at c++ but as said before the only advide i got is to keep your main short and simple...it will help a lot when you start makeing larger programs or if you want someone else to help you with it.
    Its all a matter of willpower

  13. #28
    Registered User cyberCLoWn's Avatar
    Join Date
    Dec 2003
    Location
    South Africa
    Posts
    124
    Yeah, which is why I removed many things out of main.

    *off to carry on reading C++ book*

  14. #29
    Tha 1 Sick RAT
    Join Date
    Dec 2003
    Posts
    271
    Shout out to you cyber. I'm also new and Using a Herbert Schildt book. ("The Complete Reference to C++") 's quite good actually. But I do think Oluf is right. I tend to just insert the values in main rather than write code that makes requests and waits for response to test the prog. (Check my post with attached code) 's what you mean, right Oluf?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Issue with program that's calling a function and has a loop
    By tigerfansince84 in forum C++ Programming
    Replies: 9
    Last Post: 11-12-2008, 01:38 PM
  2. Need help with a program, theres something in it for you
    By engstudent363 in forum C Programming
    Replies: 1
    Last Post: 02-29-2008, 01:41 PM
  3. Replies: 4
    Last Post: 02-21-2008, 10:39 AM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM