1 // BrainTree - A C++ behavior tree single header library.
2 // Copyright 2015-2018 Par Arvidsson. All rights reserved.
3 // Licensed under the MIT license (https://github.com/arvidsson/BrainTree/blob/master/LICENSE).
10 #include <unordered_map>
29 virtual Status update() = 0;
30 virtual void initialize() {}
31 virtual void terminate(Status s) {}
35 if (status != Status::Running) {
41 if (status != Status::Running) {
48 bool isSuccess() const { return status == Status::Success; }
49 bool isFailure() const { return status == Status::Failure; }
50 bool isRunning() const { return status == Status::Running; }
51 bool isTerminated() const { return isSuccess() || isFailure(); }
53 void reset() { status = Status::Invalid; }
55 using Ptr = std::shared_ptr<Node>;
58 Status status = Status::Invalid;
61 class Composite : public Node
64 Composite() : it(children.begin()) {}
65 virtual ~Composite() {}
67 void addChild(Node::Ptr child) { children.push_back(child); }
68 bool hasChildren() const { return !children.empty(); }
71 std::vector<Node::Ptr> children;
72 std::vector<Node::Ptr>::iterator it;
75 class Decorator : public Node
78 virtual ~Decorator() {}
80 void setChild(Node::Ptr node) { child = node; }
81 bool hasChild() const { return child != nullptr; }
84 Node::Ptr child = nullptr;
90 void setBool(std::string key, bool value) { bools[key] = value; }
91 bool getBool(std::string key)
93 if (bools.find(key) == bools.end()) {
98 bool hasBool(std::string key) const { return bools.find(key) != bools.end(); }
100 void setInt(std::string key, int value) { ints[key] = value; }
101 int getInt(std::string key)
103 if (ints.find(key) == ints.end()) {
108 bool hasInt(std::string key) const { return ints.find(key) != ints.end(); }
110 void setFloat(std::string key, float value) { floats[key] = value; }
111 float getFloat(std::string key)
113 if (floats.find(key) == floats.end()) {
118 bool hasFloat(std::string key) const { return floats.find(key) != floats.end(); }
120 void setDouble(std::string key, double value) { doubles[key] = value; }
121 double getDouble(std::string key)
123 if (doubles.find(key) == doubles.end()) {
128 bool hasDouble(std::string key) const { return doubles.find(key) != doubles.end(); }
130 void setString(std::string key, std::string value) { strings[key] = value; }
131 std::string getString(std::string key)
133 if (strings.find(key) == strings.end()) {
138 bool hasString(std::string key) const { return strings.find(key) != strings.end(); }
140 using Ptr = std::shared_ptr<Blackboard>;
143 std::unordered_map<std::string, bool> bools;
144 std::unordered_map<std::string, int> ints;
145 std::unordered_map<std::string, float> floats;
146 std::unordered_map<std::string, double> doubles;
147 std::unordered_map<std::string, std::string> strings;
150 class Leaf : public Node
155 Leaf(Blackboard::Ptr blackboard) : blackboard(blackboard) {}
157 virtual Status update() = 0;
160 Blackboard::Ptr blackboard;
163 class BehaviorTree : public Node
166 BehaviorTree() : blackboard(std::make_shared<Blackboard>()) {}
167 BehaviorTree(const Node::Ptr &rootNode) : BehaviorTree() { root = rootNode; }
169 Status update() { return root->tick(); }
171 void setRoot(const Node::Ptr &node) { root = node; }
172 Blackboard::Ptr getBlackboard() const { return blackboard; }
175 Node::Ptr root = nullptr;
176 Blackboard::Ptr blackboard = nullptr;
179 template <class Parent>
180 class DecoratorBuilder;
182 template <class Parent>
183 class CompositeBuilder
186 CompositeBuilder(Parent* parent, Composite* node) : parent(parent), node(node) {}
188 template <class NodeType, typename... Args>
189 CompositeBuilder<Parent> leaf(Args... args)
191 auto child = std::make_shared<NodeType>((args)...);
192 node->addChild(child);
196 template <class CompositeType, typename... Args>
197 CompositeBuilder<CompositeBuilder<Parent>> composite(Args... args)
199 auto child = std::make_shared<CompositeType>((args)...);
200 node->addChild(child);
201 return CompositeBuilder<CompositeBuilder<Parent>>(this, (CompositeType*)child.get());
204 template <class DecoratorType, typename... Args>
205 DecoratorBuilder<CompositeBuilder<Parent>> decorator(Args... args)
207 auto child = std::make_shared<DecoratorType>((args)...);
208 node->addChild(child);
209 return DecoratorBuilder<CompositeBuilder<Parent>>(this, (DecoratorType*)child.get());
222 template <class Parent>
223 class DecoratorBuilder
226 DecoratorBuilder(Parent* parent, Decorator* node) : parent(parent), node(node) {}
228 template <class NodeType, typename... Args>
229 DecoratorBuilder<Parent> leaf(Args... args)
231 auto child = std::make_shared<NodeType>((args)...);
232 node->setChild(child);
236 template <class CompositeType, typename... Args>
237 CompositeBuilder<DecoratorBuilder<Parent>> composite(Args... args)
239 auto child = std::make_shared<CompositeType>((args)...);
240 node->setChild(child);
241 return CompositeBuilder<DecoratorBuilder<Parent>>(this, (CompositeType*)child.get());
244 template <class DecoratorType, typename... Args>
245 DecoratorBuilder<DecoratorBuilder<Parent>> decorator(Args... args)
247 auto child = std::make_shared<DecoratorType>((args)...);
248 node->setChild(child);
249 return DecoratorBuilder<DecoratorBuilder<Parent>>(this, (DecoratorType*)child.get());
265 template <class NodeType, typename... Args>
266 Builder leaf(Args... args)
268 root = std::make_shared<NodeType>((args)...);
272 template <class CompositeType, typename... Args>
273 CompositeBuilder<Builder> composite(Args... args)
275 root = std::make_shared<CompositeType>((args)...);
276 return CompositeBuilder<Builder>(this, (CompositeType*)root.get());
279 template <class DecoratorType, typename... Args>
280 DecoratorBuilder<Builder> decorator(Args... args)
282 root = std::make_shared<DecoratorType>((args)...);
283 return DecoratorBuilder<Builder>(this, (DecoratorType*)root.get());
288 assert(root != nullptr && "The Behavior Tree is empty!");
289 auto tree = std::make_shared<BehaviorTree>();
298 // The Selector composite ticks each child node in order.
299 // If a child succeeds or runs, the selector returns the same status.
300 // In the next tick, it will try to run each child in order again.
301 // If all children fails, only then does the selector fail.
302 class Selector : public Composite
305 void initialize() override
307 it = children.begin();
310 Status update() override
312 assert(hasChildren() && "Composite has no children");
314 while (it != children.end()) {
315 auto status = (*it)->tick();
317 if (status != Status::Failure) {
324 return Status::Failure;
328 // The Sequence composite ticks each child node in order.
329 // If a child fails or runs, the sequence returns the same status.
330 // In the next tick, it will try to run each child in order again.
331 // If all children succeeds, only then does the sequence succeed.
332 class Sequence : public Composite
335 void initialize() override
337 it = children.begin();
340 Status update() override
342 assert(hasChildren() && "Composite has no children");
344 while (it != children.end()) {
345 auto status = (*it)->tick();
347 if (status != Status::Success) {
354 return Status::Success;
358 // The StatefulSelector composite ticks each child node in order, and remembers what child it prevously tried to tick.
359 // If a child succeeds or runs, the stateful selector returns the same status.
360 // In the next tick, it will try to run the next child or start from the beginning again.
361 // If all children fails, only then does the stateful selector fail.
362 class StatefulSelector : public Composite
365 Status update() override
367 assert(hasChildren() && "Composite has no children");
369 while (it != children.end()) {
370 auto status = (*it)->tick();
372 if (status != Status::Failure) {
379 it = children.begin();
380 return Status::Failure;
384 // The StatefulSequence composite ticks each child node in order, and remembers what child it prevously tried to tick.
385 // If a child fails or runs, the stateful sequence returns the same status.
386 // In the next tick, it will try to run the next child or start from the beginning again.
387 // If all children succeeds, only then does the stateful sequence succeed.
388 class MemSequence : public Composite
391 Status update() override
393 assert(hasChildren() && "Composite has no children");
395 while (it != children.end()) {
396 auto status = (*it)->tick();
398 if (status != Status::Success) {
405 it = children.begin();
406 return Status::Success;
410 class ParallelSequence : public Composite
413 ParallelSequence(bool successOnAll = true, bool failOnAll = true) : useSuccessFailPolicy(true), successOnAll(successOnAll), failOnAll(failOnAll) {}
414 ParallelSequence(int minSuccess, int minFail) : minSuccess(minSuccess), minFail(minFail) {}
416 Status update() override
418 assert(hasChildren() && "Composite has no children");
420 int minimumSuccess = minSuccess;
421 int minimumFail = minFail;
423 if (useSuccessFailPolicy) {
425 minimumSuccess = children.size();
432 minimumFail = children.size();
439 int total_success = 0;
442 for (auto &child : children) {
443 auto status = child->tick();
444 if (status == Status::Success) {
447 if (status == Status::Failure) {
452 if (total_success >= minimumSuccess) {
453 return Status::Success;
455 if (total_fail >= minimumFail) {
456 return Status::Failure;
459 return Status::Running;
463 bool useSuccessFailPolicy = false;
464 bool successOnAll = true;
465 bool failOnAll = true;
470 // The Succeeder decorator returns success, regardless of what happens to the child.
471 class Succeeder : public Decorator
474 Status update() override
477 return Status::Success;
481 // The Failer decorator returns failure, regardless of what happens to the child.
482 class Failer : public Decorator
485 Status update() override
488 return Status::Failure;
492 // The Inverter decorator inverts the child node's status, i.e. failure becomes success and success becomes failure.
493 // If the child runs, the Inverter returns the status that it is running too.
494 class Inverter : public Decorator
497 Status update() override
499 auto s = child->tick();
501 if (s == Status::Success) {
502 return Status::Failure;
504 else if (s == Status::Failure) {
505 return Status::Success;
512 // The Repeater decorator repeats infinitely or to a limit until the child returns success.
513 class Repeater : public Decorator
516 Repeater(int limit = 0) : limit(limit) {}
518 void initialize() override
523 Status update() override
527 if (limit > 0 && ++counter == limit) {
528 return Status::Success;
531 return Status::Running;
539 // The UntilSuccess decorator repeats until the child returns success and then returns success.
540 class UntilSuccess : public Decorator
543 Status update() override
546 auto status = child->tick();
548 if (status == Status::Success) {
549 return Status::Success;
555 // The UntilFailure decorator repeats until the child returns fail and then returns success.
556 class UntilFailure : public Decorator
559 Status update() override
562 auto status = child->tick();
564 if (status == Status::Failure) {
565 return Status::Success;
571 } // namespace BrainTree