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(); }