-
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.
-
>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. :D 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
}
-
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?
-
>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: ";
}
-
Now that's funky. Lemme go play with it.
-
>Now that's funky.
Indeed. :D
-
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.
-
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.
-
*bow*
Well I am going to bed now. This thread has been amazingy fruitful for me. Thanks everyone!
^5 Prelude
-
Which shows that every statement should be on its own line.
-
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;
}
-
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.
-
Yeah, which is why I removed many things out of main. :D
*off to carry on reading C++ book*
-
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?