Бот показывает вопрос с кнопками, но на нажатие пока не реагирует. Сегодня научим его проверять ответ, говорить «верно» или «неверно» и копить очки. Считать счёт ты уже умеешь по угадайке, так что половина дела знакома.
После урока сможешь: объяснить тему «Проверяем ответ и считаем очки» и выполнить связанный с ней учебный шаг без подсказки.
Что нам нужно помнить
В квизе бот помнит две вещи для каждого игрока: на каком вопросе игрок сейчас и сколько у него очков. Это снова состояние в памяти, словари по chat_id, как в угадайке.
nomer = {} # на каком вопросе игрок
ochki = {} # сколько очков набрал
Ставим эти строки вверху, рядом со списком вопросов. На /start обнуляем оба для игрока: вопрос нулевой, очков ноль.
@bot.message_handler(commands=['start'])
def start(message):
chat_id = message.chat.id
nomer[chat_id] = 0
ochki[chat_id] = 0
poslat_vopros(chat_id)
Заметил poslat_vopros(chat_id)? Это наша своя функция, которая шлёт текущий вопрос. Сейчас её напишем, чтобы не копировать код с кнопками снова и снова.
Функция-помощник
Показывать вопрос придётся не раз: на старте и после каждого ответа. Чтобы не плодить копии, вынесем это в одну функцию.
def poslat_vopros(chat_id):
n = nomer[chat_id]
vopros = voprosy[n]
keyboard = types.InlineKeyboardMarkup()
for variant in vopros["varianty"]:
keyboard.add(types.InlineKeyboardButton(variant, callback_data=variant))
bot.send_message(chat_id, f"Вопрос {n + 1}: {vopros['text']}", reply_markup=keyboard)
Функция берёт номер текущего вопроса игрока, достаёт нужный словарь из списка и шлёт его с кнопками. Теперь вместо десяти строк пишем одно слово
poslat_vopros(chat_id). Это и есть сила своих функций: написал раз, зовёшь сколько нужно.
Ловим ответ и считаем
@bot.callback_query_handler(func=lambda call: True)
def otvet(call):
chat_id = call.message.chat.id
bot.answer_callback_query(call.id)
n = nomer[chat_id]
if call.data == voprosy[n]["otvet"]:
ochki[chat_id] += 1
bot.send_message(chat_id, "Верно!")
else:
bot.send_message(chat_id, f"Неверно. Правильно: {voprosy[n]['otvet']}")
n = nomer[chat_id]это номер вопроса, на котором игрок.voprosy[n]["otvet"]это правильный ответ этого вопроса,call.dataэто то, что игрок нажал.- Совпали — добавляем очко и хвалим. Нет — показываем верный ответ.
answer_callback_queryв начале убирает часики.
Запусти, нажми /start, ответь на первый вопрос. Бот скажет «верно» или «неверно» и под капотом изменит счёт. Пока бот застрял на первом вопросе, к следующему он не переходит. Этот шаг сделаем в финальном уроке.
Контрольный вопрос. Какой метод убирает «часики» на inline-кнопке после нажатия? Напиши имя: bot.____(call.id).
Подсказка: bot.answer_callback_query(call.id)
Онлайн-проверка ответа появится позже
Задание. Добавь словари nomer и ochki, обнуляй их на /start, напиши функцию poslat_vopros и зови её на старте. В обработчике callback проверь ответ, скажи верно/неверно и поменяй счёт. Пришли скриншот, где видно «Верно» или «Неверно».
Подсказка: Состояние — словари по chat_id. Правильный ответ текущего вопроса — voprosy[n][«otvet»], выбор игрока — call.data.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Зачёт, если:
✅ на нажатие бот говорит «Верно» или «Неверно» и меняет счёт;
✅ состояние (номер вопроса и очки) хранится по chat_id и обнуляется на /start;
✅ прислан скриншот, где видно «Верно» или «Неверно».
