...

понедельник, 19 февраля 2018 г.

[Перевод] Редактор сценариев Age of Empires 2 можно превратить в машину Тьюринга

image

Ничто не может сравниться с вечером, потраченным на логику высказываний, машины Тьюринга
и редактор сценариев AOE2…

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

1. Считывать и записывать символы
2. Менять позицию в моём «пространстве памяти»
3. Иметь «ленту» или «память»
4. Иметь пул используемых символов

Кроме того, мне нужно иметь возможность записывать какие-нибудь правила. Здесь также будет очень полезен доступ к логике высказываний. С этого я и начал свои исследования (то есть с поисков в Гугле), и через полчаса получил все нужные мне ответы.
Достаточно удовлетворяют требованиям следующие объекты, условия и эффекты:

Пул символов: любое число игровых юнитов
Пул памяти: все типы юнитов, доступных в игре (см. примечание в конце поста)

Изменение позиции в памяти: Create Object

Запись в позицию памяти: Create Object, Task Object, Kill Object

Чтение из позиции памяти: Own Objects, Own Fewer Objects

Вот пример использования типов игровых юнитов в качестве «ячеек» памяти:


В этом примере память выглядит так: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1

Но мы можем очень просто изменить память с помощью триггеров, чтобы она выглядела так:


То есть: 8, 1, 8, 1, 1, 8, 1, 1, 1, 1

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

Параллельное выполнение:

T1      T2      T3
C1 (T)  C1 (F)  C1 (F)
C2 (F)  C2 (T)  C2 (F)
C3 (F)  C3 (F)  C3 (T)

Все три триггера (T) срабатывают одновременно и сконфигурированы таким образом, что условия (С) заставляют их срабатывать в нужное время.

Древовидное выполнение:

T1 запускает T2 запускает (T3 или T4)

T1 «управляет» программой, являясь единственным триггером, начинающим работать при запуске игры и выполняющим бесконечный цикл. Он передаёт выполнение триггеру T2, а затем T2 запускает T3 и T4, но они сами между собой решают, кто из них должен выполняться (похоже на то, как ведут себя триггеры при параллельном выполнении, или на то, что ниже делает XOR).

Мне кажется, что это более практичный способ структурирования таких программ, и он эффективнее, потому что содержит меньше инструкций.

Имеет ли редактор сценариев какую-то возможность для реализации логики выражений? Да. У нас есть доступ к условиям, то есть мы можем создать if -> then, а это в сочетании с Own Objects и Own Fewer Objects, позволяет получать доступ к памяти и выполнять сравнения.

Мы можем объединить два выражения/условия, поэтому можно просто реализовать операции «AND»:

Own Objects (Unit type: Soldiers, Amount: 7)
Own Objects (Unit type: Archers, Amount: 10)

Также с помощью триггеров можно реализовать частичное «OR». Проблема с ним в том, что если обе ветви истинны, то будут выполнены оба триггера. Поэтому более полезным оператором будет «XOR»:
Trigger 1       Trigger 2
Condition 1 (T) Condition 1 (F)
Condition 2 (F) Condition 2 (T)
Effects         Effects

Оба триггера срабатывают одновременно, но выполняется только одна ветка эффектов, потому что условие Condition 1 должно быть истинным в одной, но ложным в другой, и наоборот для условия Condition 2.

Также с помощью Own Fewer Objects, Create Object, Task Object и Kill Object можно легко реализовать сложение и вычитание:

Trigger 1
Own Fewer Objects (Unit type: Soldiers, Amount: 9)
Create Object (Soldier)
Task Object (Move to location)

Trigger 2
Own Fewer Objects (Unit type: Soldiers, Amount: 17)
Create Object (Soldier)
Task Object (Move to location)

Пример того, как это может выглядеть в игре:

Нам необходим Task Object, потому что игра не будет создавать больше одного объекта в одной точке, поэтому мы заставляем его переместиться.

Результат этой операции можно найти в счётчике юнитов в верхней части экрана.

Более сложный, но полезный набор триггеров и условий позволяет выполнять операции проверки на равенство, в том числе «равно», «меньше или равно», «больше или равно». Однако для их правильной работы нам нужно ввести специальный символ «останова» — короля (King):


Конфигурация для «больше ли 23, чем 9» будет иметь вид:
Trigger 1 (On-startup, Loop)
Own Fewer Objects (Unit type: Soldiers, Amount: 23)
Create Object (Soldier)
Activate Trigger (2)

Trigger 2 (No loop)
Own Objects (Unit type: Soldiers, Amount: 9)
Own Fewer Objects (Unit type: King, Amount: 0)
Create Object (King)

Эта система будет постоянно создавать солдат, пока их не станет 23. Если у нас их окажется 9 или больше, это будет означать, что 23 больше, чем 9 и для обозначения этого мы создаём короля (King). В процессе создания сценариев можно изменить юнита «останова» на любого другого, или создать любое нужное их количество.

В целом это не особо полезно, но всё равно здорово!

К сожалению, мне не удалось найти простого способа записывать видео, но если кому-то это удастся, то я добавлю их сюда.



Так, похоже я не совсем понимал, что такое Тьюринг-полнота. Я не только должен иметь возможность создать машину Тьюринга, но это ещё и должна быть любая машина Тьюринга. Чтобы реализовать её, мне нужна «бесконечная» память. В нашем случае, мы ограничены количеством типов юнитов, но мы можем создать произвольное количество для решения этой проблемы: http://aok.heavengames.com/university/modding/an-introduction-to-creating-units-with-age-2/

Let's block ads! (Why?)

Комментариев нет:

Отправить комментарий