В прошлом уроке мы поймали баг: бот загадывал число заново на каждую догадку, поэтому выиграть было нельзя. Чинить будем так: бот загадает число один раз и запомнит его, пока ты угадываешь. Сегодня про память бота.
После урока сможешь: объяснить тему «Бот запоминает на время игры» и выполнить связанный с ней учебный шаг без подсказки.
Картинка про память
Представь ведущего, который загадал число и записал его на листочек. Пока ты угадываешь, листочек лежит перед ним, и ведущий сверяется с ним. А наш наивный бот каждый раз выбрасывал старый листочек и писал новое число.
Нам нужен такой листочек в программе. И ещё тонкость: ботом одновременно могут играть разные люди. У каждого свой листочек, числа не должны смешиваться.
Листочек это словарь
Помнишь словари из Python? Пары «ключ значение». Ключ это chat_id (у каждого чата свой), значение это загаданное число.
zagadannoe = {} # тут бот хранит число для каждого игрока
popytki = {} # а тут число попыток
Эти строки ставим вверху, до обработчиков. Пустые фигурные скобки {} это пустой словарь, в который будем складывать данные игроков по ходу.
Загадываем один раз, на /start
@bot.message_handler(commands=['start'])
def new_game(message):
chat_id = message.chat.id
zagadannoe[chat_id] = random.randint(1, 100)
popytki[chat_id] = 0
bot.send_message(chat_id, "Я загадал число от 1 до 100. Угадывай!")
zagadannoe[chat_id] = random.randint(1, 100) кладёт на «листочек» этого игрока новое число. У другого игрока свой ключ и своё число. Счётчик попыток ставим в ноль.
Угадываем и сверяемся
@bot.message_handler(func=lambda message: message.text.isdigit())
def guess(message):
chat_id = message.chat.id
if chat_id not in zagadannoe:
bot.send_message(chat_id, "Сначала нажми /start, я загадаю число.")
return
dogadka = int(message.text)
popytki[chat_id] += 1
if dogadka < zagadannoe[chat_id]:
bot.send_message(chat_id, "Моё число больше.")
elif dogadka > zagadannoe[chat_id]:
bot.send_message(chat_id, "Моё число меньше.")
else:
bot.send_message(chat_id, f"Угадал! Попыток: {popytki[chat_id]}. Ещё разок? /start")
if chat_id not in zagadannoe:проверяет, начал ли игрок партию. Если на листочке пусто, бот просит нажать /start.returnзначит «выйти из функции, дальше не идти».popytki[chat_id] += 1прибавляет единицу к счётчику попыток этого игрока.- Сравниваем с
zagadannoe[chat_id], то есть с числом именно этого игрока. Вот почему игра стала честной: число одно на всю партию.
Эта память живёт, только пока запущена программа. Закрыл бота, и все листочки пропали. Перезапустил, и словари снова пустые. Для игры это нормально. А чтобы бот помнил тебя даже после перезапуска, понадобится сохранение на диск, этим займёмся в Модуле 5.
Контрольный вопрос. В какой структуре данных удобно хранить загаданное число отдельно для каждого игрока (по его id)? Одно слово.
Подсказка: Пары «ключ — значение», ключ это chat_id.
Онлайн-проверка ответа появится позже
Задание. Добавь два словаря для числа и попыток, загадывай число на /start, угадывай в обработчике чисел и сверяйся по chat_id. Пришли скриншот победы, где бот показывает число попыток.
Подсказка: zagadannoe[chat_id] и popytki[chat_id]. Не забудь проверку if chat_id not in zagadannoe.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Зачёт, если:
✅ число загадывается один раз на /start, попытки считаются;
✅ игра идёт через несколько сообщений, состояние хранится по chat_id;
✅ прислан скриншот победы с верным числом попыток.
