Created
July 27, 2016 23:04
-
-
Save dgodfrey206/7901c23c9c805b3a5e64fc6c4bb701fd to your computer and use it in GitHub Desktop.
A console based number guessing game
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// NumberGuessing.cpp : Defines the entry point for the console application. | |
// | |
#include "stdafx.h" | |
#include <iostream> | |
#include <ctime> | |
#include <vector> | |
#include <numeric> | |
#include <limits> | |
#include <string> | |
#include <cassert> | |
// Number guessing game that shows your progress | |
class GuessNumber { | |
private: | |
int limit = 20; // default limit | |
std::vector<int> values; | |
int ans, valuesLeft; | |
bool queried; | |
public: | |
GuessNumber(bool defaultLimit) { | |
std::srand(static_cast<unsigned>(std::time(nullptr))); | |
reset(defaultLimit); | |
} | |
GuessNumber() : GuessNumber(false) { | |
} | |
// contains main program | |
void start(); | |
private: | |
// returns true if choice == ans | |
bool validateAnswer(int choice); | |
// resets state variables | |
void reset(bool = true); | |
// asks user to restart (optionally asks user for limit) | |
bool queryRestart(); | |
// gives a random number within a range | |
int randomRange(unsigned min, unsigned max) { | |
return min + (rand() % (int)(max - min + 1)); | |
} | |
// let's user know if choice is greater than or less than ans | |
void printSelectionMessage(int choice); | |
}; | |
void GuessNumber::reset(bool defaultLimit) { | |
if (!defaultLimit) { | |
system("cls"); | |
std::cout << "# of choices: "; | |
assert(std::cin >> limit); | |
} | |
queried = false; | |
values.resize(limit); | |
valuesLeft = values.size(); | |
std::iota(values.begin(), values.end(), 1); | |
ans = randomRange(1, limit); | |
} | |
void GuessNumber::start() { | |
int choice = 0; | |
while (true) { | |
// new line before the program end message | |
std::cout.put('\n'); | |
// check for a valid answer (so we can either end the game or reset state | |
// (for a restart) before anything else is done. | |
if (validateAnswer(choice)) { | |
// if the user wants to restart, reset state | |
// otherwise break from the loop | |
if (queryRestart()) { | |
// after state is cleared, game will resume as normal | |
reset(false); | |
} | |
else { | |
// break from this loop if user doesn't restart | |
break; | |
} | |
} | |
// clear screen each frame | |
system("cls"); | |
// state data | |
if (queried) { | |
printSelectionMessage(choice); | |
} | |
else { | |
// new line before the values | |
std::cout.put('\n'); | |
} | |
bool oneChoiceLeft = false; | |
// loop through the values and update available numbers | |
for (int i = 0; i < limit; ++i) { | |
if (queried) { | |
if (values[i] != -1) { | |
// mark the numbers greater than or equal to (if choice > ans) or | |
// less than or equal to (if choice < ans) as removed | |
if ((choice < ans && i+1 <= choice) || (choice > ans && i+1 >= choice)) { | |
values[i] = -1; | |
valuesLeft--; // decrement number of available choices | |
} | |
} | |
} | |
// print the values (X for removed) | |
if (values[i] == -1) | |
std::cout << "X "; | |
else | |
std::cout << values[i] << ' '; | |
// If there's one choice left set a flag that the | |
// answer should be given immediately | |
if (valuesLeft == 1) { | |
oneChoiceLeft = true; | |
// rather than breaking, let the loop finish | |
// so that all values are written out. | |
} | |
} | |
// one choice left, so display answer | |
if (oneChoiceLeft) continue; | |
std::cout << "\nChoose your number (" << valuesLeft << " left): "; | |
std::cin >> choice; | |
// a valid answer is one that is within the limit ({1,..,limit}) | |
queried = (choice >= 1 && choice <= limit); | |
} | |
std::cout << "Thank you for playing. Press any key to exit.\n"; | |
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); | |
std::cin.get(); | |
} | |
bool GuessNumber::validateAnswer(int choice) { | |
if (queried) { | |
if (valuesLeft == 1) { | |
std::cout << "\nGAME OVER. Answer: " << ans << '\n'; | |
return true; | |
} | |
else if (choice == ans) { | |
std::cout << "You got it, the answer is " << choice << '\n'; | |
return true; | |
} | |
} | |
return false; | |
} | |
void GuessNumber::printSelectionMessage(int choice) { | |
std::cout << "The answer is "; | |
if (ans < choice) std::cout << "less "; | |
if (ans > choice) std::cout << "greater "; | |
std::cout << "than " << choice << "\n"; | |
} | |
bool GuessNumber::queryRestart() { | |
std::cout << "restart: r\nquit: q\n"; | |
char c; | |
if (std::cin >> c && c == 'r') { | |
return true; | |
} | |
return false; | |
} | |
int main() | |
{ | |
GuessNumber game; | |
game.start(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment