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{};