feat: basic grammar functionality done
This commit is contained in:
parent
31c1c4cfbe
commit
e74620ab56
5 changed files with 62 additions and 39 deletions
|
|
@ -1,5 +1,6 @@
|
|||
#include "generator.h"
|
||||
#include "core/config/engine.h"
|
||||
#include "core/math/math_funcs.h"
|
||||
#include "core/object/class_db.h"
|
||||
#include "macros.h"
|
||||
|
||||
|
|
@ -8,29 +9,39 @@ void Generator::_bind_methods() {
|
|||
}
|
||||
|
||||
void Generator::initialise_state() {
|
||||
print_line("Filling state with unknown");
|
||||
for (int i{ 0 }; i < this->state->symbols.size(); ++i) {
|
||||
this->state->symbols.set(i, NonTerminals::Undefined);
|
||||
this->state->symbols.set(i, Terminals::Undefined);
|
||||
}
|
||||
print_line("Writing borders X");
|
||||
for (int i{ 0 }; i < this->state->size.x; ++i) {
|
||||
this->state->set_at({ i, 0 }, NonTerminals::Blocked);
|
||||
this->state->set_at({ i, this->state->size.y - 1 }, NonTerminals::Blocked);
|
||||
}
|
||||
print_line("Writing borders Y");
|
||||
for (int i{ 0 }; i < this->state->size.y; ++i) {
|
||||
this->state->set_at({ 0, i }, NonTerminals::Blocked);
|
||||
this->state->set_at({ this->state->size.x - 1, i }, NonTerminals::Blocked);
|
||||
}
|
||||
int y{ (int)Math::rand() % this->state->size.y - 4 };
|
||||
print_line("Writing path");
|
||||
int y{ (Math::abs((int)Math::rand()) % (this->state->size.y - 4)) + 2 };
|
||||
print_line("Path at y =", y);
|
||||
for (int i{ 1 }; i < this->state->size.x - 1; ++i) {
|
||||
this->state->set_at({ i, y }, NonTerminals::Path);
|
||||
this->state->set_at({ i, y }, Terminals::Path);
|
||||
}
|
||||
this->state->set_at({ 0, y }, NonTerminals::Start);
|
||||
this->state->set_at({ this->state->size.x - 1, y }, NonTerminals::Goal);
|
||||
print_line("Writing start & goal");
|
||||
this->state->set_at({ 0, y }, Terminals::Start);
|
||||
this->state->set_at({ this->state->size.x - 1, y }, Terminals::Goal);
|
||||
}
|
||||
|
||||
void Generator::ready() {
|
||||
initialise_state();
|
||||
print_line("STATE:");
|
||||
print_line(this->state->get_symbols_string());
|
||||
// TODO: repeat until terminal state
|
||||
this->rule->try_apply(this->state);
|
||||
print_line("STATE:");
|
||||
print_line(this->state->get_symbols_string());
|
||||
}
|
||||
|
||||
void Generator::_notification(int what) {
|
||||
|
|
|
|||
|
|
@ -18,29 +18,33 @@ bool Sentence::is_terminal() const {
|
|||
}
|
||||
|
||||
Symbol Sentence::get_at(Vector2i coord) const {
|
||||
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, "Sentence::get_at: invalid coordinate");
|
||||
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()));
|
||||
return this->symbols.get(idx);
|
||||
}
|
||||
|
||||
void Sentence::set_at(Vector2i coord, Symbol symbol) {
|
||||
ERR_FAIL_COND_EDMSG(coord.x >= this->size.x, vformat("Sentence::get_at: invalid coordinate x:%d, size.x:%d", coord.x, this->size.x));
|
||||
ERR_FAIL_COND_EDMSG(coord.y >= this->size.y, 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_EDMSG(idx < this->symbols.size(), "Sentence::set_at: invalid coordinate");
|
||||
ERR_FAIL_COND_EDMSG(idx >= this->symbols.size(), vformat("Sentence::set_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()));
|
||||
this->symbols.set(idx, symbol);
|
||||
}
|
||||
|
||||
bool Sentence::check_match_at(Vector2i at, Ref<Sentence> pattern) {
|
||||
Vector2i const pattern_size{ pattern->get_size() };
|
||||
if (at.x + pattern_size.x > this->size.x || at.y + pattern_size.y > this->size.y) {
|
||||
if (at.x + pattern_size.x >= this->size.x || at.y + pattern_size.y >= this->size.y) {
|
||||
return false; // can't match, out of bounds
|
||||
}
|
||||
for (Vector2i itr{ 0, 0 }; itr.y < pattern_size.x; ++itr.y) {
|
||||
for (; itr.x + at.x < pattern_size.x; ++itr.x) {
|
||||
for (Vector2i itr{ 0, 0 }; itr.y < pattern_size.y; ++itr.y) {
|
||||
for (; itr.x < pattern_size.x; ++itr.x) {
|
||||
if (get_at(at + itr) != pattern->get_at(itr)) {
|
||||
return false; // difference found
|
||||
}
|
||||
}
|
||||
itr.x = at.x;
|
||||
itr.x = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -58,8 +62,8 @@ void Sentence::set_symbols_string(String value) {
|
|||
int size{ this->size.x * this->size.y };
|
||||
int writer{ 0 };
|
||||
for (int reader{ 0 }; writer < size; ++reader) {
|
||||
char32_t c{ reader < value.length() ? value[reader] : (char32_t)'B' };
|
||||
if (c != '\n') {
|
||||
char32_t c{ reader < value.length() ? value[reader] : U'B' };
|
||||
if (c != U'\n') {
|
||||
this->symbols.set(writer, c);
|
||||
++writer;
|
||||
}
|
||||
|
|
@ -70,9 +74,9 @@ String Sentence::get_symbols_string() const {
|
|||
String value{};
|
||||
for (int i{ 0 }; i < this->symbols.size(); ++i) {
|
||||
if (i != 0 && i % this->size.x == 0) {
|
||||
value += L'\n';
|
||||
value += U'\n';
|
||||
}
|
||||
value += this->symbols.get(i);
|
||||
value += String::chr(this->symbols.get(i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
|
@ -115,9 +119,6 @@ void ReplaceRule::_bind_methods() {
|
|||
void ReplaceRule::try_apply(Ref<Sentence> sentence) {
|
||||
ERR_FAIL_COND_EDMSG(this->results.size() == 0, "ReplaceRule::try_apply failed, no results in list");
|
||||
Vector2i max{ sentence->get_size() - this->pattern->get_size() };
|
||||
if (max.x < 0 || max.y < 0) {
|
||||
return; // cannot continue, no area in sentence big enough
|
||||
}
|
||||
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)) {
|
||||
|
|
@ -134,6 +135,9 @@ void ReplaceRule::set_results_dict(Dictionary dict) {
|
|||
Ref<Sentence> key{ var.key };
|
||||
if (key.is_valid() && var.value.is_num()) {
|
||||
float value{ var.value };
|
||||
if (key->size != this->pattern->size) {
|
||||
key->set_size(this->pattern->size);
|
||||
}
|
||||
this->results.push_back({ key, value });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,19 @@ typedef char32_t Symbol;
|
|||
|
||||
namespace NonTerminals {
|
||||
enum : Symbol {
|
||||
Start = L'S',
|
||||
Goal = L'G',
|
||||
Undefined = L'U',
|
||||
Path = L'P',
|
||||
Blocked = L'B',
|
||||
Invalid = L'!',
|
||||
Blocked = U'B',
|
||||
Invalid = U'!',
|
||||
};
|
||||
};
|
||||
|
||||
namespace Terminals {
|
||||
enum : Symbol {
|
||||
Invalid = L'!',
|
||||
Wall = L'w',
|
||||
Path = L'p'
|
||||
Invalid = U'!',
|
||||
Start = U's',
|
||||
Goal = U'g',
|
||||
Undefined = U'u',
|
||||
Wall = U'w',
|
||||
Path = U'p'
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true
|
|||
[application]
|
||||
|
||||
config/name="dungeon"
|
||||
run/main_scene="uid://dnm5d16scmirb"
|
||||
run/main_scene="uid://cak2tf2adjv8j"
|
||||
config/features=PackedStringArray("4.7", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,21 +3,27 @@
|
|||
[sub_resource type="Sentence" id="Sentence_bb2w7"]
|
||||
size = Vector2i(10, 10)
|
||||
symbols_string = "BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BuuuuuuuuB
|
||||
BuuuuuuuuB
|
||||
BuuuuuuuuB
|
||||
BuuuuuuuuB
|
||||
BuuuuuuuuB
|
||||
BuuuuuuuuB
|
||||
BuuuuuuuuB
|
||||
BuuuuuuuuB
|
||||
BBBBBBBBBB"
|
||||
|
||||
[sub_resource type="Sentence" id="Sentence_wail4"]
|
||||
size = Vector2i(3, 3)
|
||||
symbols_string = "BBB
|
||||
BBB
|
||||
BBB"
|
||||
symbols_string = "uuu
|
||||
ppp
|
||||
uuu"
|
||||
|
||||
[sub_resource type="Sentence" id="Sentence_srduu"]
|
||||
size = Vector2i(3, 3)
|
||||
symbols_string = "uuu
|
||||
pxp
|
||||
uuu"
|
||||
|
||||
[node name="Dungeon" type="Node3D" unique_id=719313039]
|
||||
|
||||
|
|
@ -26,3 +32,6 @@ state = SubResource("Sentence_bb2w7")
|
|||
|
||||
[node name="ReplaceRule" type="ReplaceRule" parent="Generator" unique_id=1787373751]
|
||||
pattern = SubResource("Sentence_wail4")
|
||||
results_dict = {
|
||||
SubResource("Sentence_srduu"): 1.0
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue