feat: continuing grammar
This commit is contained in:
parent
e4c41bbeda
commit
31c1c4cfbe
5 changed files with 80 additions and 19 deletions
|
|
@ -7,7 +7,30 @@ void Generator::_bind_methods() {
|
|||
BIND_HPROPERTY(Variant::OBJECT, state, PROPERTY_HINT_RESOURCE_TYPE, "Sentence");
|
||||
}
|
||||
|
||||
void Generator::initialise_state() {
|
||||
for (int i{ 0 }; i < this->state->symbols.size(); ++i) {
|
||||
this->state->symbols.set(i, NonTerminals::Undefined);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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 };
|
||||
for (int i{ 1 }; i < this->state->size.x - 1; ++i) {
|
||||
this->state->set_at({ i, y }, NonTerminals::Path);
|
||||
}
|
||||
this->state->set_at({ 0, y }, NonTerminals::Start);
|
||||
this->state->set_at({ this->state->size.x - 1, y }, NonTerminals::Goal);
|
||||
}
|
||||
|
||||
void Generator::ready() {
|
||||
initialise_state();
|
||||
// TODO: repeat until terminal state
|
||||
this->rule->try_apply(this->state);
|
||||
}
|
||||
|
||||
void Generator::_notification(int what) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
class Generator : public Node3D {
|
||||
GDCLASS(Generator, Node3D);
|
||||
static void _bind_methods();
|
||||
void initialise_state();
|
||||
void ready();
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
#include "macros.h"
|
||||
|
||||
void Sentence::_bind_methods() {
|
||||
BIND_HPROPERTY(Variant::STRING, symbols_string, PROPERTY_HINT_MULTILINE_TEXT);
|
||||
BIND_PROPERTY(Variant::VECTOR2I, size);
|
||||
BIND_HPROPERTY(Variant::STRING, symbols_string, PROPERTY_HINT_MULTILINE_TEXT);
|
||||
}
|
||||
|
||||
bool Sentence::is_terminal() const {
|
||||
|
|
@ -58,7 +58,7 @@ 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{ value.length() >= reader ? value[reader] : (char32_t)'B' };
|
||||
char32_t c{ reader < value.length() ? value[reader] : (char32_t)'B' };
|
||||
if (c != '\n') {
|
||||
this->symbols.set(writer, c);
|
||||
++writer;
|
||||
|
|
@ -81,9 +81,6 @@ void Sentence::set_size(Vector2i value) {
|
|||
this->size = value;
|
||||
this->symbols.clear();
|
||||
this->symbols.resize_initialized(this->size.x * this->size.y);
|
||||
for (int i{ 0 }; i < this->symbols.size(); ++i) {
|
||||
this->symbols.set(i, 'B');
|
||||
}
|
||||
}
|
||||
|
||||
Vector2i Sentence::get_size() const {
|
||||
|
|
@ -112,10 +109,11 @@ void CompositeRule::try_apply(Ref<Sentence> sentence) {
|
|||
|
||||
void ReplaceRule::_bind_methods() {
|
||||
BIND_HPROPERTY(Variant::OBJECT, pattern, PROPERTY_HINT_RESOURCE_TYPE, Sentence::get_class_static());
|
||||
BIND_HPROPERTY(Variant::OBJECT, result, PROPERTY_HINT_RESOURCE_TYPE, Sentence::get_class_static());
|
||||
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");
|
||||
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
|
||||
|
|
@ -123,13 +121,32 @@ void ReplaceRule::try_apply(Ref<Sentence> sentence) {
|
|||
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->result);
|
||||
sentence->write_subsentence(pos, this->results[Math::rand() % this->results.size()].first); // TODO pick based on weighed random
|
||||
}
|
||||
}
|
||||
pos.x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ReplaceRule::set_results_dict(Dictionary dict) {
|
||||
this->results.clear();
|
||||
for (KeyValue<Variant, Variant> var : dict) {
|
||||
Ref<Sentence> key{ var.key };
|
||||
if (key.is_valid() && var.value.is_num()) {
|
||||
float value{ var.value };
|
||||
this->results.push_back({ key, value });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary ReplaceRule::get_results_dict() const {
|
||||
Dictionary dict;
|
||||
for (KeyValue<Ref<Sentence>, float> kvp : this->results) {
|
||||
dict[kvp.key] = kvp.value;
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
void ResizeRule::_bind_methods() {
|
||||
BIND_PROPERTY(Variant::INT, factor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,15 +7,20 @@ typedef char32_t Symbol;
|
|||
|
||||
namespace NonTerminals {
|
||||
enum : Symbol {
|
||||
Start = 'S',
|
||||
Blocked = 'B',
|
||||
Invalid = '!',
|
||||
Start = L'S',
|
||||
Goal = L'G',
|
||||
Undefined = L'U',
|
||||
Path = L'P',
|
||||
Blocked = L'B',
|
||||
Invalid = L'!',
|
||||
};
|
||||
};
|
||||
|
||||
namespace Terminals {
|
||||
enum : Symbol {
|
||||
Invalid = '!',
|
||||
Invalid = L'!',
|
||||
Wall = L'w',
|
||||
Path = L'p'
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -76,11 +81,14 @@ public:
|
|||
|
||||
private:
|
||||
Ref<Sentence> pattern{};
|
||||
Ref<Sentence> result{};
|
||||
Vector<Pair<Ref<Sentence>, float>> results{};
|
||||
|
||||
public:
|
||||
GET_SET_FNS(Ref<Sentence>, pattern);
|
||||
GET_SET_FNS(Ref<Sentence>, result);
|
||||
void set_results(Vector<Pair<Ref<Sentence>, float>> value) { this->results = value; }
|
||||
Vector<Pair<Ref<Sentence>, float>> get_results() { return this->results; }
|
||||
void set_results_dict(Dictionary value);
|
||||
Dictionary get_results_dict() const;
|
||||
};
|
||||
|
||||
class ResizeRule : public CompositeRule {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,23 @@
|
|||
[gd_scene format=3 uid="uid://cak2tf2adjv8j"]
|
||||
|
||||
[sub_resource type="Sentence" id="Sentence_bb2w7"]
|
||||
symbols_string = "BBBBB
|
||||
BBBBB
|
||||
BBBBB
|
||||
BBBBB
|
||||
BBBBB"
|
||||
size = Vector2i(5, 5)
|
||||
size = Vector2i(10, 10)
|
||||
symbols_string = "BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB
|
||||
BBBBBBBBBB"
|
||||
|
||||
[sub_resource type="Sentence" id="Sentence_wail4"]
|
||||
size = Vector2i(3, 3)
|
||||
symbols_string = "BBB
|
||||
BBB
|
||||
BBB"
|
||||
|
||||
[node name="Dungeon" type="Node3D" unique_id=719313039]
|
||||
|
||||
|
|
@ -14,3 +25,4 @@ size = Vector2i(5, 5)
|
|||
state = SubResource("Sentence_bb2w7")
|
||||
|
||||
[node name="ReplaceRule" type="ReplaceRule" parent="Generator" unique_id=1787373751]
|
||||
pattern = SubResource("Sentence_wail4")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue