
Вот как всё это выглядит:

но будем двигаться по порядку…
Прежде всего, имеет смысл определиться с тематикой квеста. Поскольку мы уже договорились, что собираемся делать что-то не тривиальное, обычный текстовый квест-бродилка нас не устроит. Помните, в "Сундуке мертвеца" пираты играли в кости? Оказывается, это реально существующая игра с весьма непростыми правилами.
Итак, в Перудо играют группами по 4-5 человек (можно больше). Вдвоём играть тоже можно, но не так интересно. В начале игры, каждый игрок имеет по 5 игровых кубиков (костей). Начиная раунд, все бросают свои кости, смотрят выпавшие очки, но другим игрокам не показывают. Цель игры — угадать сколько костей с определённым номиналом выпало у всех игроков.
Один из игроков делает ставку, называя номинал и количество выпавших костей, при этом, в большинстве случаев, «единички» играют роль «джокеров», заменяя собой любой номинал. Например, игрок говорит: «на столе четыре шестёрки» — это означает, что на всех костях, включая закрытые, не менее четырёх должно выпасть с указанным номиналом (шестёркой) или единичкой.
Следующий игрок может повысить ставку или сказать: «не верю» (в этом случае все кости вскрываются и подчитывается количество костей с требуемым номиналом). Ставка повышается в соответствии с следующими правилами:
- Количество костей в ставке можно только повышать, за одним исключением: игрок вправе уменьшить количество костей в ставке в два раза (округление в большую сторону), если он называет номинал «единицы» (Например, после ставки «пять пятёрок» или после ставки «шесть шестёрок» можно сказать «три единицы»)
- Если количество костей в ставке остаётся прежним, номинал должен быть увеличен (Например, можно сказать «три шестёрки» после ставки «три пятёрки», однако нельзя сказать «пять пятёрок» после ставки «пять шестёрок»)
- Если количество костей в ставке увеличивается, то номинал костей может быть назван любой
- Если номинал предыдущей ставки был «единицы», игрок вправе изменить ставку только увеличив количество костей в «единицах» или сделав ход в другом номинале, но с количеством костей на одну больше, чем двойное число ставки в единицах предыдущего игрока (Например, после ставки «две единицы» необходимо сказать «пять двоек» или «три единицы»)
Если игрок не согласен с предыдущей ставкой, производится подсчёт очков. Если костей названного номинала на столе оказывается меньше количества фигурировавшего в ставке, игрок делавший ставку считается проигравшим и лишается одной игральной кости. В противном случае, проигрывает игрок вскрывший ставку. Игрок лишившийся всех своих костей выбывает из игры.
Есть ещё одно правило: игрок, у которого осталась всего одна кость, может объявить специальный раунд «Мапуто» (в квесте, для простоты, будем считать, что специальный раунд объявляется автоматически), в рамках которого действуют следующие правила:
- «Единички» не являются джокерами
- Нельзя изменять номинал в последующих ставках
Перед нами классическая комбинаторная задача. Имеется n закрытых костей, номинал которых (от 1 до 6) выпадает равновероятно и независимо. Нас интересуют те случаи, когда k из этих костей выпали с требуемым номиналом. Интересующие нас k костей могут быть рассредоточены среди n количеством способов, равном числу сочетаний k из n (кто хочет, может сам проверить). При этом, искомый номинал на них, очевидным образом, может выпасть единственным образом. Остальные кости (на которых номинал не выпал) дают количество размещений с повторениями оставшихся 5-ти значений на (n-k) костей:

Это числитель (да и то не весь), а нам нужна была вероятность. В знаменателе будет количество размещений с повторениями всех 6-ти значений на n костях. Ну и вспоминаем, что нам интересны не только k но и большие количества правильно выпавших костей вплоть до самого n. Значит, в числителе будет сумма:

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

теперь можно и посчитать. Если зафиксировать n=15 и перебрать все k начиная с 1, получится красивая картинка:

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

Циклы здесь — для вычисления умножениями и делениями всяких степеней и факториалов, действия же производятся над параметрами квеста. Главная проблема заключается в том, что все вычисления целочисленные, что не лучшим образом отражается на их точности. В целом же… этот подход работает.
Квест начинается с параметров — единственных переменных величин, которыми мы можем манипулировать в рамках квеста. Параметры управляют переходами, отображением текстов, могут отображаться в текстах, информационной панели и т.п. Это числовые значения, которые необходимо объявить. Вот так, например, выглядит объявление параметра, управляющего текущей ставкой в игре:

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

Разумеется, только этим изобразительные возможности не ограничиваются. Вот здесь, например, отображается подстановка числового значения параметра:

а здесь подставляется текстовое значение других параметров:

Для подстановки числовых значений используется [pN], а вообще можно подставить значение вычисления любого допустимого арифметического выражения, обернув его в фигурные скобки. Такие же подстановки работают в текстах локаций и переходов.

Игру начинаем с выбрасывания костей. Выражение [1..6] возвращает случайное число в указанном диапазоне. Выбрасываем все кости (по 5 у каждого из 4 игроков). Дальше почистим лишние. Количество костей — это параметры p61 по p64. Дуги графа выполняются в соответствии с заданными условиями:

Так, если у первого игрока осталась всего одна кость, обнуляем кости со 2-ой по 5-ую и дополнительно к этому устанавливаем специальный режим игры «Мапуто». Повторяем это для всех четырёх игроков, учитывая то, что последние два могут просто отсутствовать (в этом случае, обнуляем им все 5 костей). Далее надо показать расклад игроку, скрыв кости выпавшие ботам. Для взаимодействия с игроком предназначены промежуточные локации (в графе квеста отображаются белым). Кроме того, локация может отображать несколько вариантов текстовки (в нашем случае, это состав игроков, управляемый параметром p32:

Здесь есть хитрость: для первого игрока мы показываем выброшенные очки, но для всех остальных закрытые кости (знаками вопроса). Но как быть с тем, что костей может быть меньше 5-ти? Здесь нам помогает возможность гибкой настройки отображения значений параметров:

Внимательный читатель может спросить: а что это за параметр p76? Это подсказка. Если разыграть квестовую часть правильно, Прихлоп будет показывать выпавшие ему очки:

Эта возможность сильно помогает в игре, но количество таких подсказок ограничено.
Формулы редактора квестов — инструмент безусловно мощный, но при неправильном употреблении способный отнять много сил и нервов. Приведу небольшой пример:

Цель этой хитрой формулы — определение количества очков в текущей ставке и раньше это было простое деление. К сожалению, выяснилось что деление в формулах квеста хоть и целочисленное, но с округлением в ближайшую сторону. С учётом отсутствия дробей, это правильно, но напрочь ломало всю логику. Баг с подсчётом вскрытых очков пришлось искать несколько дней. К счастью, в формулах действует неявное преобразование булевских значений в числовые, что и позволило написать эту ступенчатую функцию. Аналогичным образом осуществляется и сам подсчёт очков:


Это очень важный момент, поскольку «Деньги игрока» — внешний по отношению к квесту параметр и может получиться так, что у игрока не окажется денег, а чтобы начать игру, какую-то минимальную сумму иметь необходимо. Так что, денег можно попросить у Прихлопа (правда помогать в игре он после этого уже больше не будет).

Надо, всего-навсего, погасить все плюсики. Каждый новый плюсик добавляет Капитану тревожности (и приближает момент, когда он очнётся). Те из вас, кто играли в "Братьев Пилотов", наверняка помнят сейф Карбофоса (кстати, квест про открывание сейфа тоже есть).

В случае с капитанскими «тревожными мыслями», суть та же, просто паттерн переключения другой. В общем, это известная математическая головоломка LightOut. После первого успеха игрок получает случайное денежное вознаграждение и переходит к следующему раунду, приносящему вожделенный ключ. Кстати, потренироваться с различными вариантами этой головоломки можно здесь:

В версию квеста для Telegram внесены некоторые декоративные изменения. Например, такое меню в миниигре, на мой взгляд, выглядит более наглядно:

Тот же Прихлоп знакомит нас с правилами игры (причём делает это в двух совершенно различных локациях):

Это тоже очень важно, поскольку пользователь запустивший квест может ничего не знать о правилах и необходимо ввести его в курс дела (но эти объяснения можно и пропустить, если не хочется перечитывать одно и то же много раз).
Важной составляющей реиграбельности является различное поведение игроков бота. Прихлоп нам подсказывает (или нет, в зависимости от отыгрыша квеста), но Кок, Боцман и Капитан также обладают своей индивидуальностью. Как это достигается?

Для каждого из игроков бота заданы индивидуальные пороговые вероятности. Значения с Q2 по Q4 управляют «доверчивостью» игрока и определяет будет ли он вскрывать предыдущую ставку. В свою очередь P2 по P4 — это «оптимизм» в его собственных ставках. По задумке, Кок, например — это самый доверчивый и оптимистичный игрок, который вылетает из игры первым, после чего к игре присоединяется Капитан и проигрыш в игре переквалифицируется в «смерть» главного героя.

Все эти значения задаются случайным образом (но в заданных диапазонах), в зависимости от расстановки игроков. Всё перечисленное служит тому, чтобы сделать весь квест как можно более реиграбельным.
Немного расскажу о том, как со всем этим иметь дело. Прежде всего, есть Web-плейер с уже имеющимся огромным количеством готовых квестов. В нём есть редактор, в котором можно запустить любой из имеющихся квестов, загрузить qm или qmm-файл с клиента или создать его с нуля в самом редакторе. В какой-то момент вам захочется дать ссылку на один из собственноручно разработанных квестов. Это немного менее очевидно и начинается с установки PWA-приложения. Далее, приложение синхронизируется с облаком и уже в его редакторе вы можете загрузить собственный квест, после чего нажать на иконку с облаком:

Здесь не забудьте включить чекбокс «Доступен для всех» и нажать кнопку «Сохранить», после чего появится ссылка. Также, можно открыть в редакторе чужую ссылку, если возникнет желание разобраться в том как работает квест.
Автор: GlukKazan