#include #include "goal.hpp" #include "level.hpp" namespace Nimbin { namespace Goal { bool contains(const DynArray& v, const std::string& s) { return std::find(v.begin(), v.end(), s) != v.end(); } bool contains(const DynArray& v, PultAction a) { return std::find(v.begin(), v.end(), a) != v.end(); } bool is_Satisfied(const Type& g, const Context& ctx) { return std::visit([&ctx](const auto& concrete) -> bool { using T = std::decay_t; if constexpr (std::is_same_v) { if (concrete.tag.empty()) return !ctx.active_plate_tags.empty(); return contains(ctx.active_plate_tags, concrete.tag); } else if constexpr (std::is_same_v) { return contains(ctx.buttons_pressed_this_step, concrete.action); } else if constexpr (std::is_same_v) { return contains(ctx.picked_up_this_step, concrete.text); } else if constexpr (std::is_same_v) { return ctx.dropped_this_step; } else if constexpr (std::is_same_v) { return ctx.shot_this_step; } else if constexpr (std::is_same_v) { if (!ctx.compile_ok_this_step) return false; if (concrete.pattern.empty()) return true; return Level::Check::contains_Pattern(ctx.editor_normalized, concrete.pattern); } else if constexpr (std::is_same_v) { for (const Type& sub : concrete.options) if (Goal::is_Satisfied(sub, ctx)) return true; return false; } else if constexpr (std::is_same_v) { for (const Type& sub : concrete.options) if (!Goal::is_Satisfied(sub, ctx)) return false; return !concrete.options.empty(); } else if constexpr (std::is_same_v) { if (concrete.text.empty()) return !ctx.ai_words_defeated_this_step.empty(); return contains(ctx.ai_words_defeated_this_step, concrete.text); } else { static_assert(sizeof(T) == 0, "Unhandled Type alternative"); } }, g); } } // namespace Type } // namespace Nimbin