Reputation: 79
I am trying to create a game where the AI is trying to guess the number the user is thinking through a series of questions.
Example:
Is your number greater than 50? (y/n)
n
Is your number greater than 25? (y/n)
y
Is your number greater than 38? (y/n)
y
Is your number greater than 44? (y/n)
n
Is your number greater than 41? (y/n)
y
Is your number greater than 43? (y/n)
y
The number you're thinking of is 44.
I understand you have to set a new upperLimit and lowerLimit based on what the user enters and then return the average of the new limits. My code does not work well.
What my code does if I'm thinking of the number 59.
Is your number greater than 50? (y/n)
y
Is your number greater than 75? (y/n)
n
Is your number greater than 62? (y/n)
n
Is your number greater than 56? (y/n)
y
Is your number greater than 59? (y/n)
n
Is your number greater than 57? (y/n)
y
Is your number greater than 58? (y/n)
y
Is your number greater than 58? (y/n)
y
Is your number greater than 58? (y/n)
y
Is your number greater than 58? (y/n)
y
Is your number greater than 58? (y/n)
Any advice/tips/help is greatly appreciated!
My code:
public void play(int lowerLimit, int upperLimit) {
instructions(lowerLimit, upperLimit);
while (lowerLimit != upperLimit) {
if(isGreaterThan(average(lowerLimit, upperLimit))) {
lowerLimit = average(lowerLimit, upperLimit);
} else {
upperLimit = average(lowerLimit, upperLimit);
}
}
System.out.println("The number you're thinking of is " + lowerLimit);
}
public boolean isGreaterThan(int value) {
System.out.println("Is your number greater than " + value + "? (y/n)");
String answer = reader.nextLine();
return answer.equals("y");
}
public int average(int firstNumber, int secondNumber) {
return (firstNumber + secondNumber) / 2;
}
Upvotes: 0
Views: 794
Reputation: 3048
Here is a pretty solution for your program:
Code:
public class Program {
public static void main(String[] args) {
System.out.println("The number you're thinking of is " + new Program().play(0, 100));
}
public void instructions(int lowerLimit, int upperLimit) {
//xxx
}
public int play(int lowerLimit, int upperLimit) {
instructions(lowerLimit, upperLimit);
Scanner reader = new Scanner(System.in);
while (true) {
switch (upperLimit - lowerLimit) {
case 0:
return lowerLimit;
case 1:
System.out.println("Is your number " + upperLimit + "? (y/n)");
boolean upper = "y".equals(reader.nextLine());
return upper ? upperLimit : lowerLimit;
default:
int x = (lowerLimit + upperLimit) / 2;
System.out.println("Is your number greater than " + x + "? (y/n)");
boolean greater = "y".equals(reader.nextLine());
if (greater) {
lowerLimit = x + 1;
} else {
upperLimit = x;
}
break;
}
}
}
}
Output:
Is your number greater than 50? (y/n)
n
Is your number greater than 25? (y/n)
y
Is your number greater than 38? (y/n)
y
Is your number greater than 44? (y/n)
n
Is your number greater than 41? (y/n)
y
Is your number greater than 43? (y/n)
n
Is your number 43? (y/n)
n
The number you're thinking of is 42
Upvotes: 0
Reputation: 101
Try this lowerLimit = average(lowerLimit, upperLimit) + 1;
The explanation is very simple. The question you're always asking is if the number is greater than X. If it is, X+1 should become the lower limit, because obviously the number can't be X. The same can't be applied in the other end of the interval, because if your number is X, the answer to the question is it greater is No, so the upperLimit should stay X.
Upvotes: 3
Reputation: 10428
The problem is related to
return (firstNumber + secondNumber) / 2;
This is using integer division, so when firstNumber = 58
and secondNumber = 59
the result is 58
. Therefore the lower bound never converges to the upper bound.
Upvotes: 3