💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
5.0 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_AI_BT_NODE_HPP
  20. #define ANTKEEPER_AI_BT_NODE_HPP
  21. #include "ai/bt/status.hpp"
  22. namespace ai {
  23. namespace bt {
  24. /**
  25. * Abstract base class for behavior tree nodes.
  26. *
  27. * @tparam T Data type on which nodes operate.
  28. */
  29. template <class T>
  30. struct node
  31. {
  32. /// Data type on which nodes operate.
  33. typedef T context_type;
  34. /**
  35. * Executes a node's function and returns its status.
  36. *
  37. * @param context Context data on which the node will operate.
  38. */
  39. virtual status execute(context_type& context) const = 0;
  40. };
  41. /// Behavior tree node with no children.
  42. template <class T>
  43. using leaf_node = node<T>;
  44. /// A node with exactly one child.
  45. template <class T>
  46. struct decorator_node: node<T>
  47. {
  48. node* child;
  49. };
  50. /// A node that can have one or more children.
  51. template <class T>
  52. struct composite_node: node<T>
  53. {
  54. std::list<node*> children;
  55. };
  56. /// Executes a function on a context and returns the status.
  57. template <class T>
  58. struct action: leaf_node<T>
  59. {
  60. virtual status execute(context_type& context) const final;
  61. typedef std::function<status(context_type&)> function_type;
  62. function_type function;
  63. };
  64. /// Evaluates a boolean condition (predicate) and returns either `status::success` or `status::failure`.
  65. template <class T>
  66. struct condition: leaf_node<T>
  67. {
  68. virtual status execute(context_type& context) const final;
  69. typedef std::function<status(const context_type&)> predicate_type;
  70. predicate_type predicate;
  71. };
  72. /// Executes a child node and returns its inverted status. If the child returns `status::success`, then `status::failure` will be returned. Otherwise if the child returns `status::failure`, then `status::success` will be returned.
  73. template <class T>
  74. struct inverter: decorator_node<T>
  75. {
  76. virtual status execute(context_type& context) const final;
  77. };
  78. /// Attempts to execute a child node `n` times or until the child fails.
  79. template <class T>
  80. struct repeater: decorator_node<T>
  81. {
  82. virtual status execute(context_type& context) const final;
  83. int n;
  84. };
  85. /// Executes a child node and returns `status::success` regardless of the child node status.
  86. template <class T>
  87. struct succeeder: decorator_node<T>
  88. {
  89. virtual status execute(context_type& context) const final;
  90. };
  91. /// Attempts to execute each child node sequentially until one fails. If all children are executed successfully, `status::success` will be returned. Otherwise if any children fail, `status::failure` will be returned.
  92. template <class T>
  93. struct sequence: composite_node<T>
  94. {
  95. virtual status execute(context_type& context) const final;
  96. };
  97. /// Attempts to execute each child node sequentially until one succeeds. If a child succeeds, `status::success` will be returned. Otherwise if all children fail, `status::failure` will be returned.
  98. template <class T>
  99. struct selector: composite_node<T>
  100. {
  101. virtual status execute(context_type& context) const final;
  102. };
  103. template <class T>
  104. status action<T>::execute(context_type& context) const
  105. {
  106. return function(context);
  107. }
  108. template <class T>
  109. status condition<T>::execute(context_type& context) const
  110. {
  111. return (predicate(context)) ? status::success : status::failure;
  112. }
  113. template <class T>
  114. status inverter<T>::execute(context_type& context) const
  115. {
  116. status child_status = child->execute(context);
  117. return (child_status == status::success) ? status::failure : (child_status == status::failure) ? status::success : child_status;
  118. }
  119. template <class T>
  120. status repeater<T>::execute(context_type& context) const
  121. {
  122. status child_status;
  123. for (int i = 0; i < n; ++i)
  124. {
  125. child_status = child->execute(context);
  126. if (child_status == status::failure)
  127. break;
  128. }
  129. return child_status;
  130. }
  131. template <class T>
  132. status succeeder<T>::execute(context_type& context) const
  133. {
  134. child->execute(context);
  135. return status::success;
  136. }
  137. template <class T>
  138. status sequence<T>::execute(context_type& context) const
  139. {
  140. for (const node* child: children)
  141. {
  142. status child_status = child->execute(context);
  143. if (child_status != status::success)
  144. return child_status;
  145. }
  146. return status::success;
  147. }
  148. template <class T>
  149. status selector<T>::execute(context_type& context) const
  150. {
  151. for (const node* child: children)
  152. {
  153. status child_status = child->execute(context);
  154. if (child_status != status::failure)
  155. return child_status;
  156. }
  157. return status::failure;
  158. }
  159. } // namespace bt
  160. } // namespace ai
  161. #endif // ANTKEEPER_AI_BT_NODE_HPP