feat: started generative grammar
This commit is contained in:
parent
0e9576adbc
commit
1d4feabf7e
10 changed files with 229 additions and 0 deletions
3
modules/generative_grammar/SCsub
Normal file
3
modules/generative_grammar/SCsub
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Import('env')
|
||||
|
||||
env.add_source_files(env.modules_sources, "*.cpp")
|
||||
5
modules/generative_grammar/config.py
Normal file
5
modules/generative_grammar/config.py
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
def can_build(env, platform):
|
||||
return True;
|
||||
|
||||
def configure(env):
|
||||
pass;
|
||||
24
modules/generative_grammar/generator.cpp
Normal file
24
modules/generative_grammar/generator.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "generator.h"
|
||||
#include "core/config/engine.h"
|
||||
#include "core/object/class_db.h"
|
||||
#include "macros.h"
|
||||
|
||||
void Generator::_bind_methods() {
|
||||
BIND_HPROPERTY(Variant::OBJECT, state, PROPERTY_HINT_RESOURCE_TYPE, "Symbol");
|
||||
}
|
||||
|
||||
void Generator::ready() {
|
||||
}
|
||||
|
||||
void Generator::_notification(int what) {
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
return;
|
||||
}
|
||||
switch (what) {
|
||||
default:
|
||||
return;
|
||||
case NOTIFICATION_READY:
|
||||
ready();
|
||||
return;
|
||||
}
|
||||
}
|
||||
19
modules/generative_grammar/generator.h
Normal file
19
modules/generative_grammar/generator.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "generative_grammar/symbol.h"
|
||||
#include "scene/3d/node_3d.h"
|
||||
|
||||
class Generator : public Node3D {
|
||||
GDCLASS(Generator, Node3D);
|
||||
static void _bind_methods();
|
||||
void ready();
|
||||
|
||||
protected:
|
||||
void _notification(int what);
|
||||
|
||||
public:
|
||||
Ref<Symbol> state{};
|
||||
|
||||
private:
|
||||
GET_SET_FNS(Ref<Symbol>, state);
|
||||
};
|
||||
19
modules/generative_grammar/register_types.cpp
Normal file
19
modules/generative_grammar/register_types.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "generative_grammar/register_types.h"
|
||||
#include "core/object/class_db.h"
|
||||
#include "generative_grammar/generator.h"
|
||||
#include "generative_grammar/symbol.h"
|
||||
|
||||
void initialize_generative_grammar_module(ModuleInitializationLevel p_level) {
|
||||
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
|
||||
return;
|
||||
}
|
||||
ClassDB::register_class<Symbol>();
|
||||
ClassDB::register_class<Rule>();
|
||||
ClassDB::register_class<Generator>();
|
||||
}
|
||||
|
||||
void uninitialize_generative_grammar_module(ModuleInitializationLevel p_level) {
|
||||
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
9
modules/generative_grammar/register_types.h
Normal file
9
modules/generative_grammar/register_types.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef GENERATIVE_GRAMMAR_REGISTER_TYPES_H
|
||||
#define GENERATIVE_GRAMMAR_REGISTER_TYPES_H
|
||||
|
||||
#include "modules/register_module_types.h"
|
||||
|
||||
void initialize_generative_grammar_module(ModuleInitializationLevel p_level);
|
||||
void uninitialize_generative_grammar_module(ModuleInitializationLevel p_level);
|
||||
|
||||
#endif // !GENERATIVE_GRAMMAR_REGISTER_TYPES_H
|
||||
80
modules/generative_grammar/symbol.cpp
Normal file
80
modules/generative_grammar/symbol.cpp
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#include "generative_grammar/symbol.h"
|
||||
#include "core/error/error_macros.h"
|
||||
#include "core/object/class_db.h"
|
||||
|
||||
void Symbol::_bind_methods() {
|
||||
BIND_HPROPERTY(Variant::INT, symbol, PROPERTY_HINT_ENUM, Type_hint());
|
||||
BIND_HPROPERTY(Variant::ARRAY, children_array, PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Symbol"));
|
||||
}
|
||||
|
||||
bool Symbol::is_terminal() const {
|
||||
switch (this->type) {
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Symbol::set_children_array(TypedArray<Ref<Symbol>> array) {
|
||||
for (Ref<Symbol> symbol : this->children) {
|
||||
if (symbol.is_valid()) {
|
||||
symbol->set_parent(nullptr);
|
||||
}
|
||||
}
|
||||
this->children.clear();
|
||||
for (Variant var : array) {
|
||||
Ref<Symbol> child{ var };
|
||||
this->children.insert(var);
|
||||
if (child.is_valid()) {
|
||||
child->set_parent(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TypedArray<Ref<Symbol>> Symbol::get_children_array() const {
|
||||
TypedArray<Ref<Symbol>> array{};
|
||||
for (Ref<Symbol> symbol : this->children) {
|
||||
array.push_back(symbol);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
void Rule::_bind_methods() {
|
||||
BIND_HPROPERTY(Variant::OBJECT, match, PROPERTY_HINT_RESOURCE_TYPE, "Symbol");
|
||||
BIND_HPROPERTY(Variant::OBJECT, result, PROPERTY_HINT_RESOURCE_TYPE, "Symbol");
|
||||
}
|
||||
|
||||
bool Rule::symbols_match(Ref<Symbol> match, Ref<Symbol> pattern) {
|
||||
if (match == pattern) {
|
||||
return true; // reference match or null match
|
||||
}
|
||||
ERR_FAIL_COND_V_EDMSG(match.is_valid() == false, false, "Attempt to match null symbol, is not possible");
|
||||
if (pattern.is_null()) {
|
||||
return false; // null matches nothing
|
||||
}
|
||||
if (match->get_symbol() != pattern->get_symbol()) {
|
||||
return false; // symbol type mismatch
|
||||
}
|
||||
if (match->get_children().size() < pattern->get_children().size()) {
|
||||
return false; // too little children to be able to match
|
||||
}
|
||||
if ((match->get_parent() == nullptr) != (pattern->get_parent() == nullptr)) {
|
||||
return false; // mismatch in existence of incoming edge
|
||||
}
|
||||
// check for matching outgoing edges
|
||||
for (Ref<Symbol> pattern_symbol : pattern->get_children()) {
|
||||
bool match_found{ false };
|
||||
for (Ref<Symbol> match_symbol : match->get_children()) {
|
||||
if (symbols_match(match_symbol, pattern_symbol)) {
|
||||
match_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match_found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Rule::matches(Ref<Symbol> graph) {
|
||||
}
|
||||
49
modules/generative_grammar/symbol.h
Normal file
49
modules/generative_grammar/symbol.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/io/resource.h"
|
||||
#include "core/templates/hash_set.h"
|
||||
#include "core/variant/type_info.h"
|
||||
#include "core/variant/typed_array.h"
|
||||
#include "macros.h"
|
||||
|
||||
class Symbol : public Resource {
|
||||
GDCLASS(Symbol, Resource);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
GDENUM(Type, Start, Goal, Challenge, Reward);
|
||||
bool is_terminal() const;
|
||||
|
||||
private:
|
||||
Type symbol{ Start };
|
||||
HashSet<Ref<Symbol>> children{};
|
||||
Symbol *parent{ nullptr };
|
||||
|
||||
public:
|
||||
GET_SET_FNS(Type, symbol);
|
||||
GET_SET_FNS(Symbol *, parent);
|
||||
GET_SET_REF_FNS(HashSet<Ref<Symbol>>, children);
|
||||
void set_children_array(TypedArray<Ref<Symbol>> array);
|
||||
TypedArray<Ref<Symbol>> get_children_array() const;
|
||||
};
|
||||
|
||||
MAKE_TYPE_INFO(Symbol::Type, Variant::INT);
|
||||
|
||||
struct Rule : public Resource {
|
||||
GDCLASS(Rule, Resource);
|
||||
static void _bind_methods();
|
||||
bool symbols_match(Ref<Symbol> match, Ref<Symbol> pattern);
|
||||
|
||||
public:
|
||||
bool matches(Ref<Symbol> graph);
|
||||
void apply(Ref<Symbol> graph);
|
||||
bool try_apply(Ref<Symbol> graph);
|
||||
|
||||
private:
|
||||
Ref<Symbol> match{};
|
||||
Ref<Symbol> result{};
|
||||
|
||||
public:
|
||||
GET_SET_FNS(Ref<Symbol>, match);
|
||||
GET_SET_FNS(Ref<Symbol>, result);
|
||||
};
|
||||
13
project/data/rules/test_rule.tres
Normal file
13
project/data/rules/test_rule.tres
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[gd_resource type="Rule" format=3 uid="uid://cb5x75r5umlh5"]
|
||||
|
||||
[sub_resource type="Symbol" id="Symbol_26ujg"]
|
||||
|
||||
[sub_resource type="Symbol" id="Symbol_titn7"]
|
||||
type = 1
|
||||
|
||||
[sub_resource type="Symbol" id="Symbol_kwj57"]
|
||||
children_array = Array[Object]([SubResource("Symbol_titn7")])
|
||||
|
||||
[resource]
|
||||
match = SubResource("Symbol_26ujg")
|
||||
result = SubResource("Symbol_kwj57")
|
||||
8
project/scenes/levels/dungeon.tscn
Normal file
8
project/scenes/levels/dungeon.tscn
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[gd_scene format=3 uid="uid://cak2tf2adjv8j"]
|
||||
|
||||
[sub_resource type="Symbol" id="Symbol_bb2w7"]
|
||||
|
||||
[node name="Dungeon" type="Node3D" unique_id=719313039]
|
||||
|
||||
[node name="Generator" type="Generator" parent="." unique_id=1532743122]
|
||||
state = SubResource("Symbol_bb2w7")
|
||||
Loading…
Add table
Add a link
Reference in a new issue