chore: sentences can be transposed & flipped

This commit is contained in:
Sara Gerretsen 2026-03-31 17:39:16 +02:00
parent 44e75c8800
commit bf1e2d8f6f
3 changed files with 148 additions and 66 deletions

View file

@ -18,10 +18,21 @@ bool Sentence::is_terminal() const {
}
Symbol Sentence::get_at(Vector2i coord) const {
if (this->read_transposed) {
int x{ coord.x };
coord.x = coord.y;
coord.y = x;
}
if (this->read_flip_h) {
coord.x = this->size.x - (coord.x + 1);
}
if (this->read_flip_v) {
coord.y = this->size.y - (coord.y + 1);
}
ERR_FAIL_COND_V_EDMSG(coord.x >= this->size.x, NonTerminals::Invalid, vformat("Sentence::get_at: invalid coordinate x:%d, size.x:%d", coord.x, this->size.x));
ERR_FAIL_COND_V_EDMSG(coord.y >= this->size.y, NonTerminals::Invalid, vformat("Sentence::get_at: invalid coordinate y:%d size.y:%d", coord.y, this->size.y));
int idx{ coord.x + (coord.y * this->size.x) };
ERR_FAIL_COND_V_EDMSG(idx >= this->symbols.size(), NonTerminals::Invalid, vformat("Sentence::get_at: invalid coordinate x:%d y:%d idx:%d size:%d,%d len:%d", coord.x, coord.y, idx, this->size.x, this->size.y, this->symbols.size()));
ERR_FAIL_COND_V_EDMSG(idx >= this->symbols.size(), NonTerminals::Invalid, vformat("Sentence::get_at: invalid coordinate x:%d y:%d idx:%d size:%d,%d len:%d h:%s v:%s t:%s", coord.x, coord.y, idx, this->size.x, this->size.y, this->symbols.size(), this->read_flip_h, this->read_flip_v, this->read_transposed));
return this->symbols.get(idx);
}
@ -95,7 +106,7 @@ void Sentence::set_size(Vector2i value) {
}
Vector2i Sentence::get_size() const {
return this->size;
return this->read_transposed ? Vector2i{ this->size.y, this->size.x } : this->size;
}
void CompositeRule::_bind_methods() {
@ -147,13 +158,13 @@ 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()));
}
bool ReplaceRule::try_apply(Ref<Sentence> sentence) {
bool ReplaceRule::try_match(Ref<Sentence> sentence, Vector2i &out) {
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() };
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)) {
sentence->write_subsentence(pos, this->results[Math::rand() % this->results.size()].first); // TODO pick based on weighed random
out = pos;
return true;
}
}
@ -162,6 +173,69 @@ bool ReplaceRule::try_apply(Ref<Sentence> sentence) {
return false;
}
void ReplaceRule::write_result(Ref<Sentence> to, Vector2i at) {
Ref<Sentence> result{ this->results[Math::rand() % this->results.size()].first };
result->read_flip_h = this->pattern->read_flip_h;
result->read_flip_v = this->pattern->read_flip_v;
result->read_transposed = this->pattern->read_transposed;
to->write_subsentence(at, result);
result->read_flip_h = false;
result->read_flip_v = false;
result->read_transposed = false;
}
bool ReplaceRule::try_apply_all(Ref<Sentence> sentence) {
Vector2i at{};
if (try_match(sentence, at)) {
write_result(sentence, at);
return true;
}
this->pattern->read_flip_h = true;
if (try_match(sentence, at)) {
write_result(sentence, at);
return true;
}
this->pattern->read_flip_v = true;
if (try_match(sentence, at)) {
write_result(sentence, at);
return true;
}
this->pattern->read_transposed = true;
if (try_match(sentence, at)) {
write_result(sentence, at);
return true;
}
this->pattern->read_flip_h = false;
if (try_match(sentence, at)) {
write_result(sentence, at);
return true;
}
this->pattern->read_flip_v = false;
if (try_match(sentence, at)) {
write_result(sentence, at);
return true;
}
this->pattern->read_flip_h = true;
if (try_match(sentence, at)) {
write_result(sentence, at);
return true;
}
this->pattern->read_transposed = false;
if (try_match(sentence, at)) {
write_result(sentence, at);
return true;
}
return false;
}
bool ReplaceRule::try_apply(Ref<Sentence> sentence) {
bool success{ try_apply_all(sentence) };
this->pattern->read_flip_h = false;
this->pattern->read_flip_v = false;
this->pattern->read_transposed = false;
return success;
}
void ReplaceRule::set_results_dict(Dictionary dict) {
this->results.clear();
for (KeyValue<Variant, Variant> var : dict) {

View file

@ -40,6 +40,9 @@ public:
public:
Vector<Symbol> symbols{};
Vector2i size{ 0, 0 };
bool read_transposed{ false };
bool read_flip_h{ false };
bool read_flip_v{ false };
public:
void set_symbols_string(String value);
@ -86,9 +89,12 @@ public:
class ReplaceRule : public Rule {
GDCLASS(ReplaceRule, Rule);
static void _bind_methods();
bool try_match(Ref<Sentence> graph, Vector2i &out);
void write_result(Ref<Sentence> to, Vector2i at);
bool try_apply_all(Ref<Sentence> sentence);
public:
bool try_apply(Ref<Sentence> graph) override;
bool try_apply(Ref<Sentence> sentence) override;
private:
Ref<Sentence> pattern{};

View file

@ -43,7 +43,7 @@ uuuuuuuuuuuuuuuuuuuu"
size = Vector2i(5, 3)
symbols_string = "uuuuu
uuuuu
#####"
*###*"
[sub_resource type="Sentence" id="Sentence_yc5ro"]
size = Vector2i(5, 3)
@ -51,18 +51,6 @@ symbols_string = "uuuuu
uxpxu
*pup*"
[sub_resource type="Sentence" id="Sentence_7f72c"]
size = Vector2i(5, 3)
symbols_string = "#p#p#
uuuuu
uuuuu"
[sub_resource type="Sentence" id="Sentence_pbld3"]
size = Vector2i(5, 3)
symbols_string = "*pup*
upxpu
uuuuu"
[sub_resource type="Sentence" id="Sentence_wyxho"]
size = Vector2i(5, 5)
symbols_string = "uuuuu
@ -74,50 +62,66 @@ uuuuu"
[sub_resource type="Sentence" id="Sentence_q0ye3"]
size = Vector2i(5, 5)
symbols_string = "uuuuu
upxpu
uppxu
#pup#
upxpu
uxppu
uuuuu"
[sub_resource type="Sentence" id="Sentence_7f72c"]
size = Vector2i(5, 3)
symbols_string = "u#u#u
u#u#u
u#u#u"
[sub_resource type="Sentence" id="Sentence_w0mg0"]
size = Vector2i(4, 5)
symbols_string = "uuuu
##u*
u##*
##u*
uuuu"
size = Vector2i(5, 3)
symbols_string = "u#p#u
uuu#u
u#p#u"
[sub_resource type="Sentence" id="Sentence_pbld3"]
size = Vector2i(5, 5)
symbols_string = "u#u#u
*###*
uu#uu
*###*
u#u#u"
[sub_resource type="Sentence" id="Sentence_06kf8"]
size = Vector2i(4, 5)
symbols_string = "uuuu
##pp
uuu#
##pp
uuuu"
[sub_resource type="Sentence" id="Sentence_wail4"]
size = Vector2i(5, 3)
symbols_string = "uuuuu
uuuuu
#####"
[sub_resource type="Sentence" id="Sentence_srduu"]
size = Vector2i(5, 3)
symbols_string = "upxpu
size = Vector2i(5, 5)
symbols_string = "u#u#u
*#u#*
upupu
##u##"
*#u#*
u#u#u"
[sub_resource type="Sentence" id="Sentence_c7dwr"]
size = Vector2i(5, 3)
symbols_string = "uuu#*
uuu#*
uuu#*"
size = Vector2i(5, 5)
symbols_string = "u#u#u
*###*
upuuu
*###*
u#u#u"
[sub_resource type="Sentence" id="Sentence_ohg4i"]
size = Vector2i(5, 3)
symbols_string = "uxp#*
upuu*
uxp#*"
size = Vector2i(6, 4)
symbols_string = "uuuuuu
u###uu
u#u#uu
*#u#u*"
[sub_resource type="Sentence" id="Sentence_b4io3"]
size = Vector2i(6, 4)
symbols_string = "uuuuuu
u###pu
u#uupu
*#upp*"
[sub_resource type="Sentence" id="Sentence_eijdf"]
size = Vector2i(4, 3)
symbols_string = "####
uu#u
###*"
[node name="Dungeon" type="Node3D" unique_id=719313039]
@ -147,32 +151,30 @@ results_dict = {
SubResource("Sentence_yc5ro"): 1.0
}
[node name="ZagDown" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/InitialLayout" unique_id=1665850421]
pattern = SubResource("Sentence_7f72c")
results_dict = {
SubResource("Sentence_pbld3"): 1.0
}
[node name="Split" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/InitialLayout" unique_id=222066055]
pattern = SubResource("Sentence_wyxho")
results_dict = {
SubResource("Sentence_q0ye3"): 1.0
}
[node name="StretchLoop" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/InitialLayout" unique_id=995556959]
pattern = SubResource("Sentence_w0mg0")
[node name="Bridge" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/InitialLayout" unique_id=233403765]
pattern = SubResource("Sentence_7f72c")
results_dict = {
SubResource("Sentence_06kf8"): 1.0
SubResource("Sentence_w0mg0"): 1.0
}
[node name="ExtendLoop" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/InitialLayout" unique_id=1207681043]
pattern = SubResource("Sentence_wail4")
[node name="ConnectLoops" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/InitialLayout" unique_id=874341993]
pattern = SubResource("Sentence_pbld3")
results_dict = {
SubResource("Sentence_srduu"): 1.0
SubResource("Sentence_06kf8"): 1.0,
SubResource("Sentence_c7dwr"): 1.0
}
[node name="SplitVertical" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/InitialLayout" unique_id=1220297709]
pattern = SubResource("Sentence_c7dwr")
[node name="WidenLoops" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/InitialLayout" unique_id=2024540398]
pattern = SubResource("Sentence_ohg4i")
results_dict = {
SubResource("Sentence_ohg4i"): 1.0
SubResource("Sentence_b4io3"): 0.0
}
[node name="CloseGaps" type="ReplaceRule" parent="Generator/RepeatRuleUntilFailure/InitialLayout" unique_id=370907114]
pattern = SubResource("Sentence_eijdf")