Skip to content

Instantly share code, notes, and snippets.

@dgodfrey206
Created July 27, 2016 23:04
Show Gist options
  • Save dgodfrey206/7901c23c9c805b3a5e64fc6c4bb701fd to your computer and use it in GitHub Desktop.
Save dgodfrey206/7901c23c9c805b3a5e64fc6c4bb701fd to your computer and use it in GitHub Desktop.
A console based number guessing game
// 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