feat: added RepeatRuleUntilFailure

This commit is contained in:
Sara Gerretsen 2026-03-30 20:02:49 +02:00
parent e74620ab56
commit fca1b11f1c
4 changed files with 71 additions and 19 deletions

View file

@ -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> sentence) {
bool CompositeRule::try_apply(Ref<Sentence> 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> 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> sentence) {
ERR_FAIL_COND_EDMSG(this->results.size() == 0, "ReplaceRule::try_apply failed, no results in list");
bool ReplaceRule::try_apply(Ref<Sentence> 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<Sentence> data, Vector2i coord, Symbol tile) {
}
}
void ResizeRule::try_apply(Ref<Sentence> sentence) {
bool ResizeRule::try_apply(Ref<Sentence> sentence) {
Vector2i size_before{ sentence->size };
Vector<Symbol> before{ sentence->symbols };
sentence->set_size(size_before * this->factor);
@ -174,4 +185,5 @@ void ResizeRule::try_apply(Ref<Sentence> sentence) {
}
at.x = 0;
}
return true;
}

View file

@ -53,7 +53,7 @@ class Rule : public Node {
static void _bind_methods() {}
public:
virtual void try_apply(Ref<Sentence> graph) {}
virtual bool try_apply(Ref<Sentence> sentence) { return false; }
};
class CompositeRule : public Rule {
@ -65,18 +65,26 @@ protected:
void _notification(int what);
public:
void try_apply(Ref<Sentence> graph) override;
bool try_apply(Ref<Sentence> sentence) override;
protected:
Vector<Rule *> rules{};
};
class RepeatRuleUntilFailure : public CompositeRule {
GDCLASS(RepeatRuleUntilFailure, CompositeRule);
static void _bind_methods() {}
public:
bool try_apply(Ref<Sentence> sentence) override;
};
class ReplaceRule : public Rule {
GDCLASS(ReplaceRule, Rule);
static void _bind_methods();
public:
void try_apply(Ref<Sentence> graph) override;
bool try_apply(Ref<Sentence> graph) override;
private:
Ref<Sentence> pattern{};
@ -96,7 +104,7 @@ class ResizeRule : public CompositeRule {
void fill_area(Ref<Sentence> data, Vector2i coord, Symbol tile);
public:
void try_apply(Ref<Sentence> sentence) override;
bool try_apply(Ref<Sentence> sentence) override;
private:
int factor{ 10 };

View file

@ -9,6 +9,7 @@ void initialize_generative_grammar_module(ModuleInitializationLevel p_level) {
}
ClassDB::register_abstract_class<Rule>();
ClassDB::register_class<Sentence>();
ClassDB::register_class<RepeatRuleUntilFailure>();
ClassDB::register_class<CompositeRule>();
ClassDB::register_class<ReplaceRule>();
ClassDB::register_class<Generator>();

View file

@ -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
}