Astonishingly, Aristotle Amato’s always amazingly attired Australian Aboriginal attorney, Amaroo Alba, already anticipating another abundantly absurd argument about amorous Amazonian alligators attacking albino Argentinean alpacas, advised adventurous aunt Alexandra Amundson against abruptly appropriating attention as Arabian Admiral Anwar Al Anawaki accepts an award at Anchorage Alaska’s annual Aleutian American Awesome Alitteration Affair, and all attendees acted appropriately appreciative.
How to Write a Number Guessing Game in C++
28 04 2012Someone on Yahoo Answers had written a number guessing game in C++ for a class and was asking about adding a feature that alerts the player if he had already guessed the number he just entered. His code so far was awful but probably worked well enough for him. He had one goto statement and was counting the number of tries backwards for reasons I can’t imagine. I tried to explain what he should do to make the code easier to read and maintain and how he might add the feature. I wound up deciding to just re-write the whole thing. When I went to submit my answer, Yahoo Answers informed me that it was on break, as in broken. So I’m going to put here where it totally doesn’t belong.
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.
The inner-most loop adds the functionality the student was asking for.
// 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.
Comments : Leave a Comment »
Tags: C++, code, number guessing game, programming, random number generator, stupid games, Yahoo Answers can eat a dick
Categories : Programming
I Totally Intend to Post More
3 01 2012…Maybe I’ll talk about Ron Paul. Maybe I’ll talk about Julian Assange. Maybe I’ll talk about my awesome phone. Maybe I’ll talk about some ridiculous thing my attractive female cousin posted on facebook. Maybe I’ll talk about all the podcasts I listen to.
Did you know that two days ago Howard Stern solicited phone numbers from his twitter followers so he and his wife could drunk dial them? He then tweeted something about each person he called. So, twitter’s fun and you should totally follow me on it.
Comments : Leave a Comment »
Tags: facebook, Howard Stern, twitter
Categories : Caveman Life
Recent Comments