## How to Write a Number Guessing Game in C++

28 04 2012

It works using 3 nested do/while loops. The outer most loop contains the game and loops when our player wants to play again. The loop inside that is the game loop and it runs until a game ending condition is met (the player either guesses correctly or gives up). The loop inside that one gets the player’s guess and re-runs if the guess is outside the range of the game or has already been guessed.

```// includes go here
using namespace std;

// Let's define our constants
const int MIN_NUMBER = 1;
const int MAX_NUMBER = 100;
const int EXIT_VALUE = -1;

int main()
{
// seed the random number generator
srand((unsigned int)time(NULL));

// initialize our program variables
int games = 0;			// counts number of games played
int wins = 0;			// counts number of games won
int total_guesses = 0;	// adds total guesses together to calc the average at the end
char again = 'n';		// will == 'y' or 'Y' if we want to play again

// Let's save our title as a string so we can reuse it latter and ensure it doesn't change.
char* title = "Unfrozen Caveman's Stupid Number Guessing Game";

cout << "*** You are playing " << title << "! ***\n\n";

do // This loop will exit when we don't want to play the game any more
{
// init our per game variables
// set our target to a random number between MIN_NUMBER AND MAX_NUMBER
int target = rand() % (MAX_NUMBER-MIN_NUMBER+1) + MIN_NUMBER;
```

The student’s code had a function to get a random number that wasn’t quite implemented properly. I found it unnecessary (to define an external function), but you can do that if you want. rand() % MAX_NUMBER will give us a random number in the range of 0 and MAX_NUMBER-1 (0 to 99). rand() % (MAX_NUMBER) + MIN_NUMBER will work as long as MIN_NUMBER == 1, but we don’t want our code to break if our constants are changed even if we don’t plan on doing so. If MAX_NUMBER==50 and MIN_NUMBER==25, our random number needs to be constrained by 26 (50-25+1) before 25 is added to ensure the number is within range. I hope that makes sense.

```		int guess = 0;				// record our guess
int guesses = 0;			// count our guesses
bool game_over = false;		// this will == true when reach an end of game condition ( win or lose)

// Let's declare and initialize an array to store all of our previous guesses with
// enough elements to ensure we won't run out. If MAX_NUMBER = 40 and MIN_NUMBER = 20,
// then we need 40-20+1 = 21 elements to cover the maximum number of guesses possible
int old_guess[MAX_NUMBER - MIN_NUMBER + 1];
for (int i=0; i			old_guess[i] = 0;
```

I hope this makes sense too. Worst case scenario is that our player guesses every single wrong answer before “winning”. In that case we need to have enough elements in our old_guess array to cover every single wrong guess (and his final correct one). We could eliminate the +1 here, but that would necessitate checking later on for this highly unlikely case.

```
do // this loop will run until and end of game condition occurs
{
bool good_guess = false;

// This loop ensures that our number is in range and hasn't been guessed already. This
// loop could easily be another do-while loop, as it has to run at least once
while(good_guess == false)
{
// Explain our range and ask for a guess within it.
cout << "Enter a number between " << MIN_NUMBER << " and " << MAX_NUMBER << " (-1 to give up): "; 				cin >> guess;

good_guess = true;

// If the guess is our exit value, skip the other checks
if(guess == EXIT_VALUE)
{}
else if(guess > MAX_NUMBER)
{
cout<<guess<<" is higher than the range of this game. Try again."<<endl;
good_guess = false;
}
else if(guess < MIN_NUMBER)
{
cout<<guess<<" is lower than the range of this game. Try again."<<endl;
good_guess = false;
}
else
{
for (int i=0; i					{
if (guess == old_guess[i])
{
// if the player guesses a number he already tried, he should be verbally abused
cout << "You already guessed that on guess #" << (i+1) << " you idiot!" << endl;
good_guess = false;
}
} // end for
} //end if
} // end while

// Now that we have a valid guess, let's save it in our old_guess array and increment our counter
old_guess[guesses] = guess;
guesses++;

// now for our normal checking
if(guess==EXIT_VALUE)	// Do we have a quitter on our hands?
{
// quitting calls for some verbal abuse
cout << "*** YOU GOD-DAMNED QUITTER!! ***\n";
cout << "The number was " << target << endl << endl; 				game_over = true; 			} 			else if (guess > target)	// Did he guess too high?
cout << guess << " is too high. " << endl;
else if (guess < target)	// Did he guess too low?
cout << guess << " is too low. " << endl;
```

The student’s code did not give “too low” or “too high” hints until the player had guessed five times, drastically reducing the tiny amount of fun present in my (and everyone else’s) version of this game.

```			else if (guess == target)	// This could just be an else statement, because all other possibilities have been covered.
{
if (guesses == 1)
cout << "!!!!HOLY HELL!!!! You fucking RAINMANED that shit! Just " << guesses << " guess!\n\n";
else
cout << "*** YOU GOT IT!! ***\n It took you "<< guesses <				game_over = true;
wins++;
total_guesses += guesses;
}
```

I didn’t want the game to say “It took you 1 guesses” if the player happens to nail it (Rainman it) on the first try, so I added a special vulgar message for such a case.

```
} while (game_over == false);

games++;

cout << "Would you like to play again? "; 		cin >> again;
cout << "\n\n";

} while ((again == 'y') || (again == 'Y'));
```

The student’s code only permitted the player to play 256 times (a curiously square number). I can only guess that this was intended to be like the Nintendo Wii suggesting you go outside and play after playing with it for several hours. You know, cuz number guessing games are so addictive.

```
// lets calculate the average number of guesses it took our player to win
float average = float(total_guesses) / float(wins);
cout << "Thanks for playing " << title << endl;
cout << "You played "<< games <	cout << "with an average of " << average << " guesses per win\n\n";

cout << "Hit enter to exit.\n\n";
cin.ignore();
cin.get();

return 0;
}
```

Wasn’t that fun? So, yeah, I’ve been programming computers as a hobby since I was 12 or so. I’ve spent years away from it, but I’ve been getting back into it lately. Feel free to point out anything you don’t like about my code or to ask questions about it or about your own code. If you want to know how to show code on wordpress.com, check out this thing I just learned. You can no longer find this full code without interruption at PASTEBIN, which is where you should go if you need to share code with others on the interwebs for a fairly limited amount of time.