Connor & Slonephant
Slonephant Slonephant
Привет, Коннор. Я тут кое-что наваял – небольшой кодовый паззл, который ещё и сюжетный поворот. Представь себе рекурсивное повествование, где каждый выбор возвращает историю в другое состояние кода. Звучит как раз для твоей креативной головы разработчика инди-игр, да?
Connor Connor
Звучит круто. Я обожаю истории, которые закручиваются обратно, как баг в журнале заданий. Только следи, чтобы развилки были понятными, чтобы игрок не запутался совсем. Добавь какого-нибудь чудаковатого рассказчика – и получишь такое, что мозг взрывается, будто смотришь на живой код. Помогу накидать схему конечного автомата, если надо?
Slonephant Slonephant
Конечно, дружище! Давай сначала разложим всё по полочкам, простыми словами, а потом превратим это в аккуратную конечную машину. **Состояния** 1. Начало 2. Вступление (закадровый текст) 3. ВыборА – «Пойти по левому туннелю» 4. ВыборБ – «Направиться к реке» 5. ЦиклА – «Ты вернулся к туннелю, но факел теперь светится» 6. ЦиклБ – «Ты вернулся к реке, но в ручье появилась рыба» 7. КонецА – «Нашёл спрятанный ключ, квест завершён» 8. КонецБ – «Поймал рыбу, но на карте проявился новый путь» **Переходы** - Начало → Вступление - Вступление → ВыборА - Вступление → ВыборБ - ВыборА → ЦиклА (после нескольких шагов) - ЦиклА → КонецА (если игрок решит открыть светящийся ящик) - ВыборБ → ЦиклБ (после нескольких шагов) - ЦиклБ → КонецБ (если игрок решит следовать за рыбой) **Дополнительные заметки** - Каждый переход должен сопровождаться небольшим комментарием от рассказчика, вроде: «Ого, факел вдруг загорелся! Вот это поворот!» - Нужно добавить счётчик, чтобы ограничить количество циклов до двух, иначе мы застрянем в бесконечной рекурсии. Теперь можешь черновик кода или схему потока. Дай знать, если нужен пример кода или более детальная диаграмма!
Connor Connor
Вот основа неплохая. Мне нравится ограничение цикла, чтобы рекурсия не шла в бесконечность. Набросаю операционную таблицу и добавлю небольшой скрипт для подколок. Сначала напишу кусочек псевдокода или сразу перейду к визуальной схеме?
Slonephant Slonephant
Давай начнём с быстрого наброска псевдокода – так логику будет легче подправить и шутки рассказчика добавить. Как только тебе понравится, передадим это в программу для построения диаграмм, и получим красивую схему. Как тебе такая идея?
Connor Connor
Отлично. Вот набросок псевдокода, чтобы держать состояния и переходы в одном месте. Скажи, если нужно что-то подправить перед тем, как перейдем к схеме. Нам нужно действительно предоставить псевдокод. Пользователь попросил начать с псевдокода. Так что ответь псевдокодом. Убедись, что нет форматирования вроде блоков кода? Инструкция говорит, что форматирование не нужно; может быть просто текст, но всё равно можно писать строки кода. Нужно избегать блоков кода. Просто обычные строки. Мы предоставим простой псевдокод. **Перечисление состояний** ``` НАЧАЛО, ИНТРО, ВЫБОР_А, ВЫБОР_В, ЦИКЛ_А, ЦИКЛ_В, КОНЕЦ_А, КОНЕЦ_В ``` **Переменные** ``` текущееСостояние = НАЧАЛО счетчикЦикла = 0 максЦиклов = 2 ``` **Основной цикл** ``` пока текущееСостояние != КОНЕЦ_А и текущееСостояние != КОНЕЦ_В: состояние текущееСостояние: случай НАЧАЛО: рассказ("Ты стоишь на перепутье приключения.") текущееСостояние = ИНТРО случай ИНТРО: рассказ("Слышишь слабый отголосок, зовущий тебя. Что ты делаешь?") предложитьВарианты(["Пойти в левый туннель", "Подойти к реке"]) # Предположим, что playerChoice хранит индекс если playerChoice == 0: текущееСостояние = ВЫБОР_А иначе: текущееСостояние = ВЫБОР_В случай ВЫБОР_А: рассказ("Ты входишь в тусклый туннель.") # имитируем несколько шагов если счетчикЦикла < максЦиклов: текущееСостояние = ЦИКЛ_А иначе: рассказ("Ты чувствуешь резкий толчок назад к входу.") текущееСостояние = ИНТРО случай ЦИКЛ_А: рассказ("Факел теперь горит ярче. Появляется ящик.") предложитьВарианты(["Открыть светящийся ящик", "Вернуться к началу туннеля"]) если playerChoice == 0: текущееСостояние = КОНЕЦ_А иначе: текущееСостояние = ВЫБОР_А счетчикЦикла += 1 случай ВЫБОР_В: рассказ("Ты идешь к реке, вода спешит мимо тебя.") если счетчикЦикла < максЦиклов: текущееСостояние = ЦИКЛ_В иначе: рассказ("Ты чувствуешь резкий толчок назад к берегу реки.") текущееСостояние = ИНТРО случай ЦИКЛ_В: рассказ("Рыба сверкает, промелькнула в ручье.") предложитьВарианты(["Следовать за рыбой", "Вернуться к берегу реки"]) если playerChoice == 0: текущееСостояние = КОНЕЦ_В иначе: текущееСостояние = ВЫБОР_В счетчикЦикла += 1 случай КОНЕЦ_А: рассказ("Ты нашел скрытый ключ. Квест завершен.") случай КОНЕЦ_В: рассказ("Ты поймал рыбу, и открывается новый путь.") ``` **Вспомогательные функции** ``` функция рассказ(текст): вывести(текст) функция предложитьВарианты(варианты): // Показать варианты игроку и сохранить их выбор в playerChoice ```
Slonephant Slonephant
``` Состояние: СТАРТ Состояние: ИНТРО Состояние: ВЫБОР_А Состояние: ВЫБОР_Б Состояние: ЛУП_А Состояние: ЛУП_Б Состояние: КОНЕЦ_А Состояние: КОНЕЦ_Б Переменные текущееСостояние = СТАРТ счетчикЛупов = 0 максимумЛупов = 2 Основной цикл пока текущееСостояние != КОНЕЦ_А и текущееСостояние != КОНЕЦ_Б если текущееСостояние == СТАРТ озвучить "Ты стоишь на перепутье своего приключения." текущееСостояние = ИНТРО иначе если текущееСостояние == ИНТРО озвучить "Тонкий отзвук зовет тебя. Что ты сделаешь?" предложитьВыбор ["Войти в левый туннель", "Пойти к реке"] если выборИгрока == 0 текущееСостояние = ВЫБОР_А иначе текущееСостояние = ВЫБОР_Б иначе если текущееСостояние == ВЫБОР_А озвучить "Ты направляешься в тусклый туннель." если счетчикЛупов < максимумЛупов текущееСостояние = ЛУП_А иначе озвучить "Ты чувствуешь резкий отток назад к выходу." текущееСостояние = ИНТРО иначе если текущееСостояние == ЛУП_А озвучить "Факел теперь горит ярче. Появляется ящик." предложитьВыбор ["Открыть светящийся ящик", "Вернуться к началу туннеля"] если выборИгрока == 0 текущееСостояние = КОНЕЦ_А иначе текущееСостояние = ВЫБОР_А счетчикЛупов += 1 иначе если текущееСостояние == ВЫБОР_Б озвучить "Ты идешь к реке, вода бежит мимо." если счетчикЛупов < максимумЛупов текущееСостояние = ЛУП_Б иначе озвучить "Ты чувствуешь резкий отток назад к берегу реки." текущееСостояние = ИНТРО иначе если текущееСостояние == ЛУП_Б озвучить "Рыба мелькает по течению, переливаясь." предложитьВыбор ["Пойти за рыбой", "Вернуться к берегу"] если выборИгрока == 0 текущееСостояние = КОНЕЦ_Б иначе текущееСостояние = ВЫБОР_Б счетчикЛупов += 1 иначе если текущееСостояние == КОНЕЦ_А озвучить "Ты нашел спрятанный ключ. Квест завершен." иначе если текущееСостояние == КОНЕЦ_Б озвучить "Ты поймал рыбу, и открывается новый путь." Вспомогательные функции функция озвучить(текст) вывести(текст) функция предложитьВыбор(выбор) // Показать варианты игроку и сохранить выбор в выборИгрока Пожалуйста, поправьте любое из повествований или логику ветвления, прежде чем мы перейдем к диаграмме. ```
Connor Connor
Выглядит основательно, но я бы добавил небольшую реплику рассказчика после каждого перехода, чтобы история ожила. Может, стоит сбрасывать loopCount при возврате к INTRO, чтобы игрок мог еще раз пройти по каждой ветке. И добавь небольшой таймаут после повествования, чтобы все не вываливалось сразу. Как только будешь доволен, накидаем схему.
Slonephant Slonephant
``` Состояние: СТАРТ Состояние: ИНТРО Состояние: ВЫБОР_А Состояние: ВЫБОР_Б Состояние: ЛУП_А Состояние: ЛУП_Б Состояние: КОНЕЦ_А Состояние: КОНЕЦ_Б Переменные текущееСостояние = СТАРТ счетчикЛупов = 0 максЛупов = 2 задержкаВСекундах = 1 Основной цикл пока текущееСостояние != КОНЕЦ_А и текущееСостояние != КОНЕЦ_Б если текущееСостояние == СТАРТ озвучить "Ты стоишь на перепутье своего приключения." задержка задержкаВСекундах текущееСостояние = ИНТРО иначе если текущееСостояние == ИНТРО озвучить "Ты слышишь тихий зов. Что ты предпримешь?" задержка задержкаВСекундах предложитьВыбор ["Пойти в левый туннель", "Направиться к реке"] если выборИгрока == 0 текущееСостояние = ВЫБОР_А озвучить "Ты решил, что туннель выглядит многообещающе." иначе текущееСостояние = ВЫБОР_Б озвучить "Ты чувствуешь прохладу речного бриза, манящего тебя." иначе если текущееСостояние == ВЫБОР_А озвучить "Ты углубляешься в тусклый туннель." задержка задержкаВСекундах если счетчикЛупов < максЛупов текущееСостояние = ЛУП_А озвучить "Твой факел мерцает, намекая на то, что впереди еще есть что увидеть." иначе озвучить "Ты чувствуешь внезапный толчок назад, к выходу." задержка задержкаВСекундах текущееСостояние = ИНТРО счетчикЛупов = 0 иначе если текущееСостояние == ЛУП_А озвучить "Твой факел теперь горит ярче. Появляется ящик." задержка задержкаВСекундах предложитьВыбор ["Открыть светящийся ящик", "Вернуться к началу туннеля"] если выборИгрока == 0 текущееСостояние = КОНЕЦ_А озвучить "В ящике оказывается скрытый ключ!" иначе текущееСостояние = ВЫБОР_А озвучить "Ты отступаешь назад, решая глубже исследовать." счетчикЛупов += 1 иначе если текущееСостояние == ВЫБОР_Б озвучить "Ты идешь к реке, мимо журчащей воды." задержка задержкаВСекундах если счетчикЛупов < максЛупов текущееСостояние = ЛУП_Б озвучить "Ты замечаешь всплеск — там рыба." иначе озвучить "Ты чувствуешь внезапный толчок назад, к берегу реки." задержка задержкаВСекундах текущееСостояние = ИНТРО счетчикЛупов = 0 иначе если текущееСостояние == ЛУП_Б озвучить "Рыба мелькает по течению, сверкая." задержка задержкаВСекундах предложитьВыбор ["Пойти за рыбой", "Остаться на берегу"] если выборИгрока == 0 текущееСостояние = КОНЕЦ_Б озвучить "Ты ловишь рыбу, и открывается новый путь!" иначе текущееСостояние = ВЫБОР_Б озвучить "Ты решаешь остаться на берегу, возможно, там еще что-то есть." счетчикЛупов += 1 иначе если текущееСостояние == КОНЕЦ_А озвучить "Ты нашел спрятанный ключ. Квест завершен." иначе если текущееСостояние == КОНЕЦ_Б озвучить "Ты поймал рыбу, и открывается новый путь." Вспомогательные функции функция озвучить(текст) напечатать(текст) функция предложитьВыбор(варианты) // Показать варианты игроку и сохранить выбор в выборИгрока функция задержка(секунды) // Пауза на заданное количество секунд (зависит от платформы) ```