#pragma once #include "macros.h" #include "scene/main/node.h" typedef char32_t Symbol; namespace NonTerminals { enum : Symbol { Invalid = U'!', }; }; namespace Terminals { enum : Symbol { Invalid = U'!', Start = U's', Goal = U'g', Undefined = U'u', PointOfInterest = U'x', Wall = U'w', Path = U'p' }; }; class Sentence : public Resource { GDCLASS(Sentence, Resource); static void _bind_methods(); public: bool is_terminal() const; int difficulty_at(Vector2i coord) const; Symbol get_at(Vector2i coord) const; void set_at(Vector2i coord, Symbol symbol); bool check_match_at(Vector2i at, Ref pattern); void write_subsentence(Vector2i at, Ref sentence); static bool symbol_is_terminal(Symbol symbol) { return String::char_lowercase(symbol) == symbol; } public: Vector symbols{}; Vector2i size{ 0, 0 }; HashMap difficulty_map{}; int difficulty_map_scale{ 0 }; bool read_transposed{ false }; bool read_flip_h{ false }; bool read_flip_v{ false }; public: void set_symbols_string(String value); String get_symbols_string() const; void set_size(Vector2i width); Vector2i get_size() const; }; class Rule : public Node { GDCLASS(Rule, Node); static void _bind_methods() {} public: virtual bool try_apply(Ref sentence) { return false; } }; class CompositeRule : public Rule { GDCLASS(CompositeRule, Rule); static void _bind_methods(); void order_changed(); protected: void _notification(int what); public: bool try_apply(Ref sentence) override; protected: Vector rules{}; bool random_order{ false }; public: GET_SET_FNS(bool, random_order); }; class RepeatRuleUntilFailure : public CompositeRule { GDCLASS(RepeatRuleUntilFailure, CompositeRule); static void _bind_methods() {} public: bool try_apply(Ref sentence) override; }; class ReplaceRule : public Rule { GDCLASS(ReplaceRule, Rule); static void _bind_methods(); void write_result(Ref to, Vector2i at); bool try_apply_all(Ref sentence); public: bool try_apply(Ref sentence) override; private: Ref pattern{}; Vector, float>> results{}; bool deterministic{ false }; int match_min_difficulty{ -1 }; int match_max_difficulty{ -1 }; public: GET_SET_FNS(Ref, pattern); GET_SET_FNS(bool, deterministic); GET_SET_FNS(int, match_min_difficulty); GET_SET_FNS(int, match_max_difficulty); void set_results(Vector, float>> value) { this->results = value; } Vector, float>> get_results() { return this->results; } void set_results_dict(Dictionary value); Dictionary get_results_dict() const; }; class ResizeRule : public CompositeRule { GDCLASS(ResizeRule, Rule); static void _bind_methods(); void fill_area(Ref data, Vector2i coord, Symbol tile); public: bool try_apply(Ref sentence) override; private: int factor{ 10 }; public: GET_SET_FNS(int, factor); }; class TagDepthRule : public Rule { GDCLASS(TagDepthRule, Rule); static void _bind_methods() {} public: bool try_apply(Ref sentence) override; }; class PlaceEndRule : public Rule { GDCLASS(PlaceEndRule, Rule); static void _bind_methods() {} public: bool try_apply(Ref sentence) override; };