{{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]].