From fca1b11f1c7a26dde6486fefb5fd72e775de29b5 Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 30 Mar 2026 20:02:49 +0200 Subject: [PATCH] feat: added RepeatRuleUntilFailure --- modules/generative_grammar/grammar.cpp | 24 ++++++--- modules/generative_grammar/grammar.h | 16 ++++-- modules/generative_grammar/register_types.cpp | 1 + project/scenes/levels/dungeon.tscn | 49 +++++++++++++++---- 4 files changed, 71 insertions(+), 19 deletions(-) diff --git a/modules/generative_grammar/grammar.cpp b/modules/generative_grammar/grammar.cpp index ca967bd96e..a93c2b9727 100644 --- a/modules/generative_grammar/grammar.cpp +++ b/modules/generative_grammar/grammar.cpp @@ -76,7 +76,7 @@ String Sentence::get_symbols_string() const { if (i != 0 && i % this->size.x == 0) { value += U'\n'; } - value += String::chr(this->symbols.get(i)); + value += this->symbols.get(i); } return value; } @@ -105,10 +105,18 @@ void CompositeRule::_notification(int what) { } } -void CompositeRule::try_apply(Ref sentence) { +bool CompositeRule::try_apply(Ref sentence) { + bool any_success{ false }; for (Rule *rule : this->rules) { - rule->try_apply(sentence); + any_success |= rule->try_apply(sentence); } + return any_success; +} + +bool RepeatRuleUntilFailure::try_apply(Ref sentence) { + while (!this->rules.get(0)->try_apply(sentence)) { + } + return true; } void ReplaceRule::_bind_methods() { @@ -116,17 +124,20 @@ void ReplaceRule::_bind_methods() { BIND_HPROPERTY(Variant::DICTIONARY, results_dict, PROPERTY_HINT_DICTIONARY_TYPE, vformat("%s/%s:%s;float", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, Sentence::get_class_static())); } -void ReplaceRule::try_apply(Ref sentence) { - ERR_FAIL_COND_EDMSG(this->results.size() == 0, "ReplaceRule::try_apply failed, no results in list"); +bool ReplaceRule::try_apply(Ref sentence) { + ERR_FAIL_COND_V_EDMSG(this->results.size() == 0, false, "ReplaceRule::try_apply failed, no results in list"); Vector2i max{ sentence->get_size() - this->pattern->get_size() }; + bool any_success{ false }; for (Vector2i pos{ 0, 0 }; pos.y < max.y; ++pos.y) { for (; pos.x < max.x; ++pos.x) { if (sentence->check_match_at(pos, this->pattern)) { + any_success = true; sentence->write_subsentence(pos, this->results[Math::rand() % this->results.size()].first); // TODO pick based on weighed random } } pos.x = 0; } + return any_success; } void ReplaceRule::set_results_dict(Dictionary dict) { @@ -164,7 +175,7 @@ void ResizeRule::fill_area(Ref data, Vector2i coord, Symbol tile) { } } -void ResizeRule::try_apply(Ref sentence) { +bool ResizeRule::try_apply(Ref sentence) { Vector2i size_before{ sentence->size }; Vector before{ sentence->symbols }; sentence->set_size(size_before * this->factor); @@ -174,4 +185,5 @@ void ResizeRule::try_apply(Ref sentence) { } at.x = 0; } + return true; } diff --git a/modules/generative_grammar/grammar.h b/modules/generative_grammar/grammar.h index 0f63abafda..a2c413b1bc 100644 --- a/modules/generative_grammar/grammar.h +++ b/modules/generative_grammar/grammar.h @@ -53,7 +53,7 @@ class Rule : public Node { static void _bind_methods() {} public: - virtual void try_apply(Ref graph) {} + virtual bool try_apply(Ref sentence) { return false; } }; class CompositeRule : public Rule { @@ -65,18 +65,26 @@ protected: void _notification(int what); public: - void try_apply(Ref graph) override; + bool try_apply(Ref sentence) override; protected: Vector rules{}; }; +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(); public: - void try_apply(Ref graph) override; + bool try_apply(Ref graph) override; private: Ref pattern{}; @@ -96,7 +104,7 @@ class ResizeRule : public CompositeRule { void fill_area(Ref data, Vector2i coord, Symbol tile); public: - void try_apply(Ref sentence) override; + bool try_apply(Ref sentence) override; private: int factor{ 10 }; diff --git a/modules/generative_grammar/register_types.cpp b/modules/generative_grammar/register_types.cpp index 69f63c02a9..4dd0c906af 100644 --- a/modules/generative_grammar/register_types.cpp +++ b/modules/generative_grammar/register_types.cpp @@ -9,6 +9,7 @@ void initialize_generative_grammar_module(ModuleInitializationLevel p_level) { } ClassDB::register_abstract_class(); ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); diff --git a/project/scenes/levels/dungeon.tscn b/project/scenes/levels/dungeon.tscn index f12438f9ca..d7be2d220e 100644 --- a/project/scenes/levels/dungeon.tscn +++ b/project/scenes/levels/dungeon.tscn @@ -14,24 +14,55 @@ BuuuuuuuuB BBBBBBBBBB" [sub_resource type="Sentence" id="Sentence_wail4"] -size = Vector2i(3, 3) -symbols_string = "uuu -ppp -uuu" +size = Vector2i(3, 1) +symbols_string = "ppp" [sub_resource type="Sentence" id="Sentence_srduu"] -size = Vector2i(3, 3) -symbols_string = "uuu -pxp -uuu" +size = Vector2i(3, 1) +symbols_string = "pxp" + +[sub_resource type="Sentence" id="Sentence_s5a2w"] +size = Vector2i(5, 5) +symbols_string = "uuuuu +uuuuu +pxpxp +uuuuu +uuuuu" + +[sub_resource type="Sentence" id="Sentence_yc5ro"] +size = Vector2i(5, 5) +symbols_string = "uuuuu +uppxu +pxupp +uuuuu +uuuuu" + +[sub_resource type="Sentence" id="Sentence_7f72c"] +size = Vector2i(5, 5) +symbols_string = "uuuuu +uuuuu +pxupp +uppxu +uuuuu" [node name="Dungeon" type="Node3D" unique_id=719313039] [node name="Generator" type="Generator" parent="." unique_id=1532743122] state = SubResource("Sentence_bb2w7") -[node name="ReplaceRule" type="ReplaceRule" parent="Generator" unique_id=1787373751] +[node name="RepeatRuleUntilFailure" type="RepeatRuleUntilFailure" parent="Generator" unique_id=407316032] + +[node name="CompositeRule" type="CompositeRule" parent="Generator/RepeatRuleUntilFailure" unique_id=117678547] + +[node name="ReplaceRule" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/CompositeRule" unique_id=1787373751] pattern = SubResource("Sentence_wail4") results_dict = { SubResource("Sentence_srduu"): 1.0 } + +[node name="ReplaceRule2" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/CompositeRule" unique_id=1073931523] +pattern = SubResource("Sentence_s5a2w") +results_dict = { +SubResource("Sentence_yc5ro"): 1.0, +SubResource("Sentence_7f72c"): 1.0 +}