Dagaz: Пинки здравому смыслу (часть 10)
… Десять настанет…
И ты задрожишь,
Как осиновый лист задрожишь!
Юринэ «Карас»
Менее всего заметно то, что лежит на поверхности. За привычной обыденностью, мы не видим чудесного. Разработчики настольных игр придумывают всё новые и новые игровые механики, но часто путают «интересность» игры с её «сложностью». Чтобы было понятно, о чём идёт речь, приведу пример:
Каждый игрок имеет по три 3-минутных «склянки». Кроме того, в игре используются нейтральные 15-секундные часы, для ограничения времени хода. В начале игры, «фигуры» расставляются в углах шестиугольной доски, с чередованием цвета. Выполняя ход, каждый игрок перемещает одну из склянок на соседнее поле (в любом направлении), переворачивая её. Сразу же после этого, на поле с фигурой надевается кольцо. Правилами запрещается выполнять ход фигурой, песок в которой полностью высыпался (первыми тремя ходами каждый игрок обязан «взвести» все свои часы) и ходить на те поля, среза трубки которых достигли кольца (трубки полей имеют различную высоту). Игра заканчивается, когда ходы становятся невозможными. Побеждает игрок надевший больше всего колец.
Безусловно, эта игра очень сложна (её совершенно точно не удастся описать на ZRF, а на Axiom, с её поддержкой таймеров, вряд ли удастся разработать сколь нибудь дружественный интерфейс), но эта сложность выглядит какой-то искусственной, «притянутой за уши». Как разработчика настольных игр, меня интересуют игры, «бросающие вызов» существующим средствам разработки, но я не приветствую «сложность ради самой сложности». Я хочу рассказать про…
1. Простые вещи
Весь этот цикл статей я затевал, в основном, для того, чтобы определить границы возможностей существующего «универсального» инструментария («Zillions of Games» и «Axiom Development Kit»), предназначенного для разработки настольных игр. Новый проект стоит затевать лишь в том случае, если найдутся задачи, которые он сможет решать лучше, чем уже существующие (или просто сможет решать). В результате чего возникают ограничения функциональности? Разработчики сами придумывают их!
Разрабатывая любой продукт (ZoG не исключение), его создатели принимают ряд допущений, облегчающих им жизнь. За примерами далеко ходить не надо. В шахматах, фигуры выполняющие взятие, замещают собой взятые. Этот механизм настолько общий, для всех игр шахматного семейства, что называется «шахматным взятием». Разработчики ZoG посчитали хорошей идеей — не удалять взятые фигуры явно (если их место, по завершении хода, занимает другая фигура). В результате родилось ограничение — одно поле не может содержать более одной фигуры (для шашек шахматный механизм взятия был не актуален, но и новое ограничение их не аффектило). Игры, в которых это ограничение не выполняется (разнообразные манкалы, Таврели, Столбовые шашки) немедленно оказались «за бортом». Поймите меня правильно. Сделать такие игры можно, но их разработка превращается в настоящий кошмар!
Другое «благое намеренье», отлитое из бронзы, звучит так: «игрок может ходить только своими фигурами». Ставропольские шашки имеют своё мнение на этот счёт. Да, их тоже можно сделать, но как! Для того, чтобы оба игрока могли двигать все фигуры, их пришлось сделать нейтральными (то есть завести ещё одного игрока, не участвующего в игре, но владеющего всеми фигурами). Мало того, что совершенно искусственное ограничение приводит к серьёзному усложнению реализации, часть возможного функционала становится просто недоступной.
В этой игре есть и фигуры, принадлежащие игрокам и нейтральная фигура «мяч». Сделав ход своей фигурой, игрок перемещает нейтральную фигуру. В таком виде всё работает, но средствами ZRF невозможно выполнить ход своей фигурой или нейтральной. То и другое по очереди, но не то или другое вместе! Иногда, это мешает (и вновь приводит к чрезмерному усложнению кода). Ещё хуже всё становится при сочетании нескольких «антипаттернов».
Для определения обязательного взятия, в играх семейства шашек, ZRF использует механизм приоритетов. Это решение, само по себе, не очень удачно, поскольку приоритеты могли бы быть легко реализованы на основе более универсального механизма, но, что более важно, делает недоступным целый пласт функциональности, в таких играх как «Ставропольские шашки». В шашках, игрок обязан выполнить взятие, если у него есть такая возможность (это очень важно, в тактическом плане), но, в «Ставропольских шашках», игрок может ходить фигурами обеих сторон. Хотя оригинальные правила этот момент не оговаривают, было бы интересно сделать взятие своими фигурами более приоритетным (а взятие фигурами противника, например, вообще не обязательным), но добиться этого в ZRF нельзя! Никак!
Великолепная вторая миссия кампании Хаоса в Battle vs Chess (начиная с 6:40, настройка start на Хабре, к сожалению, не работает). Чёрные могут добавлять свои фигуры из резерва в любое место доски, если тем самым не шахуют белых. Даже с учётом этого ограничения, у чёрных серьёзное преимущество, поскольку, как нам известно из Сёги, «фигура в руке сильнее фигуры на доске».
Играя в эту игру впервые, я не справился с управлением (сбрасываемая фигура переключается колёсиком мыши) и сбрасывал фигуры на доску строго по старшинству (первыми всех пешек, затем коней, слонов и лишь в последнюю очередь — ферзя). Даже с учётом этого, я легко победил и игра, в таком режиме, на мой взгляд, оказалась даже более интересной. Клон оригинальной миссии я сделал, но с добавлением фигур на доску «по старшинству» возникли проблемы, связанные со всё теми же приоритетами. Можно сделать приоритетными ходы сброса фигур, но приоритет перемещения фигур должен совпадать с каждым из этих приоритетов (иначе, до завершения сброса всех фигур, не удастся сдвинуть ни одну фигуру, включая короля, даже попавшего под шах). В ZRF это совершенно невозможно! Приоритетам ZRF явно не хватает гибкости.
Тема взаимодействия разнородных опций, вообще, неисчерпаема. Так, например, в играх семейства «Халма» (в нашей стране, один из её вариантов известен под именем «Уголки») возникает необходимость «пометки» ранее посещённых полей, во избежание возможного зацикливания ходов. На первый взгляд, для этой цели идеально подходят «позиционные флаги», позволяющие связать булевское значение с определённой позицией, на время выполнения хода. К сожалению, как и при использовании глобальных флагов, установленные значения автоматически обнуляются в начале каждого хода. Поскольку составной ход в ZoG состоит из вполне самостоятельных «частичных» ходов, позиционные флаги не оправдывают связанных с ними ожиданий. Решать проблему приходится «помечая» не поля, а фигуры при помощи их атрибутов (вроде используемых при выполнении проверки возможности рокировки), но это тема для отдельного разговора.
В играх семейства шашек, атрибуты фигур используются для предотвращения «Турецкого удара». По правилам, принятым в большинстве современных вариантов игры, взятые фигуры удаляются с доски лишь при завершении хода, все вместе. Для нас, это означает две вещи: во первых, из множества «частичных» необходимо выделить самый последний ход, чтобы при его выполнении удалить все взятые фигуры (при использовании «правила большинства» или превращения шашек во время выполнения хода, как в «Русских шашках» — это, само по себе, непростая задача). Кроме того, необходимо помечать взятые фигуры, используя атрибуты или превращение фигур. Здесь нас и подстерегает сюрприз. ZSG-нотация построена таким образом, что помеченную или превращённую фигуру, тем же ходом, удалить не удастся! Это означает, что последнюю взятую фигуру помечать не нужно и следует удалять индивидуально. Добавьте к этому не очень удобную семантику перемещения фигур (до завершения генерации хода, фигуры, выполняющие ход, как бы остаются на своих местах) и разработка, казалось бы, банальных шашек превратится в сложный и увлекательный квест, наполненный приключениями и борьбой с «боссами».
Когда, ко всему этому, добавляются проблемы с определением приоритетов, жизнь разработчика становится ещё интереснее. В варианте шашек, распространённом на территории Осетии (Кены), в целом, очень похожем на турецкие и армянские шашки, было введено интересное правило. Не превращённая шашка (кен) может перескакивать через дружественные кены, подобно тому, как это делается в играх семейства «Халма». К сожалению, мне так и не удалось выяснить, разрешается ли чередовать такие прыжки со взятием вражеских фигур, но такой вариант был бы, несомненно, наиболее интересен. И именно его воплотить в ZRF, по всей видимости, никогда не удастся. Поскольку взятия должны оставаться приоритетными, а «прыжки» можно чередовать со взятиями в произвольном порядке — их необходимо сделать приоритетными тоже. Но если сделать так, обычные (низкоприоритетные) ходы удастся выполнять лишь в исключительно редких случаях.
Часто, сложные в реализации правила являются следствием усовершенствований игры её создателями. Так, в классическом «Ordo» Дитера Штейна, инвариантом игры является «связность» фигур, по завершении хода. Если группа фигур разделилась (учитываются соседи как по ортогоналям, так и по диагоналям), ход, восстанавливающий связность, является приоритетным. Если найти такой ход не удаётся — игроку засчитывается поражение. В таком виде, хотя и не без труда, игру удалось описать на Axiom. В улучшенном варианте OrdoX, помимо введения новых (диагональных) ходов, было изменено правило сохранения связности. Теперь, на доске должна оставаться лишь наибольшая группа из разделённых, но если есть несколько (возможно больше двух) равных групп, игрок вправе выбрать, какую из них оставить на доске. Если решение и возможно в ZoG, оно окажется крайне трудоёмко.
Более древний пример улучшения игровых правил можно найти в одной из разновидностей «Боевых гонок», распространённой в Западной Сахаре, Марокко и Центральном Алжире. В Sigh, как и в большинстве таких игр, используются «кости», выполненные в виде четырёх плоских палочек. Выпавшие очки считаются по количеству палочек, упавших светлой стороной вверх. В целом, в этой игре, всё как обычно — есть броски, вводящие в игру новую фишку (1- khadzh), дополнительные броски (например, 4 — barga), но есть один, бросок, делающий игру действительно уникальной. Двухочковый (khmar) — аннулирует результат предыдущего броска и даёт право на повторный бросок. Если он выпадет снова, аннулируется ещё более ранний ход (соответствующая фишка возвращается в исходное положение) и так далее. Для корректной реализации этой игры, придётся вести журнал ходов, с возможностью их отката!
Некоторые игры пересматривают саму концепцию хода. В «Ambiguous Chess», показанной выше, игрок, выполняющий ход, указывает поле, на которое он собирается сходить, а уже его противник выполняет сам ход одной из фигур, способных его выполнить. Сделать такую игру в ZoG сложно, но можно. «Refusal Chess» идёт ещё дальше! В ней противник может запретить выполнение объявленного игроком хода (если этот ход не является единственно возможным) и тогда игрок должен будет сделать другой ход. Наверное, это тоже можно реализовать на ZRF, но я не очень-то хорошо себе представляю как.
Но и это не предел! В первой части цикла, я уже упоминал эфиопский Senterej, в котором игроки начинают игру, выполняя ходы одновременно, до первого боя фигуры. В манкале «Сулус-айди», в таком же режиме выполняется «нулевой посев», определяющий право первого хода и, заодно, нарушающий детерминизм первоначального расклада камней. Подчеркну, игроки одновременно берут и раскладывают камни из одних и тех же лунок! Думаю, аудитория на Хабре хорошо понимает, что это означает. Если вам мало и этого, подумайте о том, с какими сложностями придётся столкнуться в процессе реализации в ZoG всем знакомого «Подкидного дурака». Надеюсь, я довёл до вас свою мысль:
На всякого мудреца довольно простоты.