Неразрешимость игры Braid — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Полное описание счетчиковой машины)
(Сдвиг картинок)
Строка 21: Строка 21:
 
Проблема останова игры «Жизнь» неразрешима.
 
Проблема останова игры «Жизнь» неразрешима.
 
|proof =  
 
|proof =  
Заметим, что если существует МТ, которая по начальной конфигурации уровня в Braid может определить, завершается ли она, то та же МТ может определить, останавливается ли любая МТ, что противоречит неразрешимости проблемы останова для МТ. Следовательно, необходимо описать процесс построения МТ в игре Braid. Построим [[Счетчиковые машины, эквивалентность двухсчетчиковой машины МТ|счетчиковую машину]], эквивалентную МТ. Подаваемая на вход программа будет содержать следующие операции:
 
* прибавить: увеличивает на 1 значение выбранного счетчика.
 
* вычесть и перейти: сравнивает с нулем значение выбранного счетчика. Если оно больше нуля, из него вычитается единица; если равно нулю, происходит переход на указанную строку в программе.
 
* остановиться.
 
 
 
[[Файл:Platform.png|200px|thumb|right| Платформа с рычагом]]  
 
[[Файл:Platform.png|200px|thumb|right| Платформа с рычагом]]  
 
[[Файл:Cannon.png|200px|thumb|right| Пушка]]
 
[[Файл:Cannon.png|200px|thumb|right| Пушка]]
Строка 33: Строка 28:
 
[[Файл:Counter.png|200px|thumb|right| Устройство-счетчик]]
 
[[Файл:Counter.png|200px|thumb|right| Устройство-счетчик]]
 
[[Файл:Branch.png|200px|thumb|right| Устройство ветвления]]
 
[[Файл:Branch.png|200px|thumb|right| Устройство ветвления]]
 +
 +
Заметим, что если существует МТ, которая по начальной конфигурации уровня в Braid может определить, завершается ли она, то та же МТ может определить, останавливается ли любая МТ, что противоречит неразрешимости проблемы останова для МТ. Следовательно, необходимо описать процесс построения МТ в игре Braid. Построим [[Счетчиковые машины, эквивалентность двухсчетчиковой машины МТ|счетчиковую машину]], эквивалентную МТ. Подаваемая на вход программа будет содержать следующие операции:
 +
* прибавить: увеличивает на 1 значение выбранного счетчика.
 +
* вычесть и перейти: сравнивает с нулем значение выбранного счетчика. Если оно больше нуля, из него вычитается единица; если равно нулю, происходит переход на указанную строку в программе.
 +
* остановиться.
  
 
В нашей машине счетчиками будут являться группы монстров. "Программа" будет выполняться Тимом: чтобы пройти уровень, ему нужно нажать на каждый рычаг на своем пути. Каждый рычаг выполняет либо операцию "добавить", либо "вычесть и перейти". Чтобы допустить переходы (''goto''), некоторые участки пути могут вести к более ранним местам на этом пути.
 
В нашей машине счетчиками будут являться группы монстров. "Программа" будет выполняться Тимом: чтобы пройти уровень, ему нужно нажать на каждый рычаг на своем пути. Каждый рычаг выполняет либо операцию "добавить", либо "вычесть и перейти". Чтобы допустить переходы (''goto''), некоторые участки пути могут вести к более ранним местам на этом пути.

Версия 22:35, 15 января 2016

Игра Braid — изданный в 2008 году платформер-головоломка, основным элементом которого является способность главного героя поворачивать время вспять.

Игровые объекты

Тим и часть паззла
Тим (англ. Tim) — главный герой игры. Возвышение перед ним иллюстрирует максимальную высоту его прыжка. На возвышении находится часть паззла. Цель игры — заполучить ее.
Монстр (англ. monstar). Ходит по прямой линии, падает с возвышений, разворачивается, когда сталкивается с препятствием. Тим может оттолкнуться от него, чтобы прыгнуть выше.
Монстр
Рычаг (англ. lever) и платформа (англ. platform). Подъем платформы контролируется нажатием рычага. Платформу можно установить таким образом, чтобы она поднималась при нажатии рычага и падала, столкнувшись с другим объектом.
Односторонние поверхности (англ. one-way surfaces) позволяют проходить сквозь них в одну сторону, но не пускают обратно. На иллюстрации Тим может запрыгнуть на поверхность (2), но не сможет спуститься вниз. Монстр пройдет из области (1) в область (2), но не пройдет назад.
Односторонние поверхности
Пушка (англ. cannon). С некоторой периодичностью пушка стреляет определенными игровыми объектами (монстрами, кроликами, огненными шарами или облаками).
Кролик (англ. bunny). Монстр убивает кролика, сталкиваясь с ним. Это может быть использовано, чтобы отделить одного монстра от группы монстров.

Перемотка времени

Игрок может зажимать клавишу Shift, чтобы отматывать время назад, чтобы исправить соверешенную ошибку или даже отменить смерть персонажа. Обычно эта механика упрощает прохождение игроку, но никак не влияет на вычислимость игры. Однако, в Braid некоторые объекты существуют вне времени и на них не действует перемотка. Например, вневременной кролик продолжит прыгать вперед, даже когда весь мир возвращается назад во времени. На таких объектах основывается большинство уникальных головоломок в Braid. После отмотки времени назад Тим может промотать его снова вперед, аналогично командам undo и redo в различных редакторах. Как и с командами undo и redo, совершение каких-либо действий после отмотки времени назад не позволит промотать его вперед.

Неразрешимость

Теорема:
Проблема останова игры «Жизнь» неразрешима.
Доказательство:
[math]\triangleright[/math]
Платформа с рычагом
Пушка
Кролик
Устройство нажатия рычага
Устройство-перекресток
Устройство-счетчик
Устройство ветвления

Заметим, что если существует МТ, которая по начальной конфигурации уровня в Braid может определить, завершается ли она, то та же МТ может определить, останавливается ли любая МТ, что противоречит неразрешимости проблемы останова для МТ. Следовательно, необходимо описать процесс построения МТ в игре Braid. Построим счетчиковую машину, эквивалентную МТ. Подаваемая на вход программа будет содержать следующие операции:

  • прибавить: увеличивает на 1 значение выбранного счетчика.
  • вычесть и перейти: сравнивает с нулем значение выбранного счетчика. Если оно больше нуля, из него вычитается единица; если равно нулю, происходит переход на указанную строку в программе.
  • остановиться.

В нашей машине счетчиками будут являться группы монстров. "Программа" будет выполняться Тимом: чтобы пройти уровень, ему нужно нажать на каждый рычаг на своем пути. Каждый рычаг выполняет либо операцию "добавить", либо "вычесть и перейти". Чтобы допустить переходы (goto), некоторые участки пути могут вести к более ранним местам на этом пути.

Для это нам понадобится соорудить из простых игровых объектов следующие устройства:

  • устройство нажатия рычага: заставляет Тима нажать на рычаг ровно единожды. Тим начинает в точке (1). Он может только упасть вниз к точке (2) и нажать на рычаг. Когда он нажмет на рычаг, платформа под ним поднимется вместе с ним к односторонней поверхности (3) с такой скоростью, чтобы Тим не смог нажать на рычаг еще раз. Поверхность (3) не даст Тиму спуститься вниз, и ему останется лишь пройти к выходу из устройства (4). Когда платформа достигнет поверхности (3), она вернется к своему начальному состоянию, что позволяет использовать устройство столько раз, сколько потребуется. В игре один рычаг может контролировать больше одной платформы, а платформы могут контролироваться более чем одним рычагом, поэтому такое устройство позволит управлять платформами в одной точке уровня из другой точки на этом уровне.
  • устройство-перекресток: позволяет отправлять Тима или монстров вниз по маршрутам произвольной длины.
  • устройство-счетчик: позволяет прибавлять или вычитать единицу. В точке (1) находится некоторое количество монстров [math]n[/math] — значение счетчика. Этим значением могут управлять устройства вычитания и прибавления единицы.
    • устройство прибавления единицы: пушка постоянно выстреливает новых монстров. Они отскакивают от платформы (2) и умирают на шипах. Устройство активируется, когда Тим нажимает рычаг, контролирующий платформу (2). Платформа ненадолго приподнимается, пропуская под собой одного монстра, и падает обратно. При каждой активации вышедший таким образом монстр проходит через одностороннюю поверхность (3) и оказывается заперт в участке (1), увеличивая таким образом счетчик на 1.
    • устройство вычитания единицы: пушка постоянно выстреливает новых кроликов. Как и в устройстве прибавления единицы, они отскакивают от платформы и умирают на шипах. При каждой активации платформа ненадолго сдвигается, пропуская одного кролика, который долетает до нижней границы (1) и касается ее. Если в участке (1) есть монстры, кролик погибнет от столкновения с одним из них, а тот при столкновении подскочит до верхней платформы и выйдет к участку (5). В противном случае кролик долетит до шипов (4) и погибнет там. Таким образом, при каждой активации, если значение счетчика не 0, один монстр убирается из счетчика и отправляется по определенному маршруту. Стоит заметить, что он не погибает, а идет по своему пути, что мы используем в устройстве ветвления.
  • устройство ветвления: отправляет Тима по одному из двух различных путей в зависимости от того, есть ли в устройстве монстр. Тим попадает в устройство в точке (1). Площадка и лестница (2) находятся слишком высоко, чтобы запрыгнуть на них, поэтому, если в устройстве монстра нет, Тим может только дойти до конца и выйти в точке (3). Если же монстр есть, Тим не может пройти к выходу (3), и ему остается только прыгнуть на монстра, тем самым убивая его и подскакивая выше, чем при обычном прыжке. Единственное место для этого — участок (2), и при прыжке на монстра Тим окажется на площадке без возможности спуститься вниз. Он может покинуть устройство только поднявшись по лестнице. Наличие или отсутствие монстра определяет, какой из выходов сможет использовать Тим.

Разместим три устройства-счетчика далеко друг от друга. Состоящий из устройств нажатия рычага и ветвления маршрут, который мы построим для Тима, и будет подаваемой на вход "программой". Например, если мы хотим добавить 1 к счетчику №2 в начале программы, то первая комната на пути будет устройством нажатия рычага, связанным с устройством прибавления единицы во втором устройстве-счетчике. Аналогично, рычаг может быть связан с устройством вычитания единицы в каком-либо счетчике. Тогда при активации, если значение счетчика не равно нулю, один монстр покинет счетчик. Чтобы выполнить переход при равенстве нулю, нам нужно отправить монстра в соответствующее устройство ветвления. Для этого все монстры, покидающие счетчик, будут попадать в соответствующую ему комнату, по которой они будут ходить. В полу этой комнаты будет множество платформ, работающих в качестве люков. Отправим Тима во второе устройство нажатия рычага, которое и откроет один из люков. Построенный нами путь под этим люком будет вести в устройство ветвления. Теперь Тим отправится в это устройство, но его маршрут сделаем значительно длиннее, чтобы он не мог опередить монстра, направляющегося туда же. В зависимости от того, был ли счетчик нулевым, Тим встретит или не встретит монстра в устройстве ветвления и пойдет по определенному пути.

Операции "прибавить" и "вычесть и перейти" описаны. Операция "остановиться" проста: построим комнату с частью паззла и выходом с уровня.
[math]\triangleleft[/math]