#include "dbc.hpp" #include "ai.hpp" namespace ai { using namespace nlohmann; using namespace dbc; bool is_subset(State& source, State& target) { State result = source & target; return result == target; } void Action::needs(int name, bool val) { if(val) { $positive_preconds[name] = true; $negative_preconds[name] = false; } else { $negative_preconds[name] = true; $positive_preconds[name] = false; } } void Action::effect(int name, bool val) { if(val) { $positive_effects[name] = true; $negative_effects[name] = false; } else { $negative_effects[name] = true; $positive_effects[name] = false; } } bool Action::can_effect(State& state) { return ((state & $positive_preconds) == $positive_preconds) && ((state & $negative_preconds) == ALL_ZERO); } State Action::apply_effect(State& state) { return (state | $positive_effects) & ~$negative_effects; } int distance_to_goal(State& from, State& to) { auto result = from ^ to; return result.count(); } Script reconstruct_path(std::unordered_map& came_from, Action& current) { Script total_path{current}; int count = 0; while(came_from.contains(current) && count++ < 10) { current = came_from.at(current); if(current != FINAL_ACTION) { total_path.push_front(current); } } return total_path; } inline int h(State& start, State& goal) { return distance_to_goal(start, goal); } inline int d(State& start, State& goal) { return distance_to_goal(start, goal); } ActionState find_lowest(std::unordered_map& open_set) { check(!open_set.empty(), "open set can't be empty in find_lowest"); const ActionState *result = nullptr; int lowest_score = SCORE_MAX; for(auto& kv : open_set) { if(kv.second < lowest_score) { lowest_score = kv.second; result = &kv.first; } } return *result; } std::optional