Я только что посмотрел на эту реализацию, и мне стало интересно, зачем столько кода нужно для чего-то относительно простого.
Судя по тому, что вы говорите, вам нужен простой способ составления поведения. Я полагаю, что здесь поведение — это отображение состояния на ноль или более действий агента. Вы можете легко смоделировать это с помощью лямбда-выражений C#. Например:
Action Selector(Func<bool> cond, Action ifTrue, Action ifFalse) {
return () => { if cond() then ifTrue() else ifFalse() };
}
Action Sequencer(Action a, Action b) {
return () => { a(); b(); }
}
Листья вашего дерева — это простые Действия, которые делают что-то соответствующее состоянию. Вы "запускаете" дерево, просто выполняя его.
Если вы хотите пофантазировать, вы можете параметризовать эту схему, чтобы сделать состояние явным.
Надеюсь это поможет.
---- Дополнение ----
Джейсон попросил привести пример того, как вы можете использовать этот подход, поэтому вот простой пример патрулирования охранника с «ИИ» (я предполагаю, что WorldState соответствует описанию среды во время оценки дерева поведения):
Func<bool> ifPlayerIsInSight = () => ...true iff WorldState shows guard can see player...;
Action shootAtPlayer = () => { ...aim guard's weapon at player and fire... };
Func<bool> ifUnderFire = () => ...true iff WorldState shows guard hears player gunfire...;
Action takeCover = () => { ...guard runs for nearest shelter... };
Action walkBackAndForthGuardingDoorway = () => { ...default guard patrol behaviour... };
Action patrollingGuardBehaviour =
Selector(ifPlayerIsInSight, shootAtPlayer,
Selector(ifUnderFire, takeCover,
walkBackAndForthGuardingDoorway));
Чтобы заставить охрану что-то сделать, достаточно позвонить patrollingGuardBehaviour()
. Обратите внимание, что различные поддействия и тесты могут быть реализованы как методы с правильными сигнатурами, а не встроены как лямбда-выражения. К Selector
и Sequencer
можно добавить другие комбинаторы, например, для параллельной работы.
person
Rafe
schedule
22.11.2010