GP_Image_Test/include/gp.h

113 lines
2.8 KiB
C++

/*
* <Short Description>
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef GP_IMAGE_TEST_GP_H
#define GP_IMAGE_TEST_GP_H
#include <config.h>
#include <functions.h>
#include <random>
struct node;
class tree;
node* createNode(function_t type);
void destroyNode(node* n);
struct node
{
friend tree;
private:
// only valid up to the argc
std::array<node*, MAX_ARGS> sub_nodes{nullptr};
size_t argc = 0;
function_t type = function_t::ADD;
data_t data{};
std::optional<image> img;
void grow(bool use_terminals);
void full(bool use_terminals);
void populate_node(size_t i, std::mt19937_64& engine, const allowed_funcs<function_t>& allowed_args, bool use_terminal);
void print_tree();
public:
explicit node(function_t type): type(type)
{
static thread_local std::random_device dev;
static thread_local std::mt19937_64 engine{dev()};
static thread_local std::uniform_real_distribution<float> dist(0.0f, 1.0f);
if (type == function_t::SCALAR)
data[0] = dist(engine);
else if (type == function_t::COLOR)
{
for (auto& v : data)
v = dist(engine);
}
}
node(const node& copy);
static node* construct_random_tree(blt::size_t max_depth = MAX_DEPTH);
void evaluate();
void evaluate_tree()
{
for (size_t i = 0; i < argc; i++)
sub_nodes[i]->evaluate_tree();
evaluate();
}
void printTree()
{
print_tree();
std::cout << std::endl;
}
bool hasImage()
{
return img.has_value();
}
image& getImage()
{
return img.value();
}
~node()
{
for (auto* node : sub_nodes)
destroyNode(node);
}
};
struct node_deleter
{
void operator()(node* ptr)
{
destroyNode(ptr);
}
};
#endif //GP_IMAGE_TEST_GP_H