Привет! Я преподаватель информатики и математики. В один прекрасный день осознал простую и важную вещь: дети (и взрослые) любят игры, а математику не любят. И с этим ничего нельзя сделать.

Начал размышлять, как бы геймифицировать учебный процесс. Увлекаюсь HTML, CSS, JavaScript, поэтому задумал написать игру, в которой сюжет продвигался бы за счёт решения задач — и написал. Но самое интересное не это, а вот что:

Трудно быть и продактом, и разработчиком — то бишь и визионером, и исполнителем — в одном лице. Точнее не столько трудно, сколько долго. Ведь в промежутках неплохо бы заниматься своей непосредственной работой — то есть вести уроки)) Нужна помощь — миньоны-разработчики.

Кто же поможет сам-себе-продакту в наш лихой век смены кодерской парадигмы? Правильно! Искусственный интеллект! Яндекс.Шедеврум, Mistral AI, ChatGPT-4o, Claude 3.5 и прочие миньончики. Ибо полноценный раб разраб мне не по карману.

Итак, в статье рассказываю о том, как писал свою первую обучающую игру на JS и половину работы, если не больше, делегировал ИИ.

Постановка задачи

Задача: браузерная игра, в которой сюжет продвигается вперёд за счёт решения задач уровня ОГЭ по математике. Нужны локации, персонажи, уникальные задачи, увлекательный сюжет. И, конечно же, код, реализующий смену локаций, прорисовку и адаптивность всех элементов, генерацию канвасов с задачами, проверку введённых ответов и тд.

Геймплей: попадаешь в локацию → читаешь диалоги → заводишь курсор в красный квадратик (в мобильной версии на этот квадратик нужно жмякнуть) → появляется задача → решаешь задачу. Если решил правильно — попадаешь в следующую локацию. Если нет — попадаешь в начало игры. Если прошёл все локации — вознаграждаешься ощущением своего могущества и возможностью задонатить автору))

В игре 56 локаций с персонажами и диалогами
В игре 56 локаций с персонажами и диалогами
Соответственно нужно решить 56 несложных задач
Соответственно нужно решить 56 несложных задач

Познакомьтесь с командой

Перед вами фотография моей команды разработчиков.

Я нашёл мультик «38 попугаев» на сайте culture.ru и сделал скрины оттуда
Я нашёл мультик «38 попугаев» на сайте culture.ru и сделал скрины оттуда

Справа-налево:

→ попугайчик — это Яндекс.Шедеврум. Суммарно за час-другой промптинга он нарисовал мне все локации и всех персонажей. Согласитесь, неплохо. Самой трудной работой было потом убрать с отдельных картинок фон и подготовить прозрачные png-шки персонажей.

→ манки-кодер — это я, продакт-менеджер, так сказать. И сценарист.

→ слон — это Mistral AI (и другие модели), неуклюжий, но горящий желанием помочь. Как-то так получилось, что у меня сложилось взаимопонимание именно с ним — баланс адекватности и доступности. Он (ну ладно, Claude 3.5 Sonnet тоже поучаствовал) написал добрую половину кода. Также он (и немножко ChatGPT-4o) сгенерировал условия всех используемых в игре задач, сразу сверстав и оформив их в готовом для вырезания виде. Генерация задач также потребовала моего чуткого научного руководства, потому что некоторые придуманные ИИ задачи снабжались неверными ответами. Некоторые были вовсе сформулированы некорректно и решения не имели. Например, Mistral AI считает, что диагональ произвольного параллелограмма можно найти через теорему Пифагора (скрин, к сожалению, потерял). Глаз за ним да глаз.

→ Питон — желанный гость на любой вечеринке, даже если на нём не написано ни строчки (а на нём в проекте и правда не написано ни строчки). Его задача — молчаливо быть. Когда-нибудь, когда обезьянка-кодер превратится в гориллу-программиста, мы обязательно напишем свой сервер. Но пока этот великий день не настал, Питон просто получает зарплату за то, что смотрит мемчики в соцсетях. Хоть бы день так пожить.

Что «мы» с самого начала сделали не так

Величайшая ошибка: увлёкся сюжетом и наделал квадратных артов. Позже осознал, что они будут коряво смотреться и на десктопе, и на мобилках, но визуальное повествование уже состоялось, переделывать было поздно (и лениво).

Величайшая проблема: организация данных игры. Я ещё не научился связываться через веб-запросы с JSON-файлами из JS-кода, а открыть JSON-файл напрямую из JS-кода как будто бы нельзя. Пытался с помощью Mistral AI пересобрать свои списки в объект, но с наскоку не получилось, так как потребовалось менять ещё и код. Глубоко вдохнул, вспомнил все известные мне нецензурные слова, заполнил километровые списки с диалогами, оставил всё как есть — громоздко, но работает. Приберегу прозрения для следующих работ, а пока довольствуюсь МВП. Может быть, мои поделки вообще никому не пригодятся, а я тут буду гуглить всуе — зачем?

Это только 3 сцены из 56... и только один персонаж из двух
Это только 3 сцены из 56... и только один персонаж из двух

Как кодит Mistral AI

Подобрались к самому главному — как устроен код, и что именно писал ИИ.

Совсем не включать голову не получится. Как только я начинал лениться и уходить от технических деталей, машина беззастенчиво лажала.

Такой промпт:

даст более надёжный результат, чем такой:

Во втором случае модель не заставила себя долго ждать и моментально выдала чушь. И это нормально. Без ТЗ результат — сами знаете что. Мысли читать она пока не научилась. Чтобы формулировать запрос на модификацию кода как можно чётче и в терминах используемых в коде конструкций, вам придётся читать созданный моделью код (и свой собственный тоже) и хорошо в нём ориентироваться.

Но даже в таком виде ИИ — огромное подспорье! Я, например, понятия не имел (и до сих пор не имею), как расположить два канваса один на другом с сохранением пропорций и поведения при смене разрешения экрана — модель это сделала ЗА МЕНЯ. Она же начала таскать отдельный канвас вместе с курсором мыши. Я бы потратил битый час, разбираясь, как правильно работает синтаксис обработки событий mousemove и как написать для него eventlistener.

А тут рулит не Mistral AI, а Claude 3.5 Sonnet  — тоже шикарная, но труднодоступная модель
А тут рулит не Mistral AI, а Claude 3.5 Sonnet — тоже шикарная, но труднодоступная модель

Итак, золотая середина найдена: даю модели небольшие технические задачи, которые лень писать самому. Причём формулирую их в терминах тэгов, переменных, функций уже существующего кода (самой же машиной и созданного), который требуется оптимизировать.

Но давайте обо всём по порядку.

Обзор итогового кода шаг за шагом

Глобальные переменные игры:

→ canvas, ctx — пространство, в котором рисуем игру.

→ hero — канвас с небольшой иконкой героя, которая таскается за курсором мыши. На спрашивайте «зачем». Дезигн — наше фсё.

→ person — канвас, в котором происходит смена побочных персонажей.

→ hero_face — канвас с картинкой главного героя.

→ squareXStart, squareYStart, squareXEnd, squareYEnd — координаты левого верхнего и правого нижнего углов рандомного красного квадрата. Когда курсор попадает в этот квадрат, появляется условие задачи и поле для ответа.

→ scene — счётчик сцен, самая главная переменная игры.

→ start_flag — техническая переменная, позволяющая избавиться от дублирования красного квадрата в начале игры.

Переменные с префиксом square — созданы ИИ, верблюд-стайл. А я люблю нижние подчёркивания
Переменные с префиксом square — созданы ИИ, верблюд-стайл. А я люблю нижние подчёркивания

Функцию адаптивности resizeCanvas почти полностью написал Mistral AI (или кто-то из его товарищей, я жу не помню всех деталей):

Не ставлю цель детально разобрать код, это заняло бы слишком много времени и места
Не ставлю цель детально разобрать код, это заняло бы слишком много времени и места

Заходим в игру с такого кода:

Кликаем на кнопку «Начать» и попадаем в функцию startGame:

Писали её 50 на 50 — Mistral AI и я
Писали её 50 на 50 — Mistral AI и я

Далее отправляемся в функцию makeScene:

Эта функция отвечает за создание текущей сцены. Внутри неё живёт стыдобушка — огроменный блок «if-else if-else», который кастомит расположение и размеры героев на канвасе. Объекты фона не адаптивны, так что ничего умнее, кроме как вручную прописать параметры героев в каждой отдельной сцене, я придумать не смог. Отголосок тоски по хорошему JSON'у с данными игры...

Заканчиваем километровый «if-else if-else» и завершаем формирование сцены:

Мы вызывали функцию makeScene из функции startGame, поэтому по завершении первой снова оказываемся во второй. Там на очереди стоит функция set_random_rect, которая формирует рандомный (появляется в рандомном месте экрана) красный квадрат, взаимодействие с которым вызывает появление условия задачи.

set_random_rect — магия ИИ в действии. Почти полностью написана ИИ. Я вообще поначалу не вдумывался в жуткую математику высчитывания координат. Позже, однако, пришлось вручную расширить ассоциированную с квадратом область, в которой код будет реагировать на положение курсора.

И снова возвращаемся в startGame, где вслед за генерацией квадрата вызываем листенер курсора мыши с прикрученным к нему канвасом, в котором помещена картинка парнишки на доске:

Один из промптов, адресованный Claude 3.5 Sonnet. А вообще запросов разным моделям по одним и тем же задачам было много, «тот самый победный промпт» восстановить невозможно. Как и «ту самую лучшую модель» — все по чуть-чуть приложили руку
Один из промптов, адресованный Claude 3.5 Sonnet. А вообще запросов разным моделям по одним и тем же задачам было много, «тот самый победный промпт» восстановить невозможно. Как и «ту самую лучшую модель» — все по чуть-чуть приложили руку

Эта функция была написана ИИ. Я же вставил свои 30 пикселей (в прямом смысле слова) уже на этапе тестирования и причёсывания кода. Вообще не врубаюсь, что здесь происходит))

hero_search запускает механику появления картинки с текущей задачей, создание поля и кнопки подачи ответа, проверки ответа:

Приведённые выше функции фактически полностью написаны Mistral AI. Это ключевой момент игры: именно здесь живёт инкремент scene++, а также происходит проверка, не пора ли закончить игру. Если нарываемся на максимальный индекс сцены (56), то уходим на сценарий окончания игры. Ничего сверхумного в этом сценарии нет — выводим сообщение о победе, создаём и отображаем кнопки подписки на мой тг-канал и перехода к «Яндекс.Чаевым» для донатов. Не буду приводить этот код, он тоже написан Mistral AI, можете посмотреть интересующие детали в репозитории игры.

Вместо кода покажу один из промптов
Вместо кода покажу один из промптов

Если же переменная scene ещё не достигла 56, то мы снова ныряем в startGame, и всё начинается по кругу. Если же ответ и вовсе оказался неверным, то переменная scene обнуляется, и мы снова попадаем в начало игры:

Что вежливые мальчики и девочки говорят в конце? Правильно! «Спасибо!»

Решил немножко польстить модели, чтобы ей было приятно работать со мной в дальнейшем. Взаимоуважение — основа продуктивной команды
Решил немножко польстить модели, чтобы ей было приятно работать со мной в дальнейшем. Взаимоуважение — основа продуктивной команды

Чтобы не загромождать и без того раздобревшую статью, не стал приводить HTML и CSS коды. Mistral AI весьма успешно писал и их. Здесь — полный код игры для заинтересованных.

Вместо послесловия

«Мы» не самые опытные на свете разработчики, но непрерывно растём. Уважаемый читатель, прости «нам» невежество и наивность, с которыми ты, вероятно, неоднократно встретился в тексте статьи. Не взыщи, пойми, прости и отпусти. Можешь даже закрыть страницу и смачно плюнуть в монитор, мы не обидимся (монитор-то твой). А лучше поделись своими мыслями в комментариях. Возможно, некоторые путанные для «нас» вопросы на самом деле решаются в две строки.

Если интересно следить за дальнейшими приколами, взлетами и падениями моей мысли — подписывайтесь.

Вспомнить школьную математику и поиграть в игру можно здесь.

На славу потрудились
На славу потрудились

Комментарии (7)


  1. Emelian
    06.12.2024 12:45

    дети (и взрослые) любят игры, а математику не любят. И с этим ничего нельзя сделать.

    Я, лично, не вижу в этом проблем. Сам был в похожей ситуации, со стороны ученика. Еще во времена СССР, в девятом классе, я попёрся сдуру в ПТУ (сначала подавал документы в техникум, но не хватило одной бумажки, поэтому решил упростить себе жизнь, в училище). Там, естественно, учиться, кроме меня, никто не хотел, в принципе. По химии, преподаватель разрешала мне выставлять оценки в тетрадях учеников, за домашние и контрольные работы. А учительница математики, со слезами на глазах, говорила, что для нее смысл работы состоит в том, что бы преподавать математику ради меня одного, поскольку ученики ее откровенно саботировали.

    Потом я поумнел, вернулся, после года в ПТУ, в десятый класс. После школы, поступил в Политехнический институт, затем работа по распределению, во Всесоюзном НИИ, а потом, вы не поверите, пять лет дневного обучения на мехмате МГУ, по специальности математика. На этот выбор повлияли – та учительница из ПТУ и одна сокурсница, из факультета прикладной математики, из политеха.

    Кстати, на мехмате, ситуация, в какой-то мере, повторилась. На первом курсе, студентов-математиков было 300 человек (а на пятом осталось 150). Мы все математику любили, но не понимали, зачем нас так много? Какой смысл? Тем более что учиться было очень тяжело, поблажек не было абсолютно никаких, если не считать вступительных экзаменов для нацменов (идущих по республиканским квотам).

    Т.е., народ всерьёз полагал, что смысл математики в том, чтобы обучать математике подрастающее поколение в школах и ВУЗах (нас готовили для ВУЗов). Ну, не абсурд ли? Еще была научная работа, но скорее, для карьеры, чем для науки.

    Вот, интересно, узнать ваше мнение. В чем смысл преподавания математики для ваших школьников? Не уверен, что это легкий вопрос и для ваших учеников. Ну, правда, зачем им математика? Я, например, школьную тригонометрию если применил пару раз в жизни, то хорошо. Мне математика, в юности, просто нравилась и не более.

    Логично что, если дети не понимают, зачем им математика и она для них слишком трудна и скучна, то зачем они будут тратить на нее свое драгоценное время, которое можно провести с большей пользой, по их мнению?

    поэтому задумал написать игру, в которой сюжет продвигался бы за счёт решения задач — и написал

    Игра – потенциально интересная (хотя, я в игры не играю), картинки там классные. Только вот диалоговые окна немного не камильфо, на мой взгляд. Зато будет повод для изменения их в новых версиях вашей игры.

    Трудно быть и продактом, и разработчиком — то бишь и визионером, и исполнителем — в одном лице. Точнее не столько трудно, сколько долго. Ведь в промежутках неплохо бы заниматься своей непосредственной работой — то есть вести уроки))

    Согласен, чтобы одному сделать самодостаточный продукт нужно иметь «семь пядей во лбу». Я вот решил создать свой собственный пет-проект по изучению иностранных языков ( https://habr.com/ru/articles/848836/ ). Это действительно долго. Сейчас, готовлю данные для своей обучающей программы. Но, нужно еще определиться с методологией (концепцией) обучающего курса.


    1. Ambulate
      06.12.2024 12:45

      Матан это круто


    1. habaznya Автор
      06.12.2024 12:45

      Спасибо за такой вдумчивый комментарий, очень глубокие замечания высказываете.

      Я сам с матмеха СПбГУ, у нас была похожая ситуация как у вас)

      Вы правы насчёт того, что дети совершенно справедливо не понимают, зачем столько сил тратить на какие-то оторванные от жизни закорючки. Математика требует достаточно высокого уровня абстракции и её приложимость к жизни не так то просто объяснить ребятам.

      Тут интересный вопрос в целом возникает: что и зачем следует преподавать. Например, русский язык. На поверхности кажется, вот есть же автоматическая проверка орфографии, зачем все эти правила. Но мы учим русский скорее для общей культуры мышления и высказывания. Чем богаче наш язык, тем гибче и шире мышление (мне в это верится).

      Та же самая картина мне видится и с математикой. Она прививает культуру абстрактного мышления. Есть обучение направленное на овладевание навыком, а есть обучение, направленное на воспитание мышления и расширение личности. Вот это очень трудно объяснить детям.

      Поэтому то, чем я занимаюсь со своими игрушками - не попытка научить чему-то конкретному, а скорее попытка привить им вообще интерес к обучению и к новому, там и текст диалогов построен в том же духе - несколько назидательный) Возможно, эту мысль надо было мне чётче сакцентировать в статье и в игре)

      За технические замечания тоже спасибо - всё постараюсь учесть в будущих работах.


      1. Emelian
        06.12.2024 12:45

        Я сам с матмеха СПбГУ, у нас была похожая ситуация как у вас)

        Рад, встретить коллегу!

        Вы правы насчёт того, что дети совершенно справедливо не понимают, зачем столько сил тратить на какие-то оторванные от жизни закорючки. Математика требует достаточно высокого уровня абстракции и её приложимость к жизни не так то просто объяснить ребятам.

        Я бы сказал школьникам просто: «Математика, та, что выше арифметики, малоприменима в обычной жизни. Но, она нужна для общего развития личности, как и остальные «скучные» школьные предметы. Однако, если вы мечтаете пойти в науку, развивать современные технологии, вроде искусственного интеллекта, работать на Космос либо Оборону страны, то математика там более, чем востребована. Посмотрите на смартфоны, квантовые компьютеры, криптовалюту, современных роботов, включая военные разработки, тот же «Орешник», к слову. Разве они были бы возможны без математики? Но, даже если вы ограничитесь, на будущей работе, программированием либо просто работой с автоматизированными системами, то и тогда математика вам, в той или иной мере, пригодится. Другими словами, если вы хотите быть Личностью – учитесь! В идеале, учеба должна стать, вообще, вашим смыслом жизни, ради вашего успешного будущего!»

        Тут интересный вопрос в целом возникает: что и зачем следует преподавать. Например, русский язык. На поверхности кажется, вот есть же автоматическая проверка орфографии, зачем все эти правила. Но мы учим русский скорее для общей культуры мышления и высказывания. Чем богаче наш язык, тем гибче и шире мышление (мне в это верится).

        Если брать мою школьную программу, времен СССР, то единственный предмет, в котором я не видел особого смысла, был «украинский язык и литература», хотя я там все понимал и читал без проблем (но сейчас мы в ЛНР, соответственно, в составе России, поэтому это уже не актуально). Мне было жаль нашу учительницу, которая, на мой взгляд, выбрала не самый лучший путь в своей жизни. А Тараса Шевченко воспринимали как «почитаемого, но не читаемого» (добровольно) поэта и даже слегка посмеивались над ним, хотя и без злобы.

        Поэтому то, чем я занимаюсь со своими игрушками - не попытка научить чему-то конкретному, а скорее попытка привить им вообще интерес к обучению и к новому

        Думаю, что это правильно. По возможности, можно больше акцентировать внимание на алгоритмах и программировании, как таковом, том же Питоне (для обработки данных), например. Хотя, я лично, больше ориентирован на С++, как язык профессиональной разработки.


  1. souls_arch
    06.12.2024 12:45

    То, что вы делаете для детей - это прекрасно. Вопрос чисто технический (сразу бросилось в глаза). В задаче с дробями в каком виде предполагается ввод ответа и как и в каком формате js будет обрабатывать (валидировать) этот ввод? Дополнительных подсказок по вводу ответа не видно. Судя по задаче, решение предлагается сделать в уме, без калькулятора и дать ответ в виде дроби же?

    В общем собирайте фидбек от учеников/юзеров и не забывайте дорабатывать проект

    PS: У js есть куча фреймворков. Если желаете прогресса, то лучше изучить какой-нибудь. Только не через чатгпт, а хотя бы книжку почитать и бесплатный курс в ютуб посмотреть, гайды вступительные на хабре почитать и попробовать для начала.


    1. habaznya Автор
      06.12.2024 12:45

      Все ответы к задачам не выходят за рамки десятичного вида, так что на приём стоит float. В диалогах героев это прописано, но вы правы, нужно как-то больше акцентов на ключевых особенностях геймплея)

      Я уже понял, что тут у меня слабое место, есть и другие косяки подобного рода. Буду учиться управлять вниманием.

      Насчёт фреймворков вы тоже правы. Тут вопрос баланса, когда ты diy, то трудно эффективно и быстро развиваться сразу во всём, но неизбежно приходится, хотя бы потихоньку)


  1. MasterMentor
    06.12.2024 12:45

    Преисподняя полна добрыми намерениями, а небеса полны добрыми делами.
    Удачи!