Я только что посмотрел на эту реализацию, и мне стало интересно, почему столько кода требуется для чего-то относительно простого.
Исходя из того, что вы говорите, вам нужен простой способ составления поведения.Поведение здесь, я полагаю, является отображением состояния в ноль или более действий агента.Вы можете легко смоделировать это, используя C # lambdas.Например:
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(); }
}
Листья вашего дерева - это простые Действия, которые делают что-то соответствующее состоянию.Вы «запускаете» дерево, просто выполняя его.
Если вы хотите проявить фантазию, вы можете параметризовать эту схему, чтобы сделать состояние явным.
Надеюсь, это поможет.
---- Приложение ----
Джейсон попросил привести пример того, как вы могли бы использовать этот подход, так что вот простой пример патрулирования "AI" (я предполагаю, что 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
, например, для параллельной деятельности.