103 lines
2.9 KiB
C++
103 lines
2.9 KiB
C++
#include "generator.h"
|
|
#include "core/config/engine.h"
|
|
#include "core/math/math_funcs.h"
|
|
#include "core/math/vector2i.h"
|
|
#include "core/object/class_db.h"
|
|
#include "macros.h"
|
|
|
|
void Generator::_bind_methods() {
|
|
BIND_HPROPERTY(Variant::OBJECT, state, PROPERTY_HINT_RESOURCE_TYPE, "Sentence");
|
|
BIND_HPROPERTY(Variant::DICTIONARY, tiles_dict, PROPERTY_HINT_DICTIONARY_TYPE, vformat("String;PackedScene"));
|
|
}
|
|
|
|
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, Terminals::Undefined);
|
|
}
|
|
#if 0
|
|
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);
|
|
}
|
|
#endif
|
|
print_line("Writing path");
|
|
int y{ (Math::abs((int)Math::rand()) % (this->state->size.y - 6)) + 3 };
|
|
print_line("Path at y =", y);
|
|
for (int i{ 1 }; i < this->state->size.x - 1; ++i) {
|
|
this->state->set_at({ i, y }, Terminals::Path);
|
|
}
|
|
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());
|
|
for (Vector2i at{ 0, 0 }; at.y < this->state->size.y; ++at.y) {
|
|
for (; at.x < this->state->size.x; ++at.x) {
|
|
Symbol s{ this->state->get_at(at) };
|
|
if (this->tiles.has(s)) {
|
|
if (Node * node{ this->tiles.get(s)->instantiate() }) {
|
|
if (Node3D * node3d{ cast_to<Node3D>(node) }) {
|
|
node3d->set_position({ (float)at.x, 0, (float)at.y });
|
|
}
|
|
this->add_child(node);
|
|
}
|
|
}
|
|
}
|
|
at.x = 0;
|
|
}
|
|
}
|
|
|
|
void Generator::_notification(int what) {
|
|
if (Engine::get_singleton()->is_editor_hint()) {
|
|
return;
|
|
}
|
|
switch (what) {
|
|
default:
|
|
return;
|
|
case NOTIFICATION_READY:
|
|
ready();
|
|
case NOTIFICATION_CHILD_ORDER_CHANGED:
|
|
for (Variant child : get_children()) {
|
|
if (Rule * rule{ cast_to<Rule>(child) }) {
|
|
this->rule = rule;
|
|
return;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
void Generator::set_tiles_dict(Dictionary dict) {
|
|
this->tiles.clear();
|
|
for (KeyValue<Variant, Variant> kvp : dict) {
|
|
String key{ kvp.key };
|
|
Ref<PackedScene> value{ kvp.value };
|
|
if (key.is_empty() || value.is_null()) {
|
|
continue;
|
|
}
|
|
this->tiles.insert(key.get(0), value);
|
|
}
|
|
}
|
|
|
|
Dictionary Generator::get_tiles_dict() const {
|
|
Dictionary dict{};
|
|
for (TileMap::KV kvp : this->tiles) {
|
|
dict.set(String() + kvp.key, kvp.value);
|
|
}
|
|
return dict;
|
|
}
|