(C++)  1.0.0
A multi-platform, modular, universal engine for embedding advanced AI in games.
Planner.hh
1 #ifndef GRAIL_PLANNER_H
2 #define GRAIL_PLANNER_H
3 
4 #include "WorldState/WorldState.hh"
5 #include "Action/Action.hh"
6 #include "../../GrailData/GrailDebugInfo/PlannerSnapshots.h"
7 
8 #include <functional>
9 #include <memory>
10 #include <vector>
11 #include <queue>
12 #include <map>
13 
14 namespace grail
15 {
16  namespace planning
17  {
18  using ConditionFunction = std::function<bool(const WorldState&)>;
19  using PlannerHeuristic = std::function<double(const WorldState&, const std::vector<ConditionFunction>&)>;
20 
22  class Planner
23  {
24  public:
25  struct Config
26  {
27  Config() noexcept {}
28  PlannerHeuristic heuristic = nullptr;
29  std::size_t iterationLimit = 500;
30  int maxPlanLength = -1;
31  double maxPlanCost = -1;
32  std::size_t initialNodeCapacity = 128;
33  };
34 
35  struct AbstractPlan
36  {
37  std::vector<Action> actions{};
38  float totalCost = 0.0f;
39  };
40 
41  Planner(MemoryPool& memory);
42  Planner(MemoryPool& memory, const WorldState& initialState, const Config& config = Config{});
43 
44  void SetIterationLimit(std::size_t iterationLimit);
45  void SetMaxPlanLength(int maxDepth);
46  void SetMaxPlanCost(double maxCost);
47  void SetHeuristic(PlannerHeuristic heuristic);
48  void ResetConfig(const Config& config);
49 
52  void PushCondition(ConditionFunction condition);
53  AbstractPlan GetPartialPlan() const;
54  PlannerIterationSnapshot GetPlanSnapshot(std::size_t goalNodeIndex, std::size_t iteration) const;
55  void Iterate(std::size_t iterationCount) noexcept;
56  void IterateWithSnapshot(std::size_t iterationCount, PlannerReasonerSnapshot& snapshot, std::size_t minDebugSnapshotIteration = 0, std::size_t maxDebugSnapshotIteration = std::numeric_limits<std::size_t>::max()) noexcept;
57  void SetPlanFoundCallback(const std::function<void(const AbstractPlan&)> callbackFunction);
58  void SetPlanningFailedCallback(const std::function<void()> callbackFunction);
59  void Reset(const WorldState& initialState);
60  bool IsComputing() const;
61 
62  private:
63  //helper structs start
64  struct Edge;
65  struct Node
66  {
67  WorldState state;
68  int depth = 0;
69  double score = 0;
70  double distanceFromGoal = std::numeric_limits<double>::max();
71  std::shared_ptr<Edge> pathEdge = nullptr;
72 
73  Node(Node&& other);
74  Node(const WorldState& state);
75  Node(WorldState&& state);
76  Node& operator=(Node&& other);
77  };
78 
79  struct Edge
80  {
81  Edge(std::size_t sourceIndex, std::size_t destinationIndex, Action&& action);
82 
83  std::size_t sourceIndex = 0;
84  std::size_t destinationIndex = 0;
85  Action action;
86  };
87 
88  struct EdgePriority
89  {
90  EdgePriority(const std::shared_ptr<Edge>& edge, double dijkstraScore, double aStarScore);
91 
92  std::shared_ptr<Edge> edge;
93  double dijkstraScore;
94  double aStarScore;
95  };
96 
97  class EdgePriorityComparer
98  {
99  public:
100  bool operator() (const EdgePriority& one, const EdgePriority& other)
101  {
102  return one.aStarScore > other.aStarScore;
103  }
104  };
105  //helper structs end
106 
107  void AddNode(Node&& node);
108  bool IsGoalAchieved(const WorldState& state) const;
109 
110  WorldState initialState;
111  Config plannerConfig = {};
112 
113  std::vector<ConditionFunction> goalConditions = {};
114  std::function<void(const AbstractPlan&)> onPlanFound = nullptr;
115  std::function<void()> onPlanningFailed = nullptr;
116 
117  //cached data for iterative approach
118  std::size_t nextNodeIndex = 0;
119  std::size_t nodeClosestToGoalIndex = std::numeric_limits<std::size_t>::max();
120  std::size_t lastChosenNodeIndex = std::numeric_limits<std::size_t>::max();
121  int maxNodeDepth = 0;
122  std::priority_queue<EdgePriority, std::vector<EdgePriority>, EdgePriorityComparer> edges{};
123  std::vector<Node> generatedNodes{};
124  std::vector<std::size_t> closedNodeIndices{};
125  std::size_t currentIteration = 0;
126  bool isPlanningFinished = true;
127  MemoryPool& memory;
128  };
129  }
130 }
131 #endif //GRAIL_PLANNER_H
The MemoryPool class - preallocated memory container for optimization issues.
Definition: MemoryPool.hh:74
Definition: Action.hh:11
The main class responsible for finding paths in plan space.
Definition: Planner.hh:23
void PushCondition(ConditionFunction condition)
Definition: Planner.cpp:60
A class representing planner world state.
Definition: WorldState.hh:15
Definition: PlannerSnapshots.h:44
Definition: PlannerSnapshots.h:64
Definition: Planner.hh:26