Туториал по языку TextGen Script
Урок 0. Примеры, чтобы не было страшно
Чувствую, что многим, кто не программировал, кажется, что сделать скрипт, это очень непонятно и страшно. Давайте покажу, что это совсем не так!
Пример 1:
("Мама " "мыла " "раму")
Этот скрипт сгенерирует единственную фразу – «Мама мыла раму». Предсказуемо, не так ли?
Проверьте это прямо сейчас:
- запустите инструмент
- скопируйте скрипт выше в текстовое поле TextGen Script (S-expression)
- нажмите «Сгенерировать текст!»
Давайте чуть-чуть усложним – пусть мама может мыть не только раму, а еще что-нибудь:
("Мама " "мыла " (#r "раму" "окно" "дверь"))
Запустите и проверьте скрипт – он будет выдавать одну из фраз «Мама мыла раму», «Мама мыла окно» или «Мама мыла дверь».
Ну что, надеюсь, теперь у вас появилось уверенность в том, что вы можете это освоить?
Если да, то давайте пойдем дальше и почитаем чуть-чуть теории.
Если нет, то зайдите в инструмент и попытайтесь по аналогии сделать пример, в котором будет еще 4 строчка – «Мама мыла машину». Думаю, у вас получится!
Урок 1. База
Чтобы писать (или хотя бы понимать) генераторы на TextGen Script, нужно понять, что есть всего 3 основных элемента программы:
- Просто текст. Пишется в двойных кавычках. Например: "Мама". Или "Эльф пошел в лес". Если нужно использовать в тексте двойную кавычку, она экранируется обратным слешем - "Вот \" двойная кавычка".
- Управляющие конструкции. Пишутся без двойных кавычек и управляют процессом генерации текста; используются в паре с текстовыми элементами. Например: есть конструкция #r , позволяющая выбрать случайный элемент.
- Список. Список - это куча текстов/управляющих конструкций/списков. Список обрамляется в круглые скобки. Например: ("Мама" "мыла" "раму"), или ("Мама мыла раму"), или ("Здесь был " (#r "эльф" "гном")). Все скобки в программе должны быть закрыты!
Программа работает так: она проходит по всем элементам
- Если это текст – он идёт в копилку
- Если управляющая конструкция – она выполняется, результат идет в копилку
- Если список – проходится по всем элементам списка, применяя данное основное правило; результаты всех элементов складываются в копилку.
Давайте для начала возьмем генерацию только с текстом; несколько программ будут генерировать один и тот же текст.
1 вариант – единственный текст:
("Мама мыла раму")
2 вариант – будут взяты все элементы списка последовательно, и сложены:
("Мама " "мыла " "раму")
3 вариант – какие бы не были вложенные списки, идея остаётся одинаковой. Можно переносить строки, форматировать код и т.д.:
("Мама " (("мыла" " ") "раму"))
Кстати, никто не запрещает переносить элементы на следующие строки, форматировать текст и писать комментарии:
(
"Мама " ; комментарий в программе начинается с ; и продолжается до конца строки
("мыла" "раму")
)
Урок 2. Рандомная генерация (#r)
Давайте сделаем что-нибудь посложнее, например, выведем случайную карту из колоды.
Управляющая конструкция #r возвращает один из случайных оставшихся элементов списка.
Например, конструкция:
(#r "Туз" "Двойка" "Тройка" "Четверка")
вернёт нам достоинство карты.
Конструкция:
(#r "пик" "треф" "бубей" "червей")
вернёт нам масть карты.
Чтобы сложить их, упакуем их в еще один список; также надо не забыть пробел между достоинством и мастью карты.
Результирующая программа:
(
(#r "Туз" "Двойка" "Тройка" "Четверка")
" "
(#r "пик" "треф" "бубей" "червей")
)
В принципе, этого достаточно, чтобы сделать большинство классических генераторов – карт, персонажей и т.д.
http://d.janvarev.ru/sexp/textgenscript-htmlru/
Там уже есть программа, которая генерирует тексты abd, abe, acd, ace. Разберитесь, как она устроена, и модифицируйте её как-нибудь, чтобы она делала что-то, что нужно вам!
Урок 3. Переменные и условия
Если всё генерировать случайно, то может произойти казус – в одном месте у нас герой эльф, а во втором – гном. Нехорошо. Чтобы избежать подобного и увеличить связность текста используются переменные.
У них есть три конструкции:
1. #varSet – устанавливает переменную (1 параметр) в значение (2 параметр).
(#varSet "hero" "эльф")
установит переменную hero в значение эльф.
2. @<имя переменной> – возвращает значение переменной. Например,
("Грозный " @hero " вернулся с поля боя")
3. #ifVarEq – проверяет, равна ли переменная (1 параметр) значению (2 параметр). Если да – генерация идет по 3 параметру, иначе – по 4-му. Пример:
(#ifVarEq "hero" "эльф"
("Вышел эльф из девственного леса... ")
("Вышел гном из высоких гор... ")
)
Можно делать сложные вложенные конструкции:
(#ifVarEq "hero" "эльф"
("Вышел эльф из девственного леса... ")
(#ifVarEq "hero" "гном"
("Вышел гном из высоких гор... ")
("Вышел непонятно кто непонятно откуда... ")
)
)
Ну, и наконец пример, задействующий все элементы – генерацию, случайный выбор и переменные:
(
(#varSet "hero" (#r "эльф" "гном")) ; выбираем случайного персонажа
(#ifVarEq "hero" "эльф"
("Вышел эльф из " (#r "девственного леса... " "зеленой рощи... ")) ; подвыражения будут работать
("Вышел гном из высоких гор... ")
)
"Помотал головой... "
"И направился " @hero " в сторону великого города..."
)
Этот пример на сайте
Урок 4. Объединение программ
Одно из самых больших преимуществ языка по сравнению с другими способами генерации текста – возможность легко использовать чужой код для генерации.
Возьмем для примера текст про Штирлица и попытаемся его разнообразить:
(
"Штирлиц потянул карту. Дама пик."
"\"Перебор\" – подумал Штирлиц."
)
Возьмем наш код для генерации карт. Мы можем просто взять готовую программу и добавить её в то место, которое мы хотим сгенерировать.
Выглядеть это будет так:
(
"Штирлиц потянул карту. "
(
(#r "Туз" "Двойка" "Тройка" "Четверка" "Дама")
" "
(#r "пик" "треф" "бубей" "червей")
)
"."
"\"Перебор\" – подумал Штирлиц."
)
У нас есть множество стандартных программ, которые можно использовать:
и куча всего другого!