Как устроена игра «Угадай число»
Игра «Угадай число» состоит из 4 частей: загадать, спросить, сравнить и повторить. Каждая часть — одна конструкция Python, поэтому проект хорошо показывает, как отдельные темы складываются в работающую программу.
- Загадать. Модуль random выбирает случайное целое число и кладёт его в переменную secret.
- Спросить. Функция
input()получает вариант игрока, аint()превращает текст в число. - Сравнить. Конструкция
if,elif,elseвыбирает ответ: больше, меньше или угадал. - Повторить. Цикл
whileкрутит вопросы, пока число не отгадано.
Каждая попытка игрока — это один проход цикла: ввод, сравнение, подсказка. Такую логику удобно нарисовать блок-схемой, и похожие схемы разбирают на уроках: по федеральной образовательной программе циклы с условием изучают в 8 классе.
Запустите код в редакторе над статьёй кнопкой «▶ Запустить». Под выводом появится поле ввода: напишите число и нажмите Enter. Компьютер каждый раз загадывает новое значение, так что две партии подряд не будут одинаковыми. Если хочется начать с чистого листа, кнопка «Сбросить» вернёт исходную версию программы, а свои правки редактор хранит в браузере.
Шаг 1. Компьютер загадывает число
Чтобы компьютер «задумал» число, нужна функция randint из модуля random: она возвращает случайное целое число из диапазона, причём обе границы входят в результат.
import random
secret = random.randint(1, 100)
print(secret)
Здесь random.randint(1, 100) может вернуть и 1, и 100. Это отличие от range(1, 100), где правая граница не входит, — путаница между ними встречается постоянно. Строку print(secret) оставьте на время отладки, чтобы видеть загаданное значение, а перед тем как дать игру другу, удалите её. Как устроены другие функции модуля — choice, shuffle, random() — показано в статье о модуле random. В документации Python сказано, что randint(a, b) — это сокращение для randrange(a, b + 1). Там же есть важное предупреждение: модуль random не подходит для паролей и шифрования, для этого существует отдельный модуль secrets. Поведение randint описано в официальной документации Python[1].
Шаг 2. Ввод варианта и сравнение
Функция input всегда возвращает строку, поэтому ответ игрока нужно превратить в целое через int(). Без этого сравнение строки с числом закончится ошибкой TypeError.
guess = int(input("Твой вариант: "))
if guess < secret:
print("Моё число больше")
elif guess > secret:
print("Моё число меньше")
else:
print("Угадал!")
Обратите внимание на формулировки. Если игрок ввёл 40, а загадано 73, программа говорит «Моё число больше» — речь о загаданном значении, а не о варианте игрока. Новички часто путают направление подсказки, и игра становится нечестной. Проверьте логику на бумаге. Если первая попытка — пустая строка, int() тоже выдаст ошибку; об этом позаботимся в разделе улучшений.
| Загадано | Ввёл игрок | Какое условие истинно | Ответ программы |
| 73 | 40 | guess < secret | Моё число больше |
| 73 | 90 | guess > secret | Моё число меньше |
| 73 | 73 | ни одно из двух — срабатывает else | Угадал! |
Шаг 3. Цикл while до победы
Цикл while — это повторение «пока условие истинно»: здесь он подходит лучше for, потому что заранее неизвестно, за сколько ходов игрок отгадает число. Есть 2 привычные записи.
Первая — while True с выходом через break, как в редакторе: цикл бесконечный, но команда break обрывает его в ветке «Угадал». Вторая — с условием в заголовке: while guess != secret. Для неё переменную guess нужно создать до цикла, например со значением 0, которое заведомо не может быть загадано. Обе записи работают одинаково, выбирайте ту, что понятнее. Подробно о break, continue и опасности зацикливания рассказано в уроке про цикл while.
Самая частая ошибка на этом шаге — поставить secret = random.randint(1, 100) внутрь цикла. Тогда компьютер будет загадывать новое значение после каждого хода, и подсказки потеряют смысл. Загадывание должно стоять до while, ввод — внутри.
Шаг 4. Счётчик и лимит попыток
Счётчик попыток — это переменная, которая начинается с 0 и увеличивается на 1 после каждого ввода. Лимит добавляет в игру азарт: например, на отгадку даётся не более 7 ходов.
import random
secret = random.randint(1, 100)
tries = 0
max_tries = 7
guess = 0
while guess != secret and tries < max_tries:
guess = int(input("Попытка " + str(tries + 1) + ": "))
tries += 1
if guess < secret:
print("Больше")
elif guess > secret:
print("Меньше")
if guess == secret:
print("Победа! Ходов:", tries)
else:
print("Ходы кончились. Было загадано", secret)
В заголовке цикла теперь два условия через and: игра продолжается, только если число не отгадано и попытки ещё остались. После цикла программа выясняет, почему он закончился, и выводит нужное сообщение. Почему лимит именно 7, а не 5 или 10, объясняет следующий раздел. Последняя попытка особенная: после неё программа не задаёт новый вопрос, а честно называет загаданное значение.
Почему семи попыток хватает всегда
Если каждый раз называть середину оставшегося промежутка, на отгадку числа от 1 до 100 понадобится не более 7 ходов. Такая стратегия называется двоичным поиском: каждая подсказка отбрасывает половину вариантов.
| Ход | Промежуток | Называем | Подсказка (загадано 73) |
| 1 | 1–100 | 50 | больше |
| 2 | 51–100 | 75 | меньше |
| 3 | 51–74 | 62 | больше |
| 4 | 63–74 | 68 | больше |
| 5 | 69–74 | 71 | больше |
| 6 | 72–74 | 73 | угадал |
Вариантов 100, после первого хода остаётся не больше 50, потом 25, 12, 6, 3 и 1. Седьмая попытка гарантированно попадает в цель, ведь 2 в седьмой степени — это 128, что больше 100. Для промежутка от 1 до 1000 хватит 10 ходов, потому что 2 в десятой степени равно 1024. Так игра незаметно знакомит с двоичной системой: те же степени двойки изучают в 8 классе по федеральной образовательной программе[2].
6 идей, как улучшить игру
Когда базовая версия «Угадай число» работает, её можно развивать: каждое из 6 улучшений ниже добавляет одну новую идею и занимает от 5 до 15 строк.
- Уровни сложности. В начале спросите уровень: лёгкий — от 1 до 10, средний — до 100, трудный — до 1000. Верхнюю границу храните в переменной.
- Защита от букв. Если игрок введёт «пять»,
int()упадёт с ValueError. Проверкаisdigit()решает проблему. - «Горячо — холодно». Если разница меньше 5, пишите «горячо», если больше 30 — «холодно». Поможет функция
abs(), и каждая попытка станет информативнее. - Ещё партия. Оберните игру во внешний цикл и в конце спрашивайте «Сыграем ещё?».
- Рекорд. Храните наименьшее число ходов за все партии и поздравляйте, если рекорд побит.
- Роли наоборот. Пусть отгадывает компьютер, а человек подсказывает.
Защита от неверного ввода выглядит так: цикл повторяет вопрос, пока строка не состоит из одних цифр.
text = input("Число: ")
while not text.isdigit():
text = input("Нужно целое число, попробуй ещё раз: ")
guess = int(text)
А вот версия, где отгадывает компьютер. Он применяет тот же двоичный поиск: хранит нижнюю и верхнюю границы и каждый раз называет середину.
low = 1
high = 100
print("Задумай число от 1 до 100, а я отгадаю.")
while True:
mid = (low + high) // 2
answer = input("Это " + str(mid) + "? Ответь: больше, меньше или да: ")
if answer == "да":
print("Ура!")
break
elif answer == "больше":
low = mid + 1
else:
high = mid - 1
Попробуйте обмануть компьютер, отвечая противоречиво. Через несколько ходов нижняя граница станет больше верхней — добавьте проверку и сообщение «Кажется, ты меня обманываешь!».
Когда эта игра не подходит
Игра не подходит как первое знакомство с программированием вообще: она требует 4 разных конструкций сразу. Вот ситуации, где лучше начать с другого.
- Ребёнок ещё ни разу не писал print и input. Сначала нужна первая программа на 15 минут, потом игра.
- Ребёнку 7–8 лет и печатать трудно. Ту же игру проще собрать из блоков в Scratch.
- Хочется графики и анимации. Здесь только текст в 1 окне; для картинок лучше подходит черепашка.
- Нужно тренировать задание 16 ОГЭ. По материалам ФИПИ, там ввод из нескольких чисел и обработка последовательности, а случайности нет вовсе.
«Компьютер можно перехитрить: он чаще загадывает круглые числа». Это миф — randint выдаёт все значения диапазона с равной вероятностью, и предпочтений к 50 или 100 у него не существует.
«Лучшая тактика — называть числа подряд: 1, 2, 3…». Это не подтверждается простым подсчётом: перебор подряд требует до 100 ходов, а деление пополам — не более 7.
Чего делать нельзя
Нельзя считать игру готовой, пока она не проверена на крайних случаях: числах 1 и 100, буквах и пустом вводе. Вот 6 правил для этого проекта.
- Нельзя загадывать число внутри цикла — оно будет меняться после каждого хода.
- Не стоит забывать
int(): строка «50» и число 50 для Python разные вещи. - Не следует оставлять отладочный
print(secret)в версии для друзей. - Нельзя писать
while Trueбез break — игра никогда не закончится. - Не стоит называть файл random.py: программа импортирует сама себя, и randint пропадёт.
- Не допускается путать подсказки: «больше» должно относиться к загаданному значению, а не к варианту игрока.
Имена переменных в примерах записаны в стиле snake_case, как советует руководство PEP 8[3]. Оно же рекомендует ставить пробелы вокруг знаков сравнения, как в строке guess < secret. Следующий проект того же уровня — игра «Камень, ножницы, бумага», где компьютер выбирает уже не число, а слово.
Источники
[1] The Python Tutorial (официальная документация Python 3). Python Software Foundation.
[2] Приказ Минпросвещения России от 18.05.2023 № 370 «Об утверждении федеральной образовательной программы основного общего образования».
[3] van Rossum G., Warsaw B., Coghlan N. PEP 8 — Style Guide for Python Code. Python Software Foundation, 2001.
Вопросы и ответы
Сколько строк занимает «Угадай число»?
Базовая версия — около 15 строк. С уровнями сложности, защитой от букв и рекордом выходит 40–50 строк.
Почему программа падает, если ввести букву?
Функция int() не умеет превращать слово в число и выдаёт ValueError. Добавьте проверку isdigit() перед преобразованием.
Можно ли сделать так, чтобы компьютер всегда выбирал одно и то же?
Да, вызовите random.seed(1) перед randint. Это удобно при отладке: результат повторяется, и ошибку легче найти.
Чем while лучше for в этой игре?
Цикл for повторяет действия заранее известное количество раз. Здесь число ходов зависит от игрока, поэтому естественнее повторять «пока не угадал».
Как добавить подсказку «горячо — холодно»?
Посчитайте abs(guess - secret) и сравните с порогами. Например, разница меньше 5 — «горячо», больше 30 — «холодно».
Что делать дальше после «Угадай число»?
Возьмите проект, где нужны списки или словари: викторину, игру со словами или подсчёт очков нескольких игроков. Новая тема лучше запоминается в своём проекте.