BehaviourTree - простая реализация деревьев поведений

Деревья поведений (BehaviourTree) - довольно часто используемый подход для построения логики поведения ботов. Существует много комплексных решений, предоставляющих визуальное построение, отладку, плотную интеграцию в какой-то движок. Но что, если все это излишне и требуется минимальный размер, простота сборки, скорость работы и возможность работать на сервере без движка?
В общем случае Деревья состоят из узлов (Node), собирающихся в иерархию по определенным правилам. В каждый момент времени выполняется только один узел, затем происходит переход к следующему на основе результатов работы текущего - Дерево является по сути конечным автоматом (FSM - Finite State Machine), способным обрабатывать входящие данные и переключать внутренние состояния на их основе. Можно рассматривать Дерево как блок-схему работы какого-то алгоритма обработки данных.
Узлы являются атомарными абстрактными единицами построения Дерева и могут содержать в себе произвольную логику работы, которая не зависит от логики других узлов. Узлы обычно имеют на выходе результат работы - какой-то признак корректности завершения, ошибки, отложенной работы и т.п. В некоторых реализациях узлы имеют жестко зафиксированные входящие параметры - это помогает в визуальном построении Деревьев с подключением связей в нужные порты.
Примеры типов узлов, встречающихся практически во всех реализациях Деревьев:
- Пользовательский код - обертка над кодом, который должен выполниться в определенном месте работы
Дерева. - Условное ветвление - аналог “if A then B else C” - если условие
Aверно - можно переходить кB, иначе кC. - Отрицание - инверсия результата работы: был успех, станет провал и наоборот.
- Альтернативный выбор - аналог “switch { case A then B; case C then D; }” - набор пар “условие”/“обработчик”, выполняющегося в случае срабатывания условия.
- Последовательность - цепочка-список
узлов, выполняющихся последовательно друг за другом. - Цикл - аналог “while A do B” - повторять выполнение
Bпока условиеAверно.
Пакет Leopotam.Ai.Bt реализует все перечисленное и предлагает сборку Дерева из кода. Давайте соберем следующее дерево:
1 | sequence: |
Его реализация может выглядеть примерно так:
1 | // Данные, которые будем обрабатывать. |
Это сильно упрощенный пример без использования всего функционала, каждый узел может быть комплексным и состоять из десятка других узлов, собранных в нужную композицию.
Реализация в пакете Leopotam.Ai.Bt дает возможность разделения обработки узла на несколько кадров с автоматическим продолжением с места остановки, а так же поддерживает реализацию своих типов узлов в случае необходимости.