Reputation: 38
I'm studying Bjarne Stroustrup's "Programming Principles and Practice Using C++". In Chapter 4 you are to create a game where the user thinks of an integer between 1 to 100 and the computer should ask questions to guess the answer. Ideally you should have the answer within 7 questions. My intuition is to ask half of each possible range repeated multiple times, e.g. at first when the range possibilities are 1 to 100 ask the question "Is the number you are thinking of greater or equal to 50?".
Here is a part of my solution showing how I was nesting the switch statements:
char user_answer;
cout << "Is the number >= 50? Answer "yes" or "no" by inputting 'y' or 'n': \a\n";
cin >> user_answer;
switch (user_answer)
{
case 'y':
cout << "Is the number >= 75? Answer "yes" or "no" by inputting 'y' or 'n': \a\n";
cin >> user_answer;
switch (user_answer)
{
case 'y':
cout << "Is the number >= 87? Answer yes or no (you get the idea): \a\n";
cin >> user_answer;
switch (user_answer)
{
While hypothetically creating every eventual yes and no case would result in accurate logic, this code is difficult to maintain and create. Should I be attempting this with a while loop? Functions? I attempted a 'for' loop but I could not implement repetition of the logic explained above.
Upvotes: 0
Views: 2012
Reputation: 11
i am just starting out on the Stroustrup coursebook as well. The concepts introduced in chapter 4: 1. iterations 2. Functions 3. vectors After looking at the advice posted here, below is what i have. There were alot of trial and error to make sure that i have captured all the numbers.
cout << "Think of a number from 1 to 100, then press y and enter to continue.\n";
char c;
cin >> c;
int min = 1;
int max = 100;
int half(int, int);
vector<int> number;
for (int i = min; i <= max; i++){
number.push_back(i);
}
cout << "Is your number from " << number[min - 1] << " to " << number[(max / 2) - 1] << "? y/n. \n";
// the aim of this loop is to
// 1. bring up the min number to the halfway point between min and max everytime user answer no.
// 2. bring down the max number to the halfway point everytime user answer yes.
while((cin >> c)&&(min!=max)){
if (c == 'n'){
min = half( min, max);
}
else if (c == 'y'){
max = (max + min) / 2;
}
else
{
cout << "I dont understand your input!\n ";
}
cout << "min: " << min << "\t max: " << max << '\n'; // track the limits of the number
if (min == max){
cout << "Your number is " << min << "!\nPress ctrl-z!\n";
}
else if ((min+max)%2)
cout << " Is your number from " << number[min - 1] << " to " << number[half(min, max) - 2] << "? y/n.\n";
// because we added extra 1 in the half function for odd sums, we have to compensate here by deducting 2.
else
cout << " Is your number from " << number[min - 1] << " to " << number[half(min,max)-1] << "? y/n.\n";
}
keep_window_open(); // part of std_lib header, prompts enter character to exit
}
int half (int x, int y){
if ((x + y) % 2){
return ((x + y) / 2) + 1; // because division always round down, so for odd number division we add 1 to be inclusive.
}
else
return (x + y) / 2;
Upvotes: 1
Reputation: 38
This is for Chapter 4 Exercise 4 p.128 and is my solution after everyone's input. I wasn't able to use peoples suggestions directly due to the limitations of where I am at in the text book and how the question is worded. I was able to guess the users number in 7 questions or less. Thanks to everyone for the input.
// p128 Exercise 4 write a program to make a numbers guessing game. Use if, else,
// <, and =<, to find the answer of a number 1 to 100 in seven questions or less.
#include "C:\Users\X\Documents\Visual Studio 2013\Projects\std_lib_facilities.h.txt"
int main()
{
char user_answer = ' ';
int min_val = 1;
int max_val = 100;
int quest_number = 0;
int x = 0;
cout << "Welcome to the guessing game!\n-------------------------------------------------------------------------------\n\n";
cout << "Please think of a number from 1 to 100.\n";
cout << "This program will guess what number you chose by asking you yes or no questions. Answer truthfully.\n\n";
cout << "Here is my first of seven questions or less. ";
quest_number = max_val / 2;
for (int i = 1; i < 8; ++i)
{
if (min_val == max_val)
{
cout << "Test: min_val = " << min_val << ", max_val = " << max_val << ", i = " << i << "\n\n";
cout << "The number you are thinking of is " << min_val << "!\n";
keep_window_open("~");
return 0;
}
else if (max_val > 100 || min_val < 1 || min_val > 100 || quest_number > max_val || quest_number < min_val)
{
cout << "The program has had an error. Exiting.\n";
keep_window_open("~");
return 0;
}
else if (max_val - min_val == 1)
{
cout << "Is your number greater than " << min_val << "? Answer yes or no by typing 'y' or 'n': \a";
cin >> user_answer;
if (user_answer == 'y')
{
cout << "I figured it out! Your number is " << max_val << "!\n";
keep_window_open("~");
return 0;
}
else if (user_answer == 'n')
{
cout << "I figured it out! Your number is " << min_val << "!\n";
keep_window_open("~");
return 0;
}
else
{
cout << "That doesn't make sense.";
keep_window_open("~");
return 0;
}
}
cout << "Question " << i << ": Is the number >= " << quest_number << "? Answer yes or no by typing 'y' or 'n': \a";
cin >> user_answer;
if (user_answer == 'y')
{
min_val = quest_number;
cout << "\nTest: the question number = " << quest_number << "\n";
quest_number = min_val + (max_val - min_val) / 2;
cout << "Test: the question number is now = " << quest_number << "\n";
cout << "Test: min_val = " << min_val << ", max_val = " << max_val << ", i = " << i << "\n\n";
}
else if (user_answer == 'n')
{
max_val = quest_number - 1;
cout << "\nTest: the question number = " << quest_number << "\n";
quest_number = min_val + (max_val - min_val) / 2;
cout << "Test: the question number is now = " << quest_number << "\n";
cout << "Test: min_val = " << min_val << ", max_val = " << max_val << ", i = " << i << "\n\n";
}
else
{
cout << "There was an issue with your input.\n";
keep_window_open("~");
return 0;
}
}
}
Upvotes: 0
Reputation: 6717
You should go for a function and tell the function what you want it to do.
Here is a quick example that leaves room for improvement. But you should clearly see that there is a function that gets parameters as an input.
This allows you to use the function multiple times. I think i know the game you want to program, so the next step is to find the math that generates the new values to call the query function again.
#include <iostream>
#include <string>
int QueryRange(int low, int high, int * result)
{
int error = 0;
using std::string;
using std::cout;
using std::endl;
using std::cin;
string str;
cout << "Is your Number n in the following range? " << low << " <= n <=" << high << " (y/n)" << endl;
cin >> str;
if(0 == str.compare("n"))
{
*result = 0;
}
else if(0 == str.compare("y"))
{
*result = 1;
}
else
{
*result = -1;
error = 1;
}
return error;
}
int main(int argc, char ** argv)
{
using std::cout;
using std::endl;
int low = 1;
int high = 100;
int ret;
while(0 != QueryRange(low, high, &ret))
{
cout << "Unable to read your input" << endl;
}
cout << "your answer was " << ((1 == ret) ? "y" : "n") << endl;
return 0;
}
Upvotes: 0
Reputation: 757
You're supposed to think of a way where you write as few duplicate code lines as possible.
Yes, you should use a while loop, and appropriate calculations based on the user's answer to further narrow the number range you're asking on each pass of the loop.
Upvotes: 2
Reputation: 187
You should be thinking about how to make one piece of code that works for every step of the questioning, not a web a if statements.
As an example, you can store an array of possible values [1,100] and have a recurring question that asks whether its larger than the centre of that array.
Depending on the answer you remove the values in the array that are no longer possible and ask again from the new centre of the array. From there you only need a condition check to see if you have an array of size 1 (meaning you know the answer).
Upvotes: 1