Reputation: 37
I'm working through some questions in the text Principles and Practice using C++ and the specific question I'm having an issue with is the following. A user must think of a number between 1 and 100 then the computer will figure out what the question is by a series of guesses.
The current code works except for the number 1 (due to the rounding down of integers when dividing by 2). I can't seem to think of a way to fix this.
Here is the current source code:
#include <iostream>
using namespace std;
const int MAX_VALUE = 100;
const int MIN_VALUE = 1;
int guess;
int high = MAX_VALUE;
int low = MIN_VALUE;
char choice;
int main(){
cout<<"Think about a number between "<<MIN_VALUE<<" and "<<MAX_VALUE<<". \n\n";
guess = ( high-low ) / 2;
while((high-low)!=1){
cout<<"Is your number less than or equal to "<<guess<<"? \nEnter y or n. \n\n";
cin>>choice;
if(choice=='y' || choice=='Y') {
high = guess;
guess -= ( high - low ) / 2;
}
else if(choice=='n' || choice=='N') {
low = guess;
guess += (high - low ) /2;
}
else cout<<"Incorrect choice."<<endl;
}
cout<<"Your number is: "<<high<<".\n";
system("pause");
return 0;
}
Upvotes: 2
Views: 14719
Reputation: 928
There are three flaws in this program, but only one was adressed which will not work on its own:
The correct exit condition for the loop is while(guess>low)
, neither while(high>low)
nor while(guess!=high)
exit, except when the guessed number is 1 and guess=low
.
The minimum value has to be set to 0, const int MIN_VALUE = 0;
otherwise you need 8 guesses for the number 1, but only 7 questions are allowed. It also prevents the loop from quitting before the condition for the number 1 is met:
When the guessed number is reached, guess will be set to low and the loop exits:
if(high-low==1) guess=low;
else guess -= ( high - low ) / 2;
See the corrected and tested code below:
#include <iostream>
using namespace std;
const int MAX_VALUE = 100;
const int MIN_VALUE = 0;
int guess;
int high = MAX_VALUE;
int low = MIN_VALUE;
char choice;
int main(){
cout<<"Think about a number between "<<MIN_VALUE<<" and "<<MAX_VALUE<<". \n\n";
guess = ( high-low ) / 2;
while(guess>low){
cout<<"Is your number less than or equal to "<<guess<<"? \nEnter y or n. \n\n";
cin>>choice;
if(choice=='y' || choice=='Y') {
high = guess;
if(high-low==1) guess=low;
else guess -= ( high - low ) / 2;
}
else if(choice=='n' || choice=='N') {
low = guess;
guess += (high - low ) /2;
}
else cout<<"Incorrect choice."<<endl;
}
cout<<"Your number is: "<<high<<".\n";
return 0;
}
Upvotes: 1
Reputation: 1221
What's your thinking behind choosing while((high-low)!=1)
as your while expression?
Your code is basically saying - when the difference between high
and low
is 1, the correct number must be high
. That's why it's not working when someone chooses the lowest value ( in this case 1 ).
You need to ensure that the lowest value low
is presented to the user as a guess
.
So - stepping through your code:
Let's use the example where you have a MIN_VALUE
of 1, and the player has chosen 1 as their thought of number. Now, when high
is 3 and guess
is 2, you go through the while loop and because the player answers "Y" when asked if their chosen number is less than or equal to guess
, high
ends up as 2.
And interestingly guess
stays at 2 because it gets reduced by (high-low)/2
. Which rounds down to 0. This means that guess
will never reach the lowest value - and this is a problem.
Continuing - next time your evaluate the while expression, it returns false ( because 2-1 == 1 ).
And you return high
( which is currently 2 ).
So I think you have 2 problems.
1) when you find yourself reducing guess
by 0 then the player's thought of number has to be low
and you should set guess
to be low
to allow this to be presented to the user as the computer's guess.
And 2)
You need to find a way to allow your while loop to be entered, when the difference between high
and low
is 1. Which allows for the possibility of guess
being presented to the player when it is equal to low
.
Someone posted
while(high > low)
which I think is fine.
But you also need to check for when the difference between high
and low
is 1, because a) you don't want to just endlessly reduce guess
by 0 and b) the thought of number must be low
at this point.
So:
while((high>low){
cout<<"Is your number less than or equal to "<<guess<<"? \nEnter y or n. \n\n"` ;
cin>>choice;
if(choice=='y' || choice=='Y') {
high = guess;
if( high-low == 1)
{
guess = low;
}
else
{
guess -= ( high - low ) / 2;
}
}
Upvotes: 2