{{indexmenu_n>25}} ====== Составные коды ====== **Составной код** — это итоговый код уровня, который собирается из нескольких частей, разбросанных по кодам, бонусам, сквозным бонусам и подсказкам. Как только команда добывает все части, движок сам вбивает собранный код за игроков. > **Важно (относится ко всем трём способам):** итоговый собранный код обязательно должен быть заведён на уровне как обычный код (или как бонус). Иначе движок будет отправлять несуществующий ответ, и у игроков страница будет перезагружаться в цикле. Реализовать составной код можно тремя способами: - **Вложенные шаблоны** — проверка каждой части шаблоном на сервере, ввод кода скриптом в самом внутреннем шаблоне. **Рекомендуемый способ.** - **Скрипт с ''getAllParts'' / ''getAllBonuses''** — сборка кода на клиенте из ответов, уже показанных на странице. - **''code_part''** — устаревший вариант, оставлен для совместимости. ===== Способ 1: Вложенные шаблоны (рекомендуется) ===== [[authors_main:task_editor:advanced:edit_templates|Шаблоны]] вычисляются на сервере до отправки страницы. Пока команда не собрала все части, итогового кода нет ни на экране, ни в исходном коде страницы — найти его заранее невозможно. Идея: вкладываем шаблоны друг в друга, каждый уровень вложенности проверяет свою часть (код, бонус или сквозной бонус), а в самом внутреннем шаблоне скриптом вбиваем итоговый код. Пример: код собирается из 1-го кода уровня, 2-го бонуса и 5-го сквозного бонуса. {% match code_1 }:{ {%= крокодил}:{ {% match bonus_2 }:{ {%= бегемот}:{ {% match gbonus_5 }:{ {%= кабан}:{ %} %} %} %} %} %} Ветка срабатывает только при точном совпадении ответа, поэтому вложенные шаблоны раскрываются до '''' только тогда, когда вбиты все три части. Если какая-то часть ещё не вбита, соответствующий шаблон вернёт пустоту и вложенные в него шаблоны вообще не будут вычисляться. ==== Если важен только факт ввода, а не конкретный ответ ==== Когда у части кода несколько синонимов и проверять надо просто «вбито или нет», используйте ветку **''!any_answer!''** — она срабатывает на любой введённый ответ, но, в отличие от ''?'', не срабатывает, когда ответа ещё нет. Матрёшка собирается так же, просто вместо конкретных ответов на каждом уровне вложенности стоит ''!any_answer!'': {% match code_1 }:{ {%= !any_answer!}:{ {% match bonus_2 }:{ {%= !any_answer!}:{ {% match gbonus_5 }:{ {%= !any_answer!}:{ %} %} %} %} %} %} > **Важно:** не используйте вместо ''!any_answer!'' ветку ''?'' — она срабатывает на любое значение, **включая ''!no_answer!''**, и код будет вбит раньше времени. Способы проверки можно смешивать в одной матрёшке: для части кода с единственным ответом писать конкретное значение, а для части с синонимами — ''!any_answer!''. ==== Разные итоговые коды для разных комбинаций ==== Шаблоны сравнивают именно значение ответа, поэтому итоговый код может зависеть от того, каким синонимом закрыта каждая часть: достаточно прописать несколько веток с разными ''enter()''. Так делаются «ветвящиеся» составные коды, которые нельзя собрать простой склейкой частей. ==== Где размещать ==== * В **тексте задания** (режим «Источник») — как в примерах выше. * В поле **«Задание»** того бонуса, который этим составным кодом и закрывается — лучший вариант, если за составной код полагается бонус. Текст задания бонуса показывается только до ввода правильного ответа, поэтому после закрытия бонуса шаблон больше не вычисляется. * В поле **«Скрипт задания»** — тогда служебные строки шаблона закомментируйте двойным слэшем, чтобы редактор кода не ругался на синтаксис (подробнее — в разделе [[authors_main:task_editor:advanced:edit_templates#шаблоны_внутри_javascript|Шаблоны внутри javascript]]): // {% match code_1}:{ {%= крокодил}:{ // {% match bonus_2}:{ {%= бегемот}:{ enter('ЗООПАРК'); // %} %} // %} %} Что можно проверять: ''code_N'', ''bonus_N'', ''gbonus_N'' (а также ''code_first_N'', ''bonus_first_N'', ''gbonus_first_N'' — самый первый вбитый ответ). Сквозные бонусы проверяются даже на тех уровнях, где они не выведены на экран. Полный список параметров — на странице [[authors_main:task_editor:advanced:edit_templates|Шаблоны]]. ===== Способ 2: Скрипт с getAllParts / getAllBonuses ===== Функции собирают итоговый код из ответов, которые уже отображаются на странице. // Склеивает ответы в порядке перечисления аргументов enter(getAllParts('c1', 'b2', 'gb5')); * **''getAllParts(...)''** — принимает id элементов, в которых движок показывает вбитые ответы: * ''c1'', ''c2'', … — коды уровня; * ''b1'', ''b2'', … — бонусы уровня; * ''gb1'', ''gb2'', … — сквозные бонусы. * Части склеиваются **в порядке перечисления аргументов**, а не в порядке их появления на экране. * Если хотя бы одна часть ещё не вбита, функция вернёт пустую строку. Проверять результат не нужно: пустой ответ движок не засчитывает и в историю не пишет, поэтому ''enter()'' на нём просто ничего не сделает. Если все части лежат в подряд идущих бонусах, удобнее короткая форма: // Склеивает ответы бонусов с 1-го по 4-й: то же, что getAllParts('b1','b2','b3','b4') enter(getAllBonuses(1, 4)); Скрипт пишется в поле **«Скрипт задания»** и выполняется при каждом обновлении уровня. Повторных отправок бояться не нужно: ''enter()'' вбивает код только один раз. Учтите, что склеивается **ответ, который вбила команда**. Если у части кода есть синонимы, разные команды получат разные итоговые строки — либо заведите на итоговый код все возможные варианты, либо используйте способ 1. ===== Способ 3: code_part (устаревший) ===== Части кода прописываются в тексте задания или в тексте решения бонусов и штрафных подсказок (в режиме «Источник»): * **''номер_составного_кода''** — порядковый номер составного кода, если их на уровне несколько (если он один — ставьте ''0''). * **'''частькода'''** — часть кода строкой, обязательно в кавычках (даже если это число). * **''число_составных_частей''** — сколько всего частей нужно собрать. Как только на странице окажется указанное количество частей, движок вобьёт склеенный код. Особенности способа: * Части склеиваются **в порядке выполнения ''code_part''**, то есть в порядке вывода блоков на странице: сначала задание, потом подсказки, потом бонусы, потом сквозные бонусы. Свой порядок задать нельзя — при перестановке бонусов итоговый код изменится. * Перечислять, откуда брать части, не нужно: движок собирает все ''code_part'' с одинаковым номером, которые оказались на странице. Части можно свободно раскидывать по подсказкам и бонусам, не отслеживая их номера. * Часть кода задаёт автор, поэтому она не зависит от того, каким синонимом закрыт бонус или подсказка (в отличие от способа 2). Но и учесть конкретный синоним тоже нельзя — для этого нужен способ 1. * Общее количество частей указывается в каждом вызове, поэтому при изменении их числа править придётся сразу все части. * Части кода видны в исходном коде страницы сразу после открытия бонуса/подсказки. ===== Что выбрать ===== ^ Способ ^ Где вычисляется ^ Порядок частей ^ Когда использовать ^ | Вложенные шаблоны | На сервере | Задаёт автор | Самый универсальный способ: работает с синонимами и не показывает итоговый код заранее. Писать нужно больше всего — матрёшку удобно сгенерировать через AI | | ''getAllParts'' / ''getAllBonuses'' | В браузере | Задаёт автор (порядок аргументов) | Меньше всего писать, но плохо подходит, если у ответов на части есть синонимы | | ''code_part'' | В браузере | Порядок вывода на странице | С синонимами работает, но скрипт надо вручную прописать в каждой части | Для способа 1 длинную матрёшку шаблонов удобно сгенерировать нейросетью — см. [[authors_main:task_editor:ai_authoring|Редактирование и генерация заданий с помощью AI]].