Загадай число

Загадай число

Пользователь загадывает число от 1 до 100. Компьютер пытается его отгадать с трёх попыток. Каждый ход компьютер предлагает пользователю свою догадку и пояснение (на примере числа 65):

Это 65?

0 - меньше, 1 - больше, другое число - угадал

Соответственно пользователь даёт машине подсказку: вводит ноль, если загаданное число меньше предположения компьютера, единицу — если больше, и любое число, если компьютер угадал.

Если компьютер в итоге угадывает, то на экран выводится надпись: "Я угадал. Здорово!", в противном случае, когда попытки заканчиваются, — "Я не угадал. Печально."

Алгоритм должен быть достаточно обобщён и никак не зависеть от величины загаданного числа (покуда оно натуральное и лежит в пределах максимально возможного значения int'а в Java), а также не зависеть от числа попыток, то есть играть одинаково дай ему 3 попытки или 300.

В пояснении будем ориентироваться на пример с числом до 100 и 3 попытками.

Поиск задуманного числа состоит из 2 этапов:

  • Приближение

  • Угадывание

На этапе приближения алгоритму нужно сузить диапазон поиска. Минимально возможное число на первой попытке — 1, максимальное — 100. Число между ними равно (1 + 100) / 2. Это число 50 (остаток отбрасываем). Таким образом алгоритм должен предложить пользователю число 50.

Допустим, что пользователь загадал число больше. Тогда 50 — минимально возможное число, 100 — по-прежнему максимум. Число между ними вычисляется по той же формуле: (50 + 100) / 2. Это число 75. Алгоритм предлагает пользователю вариант 75.

Допустим, что пользователь загадал число меньше 75. Теперь максимально возможное число — 75, а минимум по-прежнему — 50.

Такое приближение может длится сколько угодно. Но в нашем случае третья попытка считается последней. Поэтому мы должны перейти к этапу "угадывание".

Итак, нам нужно угадать число от 50 до 75. Диапазон вариантов: 75 - 50 равен 25. Нужно сгенерировать случайное число от 0 до 25 (не включительно), например, получится 6 и прибавить это число к минимально возможному: 50 + 6 равно 56. Собственно 56 и нужно предложить пользователю как последний вариант.

Весь код на Java может выглядеть так:

public static void main(String[] args) throws Exception {

int attempts = 3; //Количество попыток
int minNumber = 1;
int maxNumber = 100; //Игрок загадывает от minNumber до maxNumber
int guessNumber; //Переменная для хранения догадок компьютера
int hint; //Подсказки пользователя 0 - меньше, 1 - больше, другое число - угадал

Scanner in = new Scanner(System.in); //Scanner считывает консольный ввод

System.out.println("Загадайте число. Начинаем.");

do {

if (attempts > 1) { //Если попытка не последняя, сужаем диапазоп поиска

guessNumber = (maxNumber + minNumber) / 2;
System.out.println("Это " + guessNumber + "?");
System.out.println("0 - меньше, 1 - больше, другое число - угадал");
hint = in.nextInt();

switch (hint) {
case 0:
maxNumber = guessNumber;
break;
case 1:
minNumber = guessNumber;
break;
default:
System.out.println("Я угадал. Здорово!");
System.exit(0);
}

} else { //Если попытка последняя, генерируем случайное число в текущем диапазоне

int range = maxNumber - minNumber; //Диапазон для генерации
guessNumber = new Random().nextInt(range) + minNumber;

System.out.println("Это " + guessNumber + "?");
System.out.println("0 - меньше, 1 - больше, другое число - угадал");
hint = in.nextInt();

if (hint != 0 && hint != 1) {
System.out.println("Я угадал. Здорово!");
System.exit(0);
}
}

attempts--;

} while (attempts > 0);

System.out.println("Я не угадал. Печально.");
}