From 00303ae3bee9d4a8f92fca37691cfce07a848854 Mon Sep 17 00:00:00 2001 From: Maddie Busig Date: Tue, 29 Apr 2025 04:59:38 -0700 Subject: [PATCH] Refactor fractal generator and fractal classes, begin rewrite Separating fractal generation run from ruleset generation. After the ruleset is processed, there is no reason for the group characteristics, etc to still be used. Additionally, this will avoid the possibility of the user attempting to use the fractal before ruleset is created and processed. Other changes: Branch rules now use unioned weighted or unweighted group. Rewrite ruleset creation usage --- include/fractal.hpp | 75 +++++++++++++++++++++++++++++--------- src/fractal.cpp | 2 ++ src/main.cpp | 88 ++++++++++++++------------------------------- 3 files changed, 86 insertions(+), 79 deletions(-) diff --git a/include/fractal.hpp b/include/fractal.hpp index df69ce9..da10e67 100644 --- a/include/fractal.hpp +++ b/include/fractal.hpp @@ -12,26 +12,24 @@ namespace fractal { using token_id_t = uint32_t; using group_id_t = uint32_t; using weighted_group_id_t = uint32_t; -using branch_rule_basic_id_t = uint32_t; -using branch_rule_marking_id_t = uint32_t; +using branch_rule_id_t = uint32_t; +using mark_rule_id_t = uint32_t; enum class token_type_e { - none, + empty, walk, rotate, - generate, }; struct token_t { - token_type_e m_token = token_type_e::none; + token_type_e m_token = token_type_e::empty; mtl::fixed m_value; }; +template struct group_characteristic_t { - static constexpr size_t g_max_group_size = 32; - uint32_t m_factor; // Number of groups generated in succession - etl::vector m_token_ids; + etl::vector m_token_ids; }; struct marker_t { @@ -59,24 +57,66 @@ struct group_t { etl::vector m_child_markers; }; +template struct weighted_group_t { - static constexpr size_t g_max_group_weights = 8; - - etl::vector m_groups; - etl::vector m_weights; - uint32_t m_weight_total; + etl::vector m_groups; + etl::vector m_weights; + uint32_t m_weight_total; // Total needed for random selection + // TODO: Control weight additions so m_weight_total = sum(m_weights) is invariant }; -struct branch_rule_basic_t { +struct branch_rule_t { token_id_t m_match; - weighted_group_id_t m_weighted_group; + bool m_weighted; + + union { + group_id_t basic; + weighted_group_id_t weighted; + } m_group; }; -struct branch_rule_marking_t { +struct mark_rule_t { token_id_t m_match; - uint32_t m_marker_id; + uint32_t m_tag; }; +template < + size_t S_MAX_TOKENS = 8, + size_t S_MAX_CGROUPS = 8, + size_t S_MAX_WGROUPS = 8, + size_t S_MAX_BRANCH_RULES = 4, + size_t S_MAX_MARK_RULES = 4, + size_t S_MAX_CGROUP_TOKENS = 16, + size_t S_MAX_WGROUP_WEIGHTS = 8 + > +class ruleset_t { +private: + etl::vector m_tokens; + etl::vector, S_MAX_CGROUPS> m_group_characteristics; + etl::vector, S_MAX_WGROUPS> m_weighted_groups; + + etl::vector m_branch_rules; + etl::vector m_mark_rules; + +public: + bool tokens_full() const; + token_id_t add_token(token_type_e type, mtl::fixed value = 0); + + bool group_characteristics_full() const; + group_id_t add_group_characteristic(const etl::ivector& tokens, uint32_t factor = 1); + + bool weighted_groups_full() const; + weighted_group_id_t add_weighted_group(const etl::ivector& groups); + + bool branch_rules_full() const; + branch_rule_id_t add_branch_rule(token_id_t match, group_id_t group); + branch_rule_id_t add_branch_rule_weighted(token_id_t match, weighted_group_id_t wgroup); + + bool mark_rules_full() const; + mark_rule_id_t add_mark_rule(token_id_t match, uint32_t tag); +}; + +#if 0 class generator_t { private: static constexpr size_t g_max_groups = 32; @@ -291,6 +331,7 @@ public: */ bool step_generation(const etl::ivector& out_markers) noexcept; }; +#endif } // namespace fractal diff --git a/src/fractal.cpp b/src/fractal.cpp index 3ab8374..d0382be 100644 --- a/src/fractal.cpp +++ b/src/fractal.cpp @@ -8,6 +8,7 @@ namespace log = mtl::log; namespace fractal { +#if 0 token_id_t generator_t::add_token(token_type_e type, mtl::fixed value) { log::debug << "Adding token with type " << (int)type << endl; @@ -199,6 +200,7 @@ void generator_t::set_initial_orientation(mtl::fixed orientation) noexcept { bool generator_t::step_generation(const etl::ivector& out_markers) noexcept { } +#endif } // namespace fractal diff --git a/src/main.cpp b/src/main.cpp index be638cf..96baa8f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,92 +8,56 @@ #include "fractal.hpp" using namespace mtl; +using namespace fractal; int main(void) { REG_DISPCNT = DCNT_MODE3 | DCNT_BG2; log::debug << "Hello world!" << mtl::endl; - fractal::generator_t gen; + ruleset_t rules; try { - fractal::token_id_t walk_petal_length = gen.add_token(fractal::token_type_e::walk, 8); - fractal::token_id_t walk_petal_side = gen.add_token(fractal::token_type_e::walk, 4); + fixed branch_angle = M_PI_4; - fractal::token_id_t rotate_axiom = gen.add_token(fractal::token_type_e::rotate, M_PI_2); - fractal::token_id_t rotate_petal = gen.add_token(fractal::token_type_e::rotate, M_PI_2); - fractal::token_id_t rotate_branchr = gen.add_token(fractal::token_type_e::rotate, -M_PI_4); - fractal::token_id_t rotate_branchl = gen.add_token(fractal::token_type_e::rotate, +M_PI_4); + token_id_t walk_petal_length = rules.add_token(token_type_e::walk, 8); + token_id_t walk_petal_side = rules.add_token(token_type_e::walk, 4); - fractal::token_id_t generate_seed = gen.add_token(fractal::token_type_e::generate); - fractal::token_id_t generate_petal = gen.add_token(fractal::token_type_e::generate); - fractal::token_id_t generate_branchr = gen.add_token(fractal::token_type_e::generate); - fractal::token_id_t generate_branchl = gen.add_token(fractal::token_type_e::generate); - fractal::token_id_t generate_mark = gen.add_token(fractal::token_type_e::generate); + token_id_t rotate_axiom = rules.add_token(token_type_e::rotate, M_PI_2); + token_id_t rotate_petal = rules.add_token(token_type_e::rotate, M_PI_2); + token_id_t rotate_branchr = rules.add_token(token_type_e::rotate, branch_angle); + token_id_t rotate_branchl = rules.add_token(token_type_e::rotate, branch_angle * -2); + + token_id_t branch = rules.add_token(token_type_e::empty); + token_id_t petal = rules.add_token(token_type_e::empty); + token_id_t mark = rules.add_token(token_type_e::empty); log::info << "Added tokens" << endl; - constexpr uint32_t axiom_factor = 4; - constexpr uint32_t branchr_factor = 1; - constexpr uint32_t branchl_factor = 1; + uint32_t axiom_factor = 4; - etl::vector axiom_characteristic{generate_seed, rotate_axiom}; - fractal::group_id_t group_axiom = gen.add_group_characteristic(axiom_factor, axiom_characteristic); + etl::vector axiom_chr{ branch, rotate_axiom }; + group_id_t axiom_grp = rules.add_group_characteristic(axiom_chr, axiom_factor); - etl::vector seed_characteristic{generate_petal, generate_branchl, generate_branchr}; - fractal::group_id_t group_seed = gen.add_group_characteristic(seed_characteristic); + etl::vector branch_chr{ petal, rotate_branchr, branch, rotate_branchl, branch }; + group_id_t branch_grp = rules.add_group_characteristic(branch_chr); - etl::vector petal_characteristic{generate_mark, walk_petal_length, generate_mark, rotate_petal, walk_petal_side, generate_mark}; - fractal::group_id_t group_petal = gen.add_group_characteristic(petal_characteristic); - - etl::vector branchl_characteristic{rotate_branchl, generate_seed}; - fractal::group_id_t group_branchl = gen.add_group_characteristic(branchl_factor, branchl_characteristic); - - etl::vector branchr_characteristic{rotate_branchr, generate_seed}; - fractal::group_id_t group_branchr = gen.add_group_characteristic(branchr_factor, branchr_characteristic); + etl::vector petal_chr{ mark, walk_petal_length, mark, rotate_petal, walk_petal_length, mark }; + group_id_t petal_grp = rules.add_group_characteristic(petal_chr); log::info << "Added group characteristics" << endl; - etl::vector, 1> axiom_weights{{group_axiom, 1}}; - fractal::weighted_group_id_t wgroup_axiom = gen.add_weighted_group(axiom_weights); + rules.add_branch_rule(branch, branch_grp); + rules.add_branch_rule(petal, petal_grp); + rules.add_mark_rule(mark, 1); - fractal::weighted_group_id_t wgroup_seed = gen.add_weighted_group(group_seed); - fractal::weighted_group_id_t wgroup_petal = gen.add_weighted_group(group_petal); - fractal::weighted_group_id_t wgroup_branchl = gen.add_weighted_group(group_branchl); - fractal::weighted_group_id_t wgroup_branchr = gen.add_weighted_group(group_branchr); - - log::info << "Added weighted groups" << endl; - - gen.add_basic_branch_rule(generate_seed, wgroup_seed); - gen.add_basic_branch_rule(generate_petal, wgroup_petal); - gen.add_basic_branch_rule(generate_branchl, wgroup_branchl); - gen.add_basic_branch_rule(generate_branchr, wgroup_branchr); - gen.add_marking_branch_rule(generate_mark, 1); - - log::info << "Added branch rules" << endl; - - gen.set_axiom(wgroup_axiom); - - log::info << "Successfully added generator values" << endl; + log::info << "Added rules" << endl; + log::info << "Finished configuring ruleset" << endl; } catch(const mtl::exception&) { - log::info << "Failed to create generator, caught exception" << endl; + log::info << "Failed to configure ruleset, caught exception" << endl; return 0; } - /*gen.preprocess(); - - constexpr uint32_t num_generations = 3; - constexpr size_t max_markers = 128; - - etl::vector markers; - for (size_t i = 0; i < num_generations; ++i) { - markers.clear(); - - gen.step_generation(markers); - - //draw_triangles(markers); - }*/ - while (true) { vid_vsync(); }