Parks-n-Rec/include/genetic/v3/program_v3.h

162 lines
4.8 KiB
C
Raw Normal View History

2023-07-18 21:59:41 -04:00
//
// Created by brett on 7/18/23.
//
#ifndef PARKSNREC_PROGRAM_V3_H
#define PARKSNREC_PROGRAM_V3_H
#include <genetic/v3/functions_v3.h>
2023-07-19 19:38:52 -04:00
#include "ImNodesEz.h"
2023-07-18 21:59:41 -04:00
namespace parks::genetic {
struct GeneticNode {
FunctionID op;
unsigned int pos{};
ParameterSet set;
2023-07-19 19:38:52 -04:00
GeneticNode(FunctionID op, unsigned int pos, ParameterSet set);
2023-07-18 21:59:41 -04:00
};
class GeneticTree {
private:
GeneticNode** nodes;
int size = 1;
2023-07-19 22:06:04 -04:00
int max_height;
2023-07-18 21:59:41 -04:00
2023-07-23 21:54:56 -04:00
static size_t getPixelPosition(unsigned int x, unsigned int y){
return x * CHANNELS + y * WIDTH * CHANNELS;
}
static double similarity(const unsigned char* pixels, unsigned int x, unsigned int y, int size);
static double aroundSimilarity(const unsigned char* pixels, unsigned int x, unsigned int y, int size);
2023-07-19 22:06:04 -04:00
void generateRandomTree(int n);
2023-07-18 21:59:41 -04:00
Color execute_internal(double x, double y, int node);
public:
2023-07-19 22:06:04 -04:00
explicit GeneticTree(int max_height): max_height(max_height) {
2023-07-18 21:59:41 -04:00
for (int i = 0; i < max_height; i++)
size *= 2;
2023-07-23 21:54:56 -04:00
size += 1;
2023-07-18 21:59:41 -04:00
nodes = new GeneticNode*[size];
for (int i = 0; i < size; i++)
nodes[i] = nullptr;
2023-07-19 21:21:16 -04:00
//nodes[0] = new GeneticNode(FunctionID::ADD, 0, functions[FunctionID::ADD].generateRandomParameters());
2023-07-19 22:06:04 -04:00
generateRandomTree(0);
2023-07-18 21:59:41 -04:00
}
Color execute(double x, double y);
static inline int left(int pos){
2023-07-19 21:21:16 -04:00
return 2 * (pos + 1);
2023-07-18 21:59:41 -04:00
}
2023-07-19 19:38:52 -04:00
2023-07-18 21:59:41 -04:00
static inline int right(int pos){
2023-07-19 21:21:16 -04:00
return 2 * (pos + 1) + 1;
2023-07-18 21:59:41 -04:00
}
2023-07-19 19:38:52 -04:00
2023-07-18 21:59:41 -04:00
static inline int parent(int pos){
if (pos <= 0)
2023-07-19 19:38:52 -04:00
return -1;
//if (pos % 2 == 0)
return pos / 2;
//return (pos + 1) / 2;
2023-07-18 21:59:41 -04:00
}
2023-07-19 19:38:52 -04:00
inline GeneticNode* node(int pos){
2023-07-18 21:59:41 -04:00
if (pos < 0 || pos >= size)
return nullptr;
2023-07-19 19:38:52 -04:00
return nodes[pos];
2023-07-18 21:59:41 -04:00
}
2023-07-19 19:38:52 -04:00
inline GeneticNode* leftNode(int pos){
return node(left(pos));
}
2023-07-18 21:59:41 -04:00
inline GeneticNode* rightNode(int pos){
if (pos < 0 || pos >= size)
return nullptr;
2023-07-19 19:38:52 -04:00
return node(right(pos));
2023-07-18 21:59:41 -04:00
}
static int height(int node);
2023-07-23 21:54:56 -04:00
[[nodiscard]] int subtreeSize(int n) const;
2023-07-19 22:06:04 -04:00
void deleteSubtree(int n);
2023-07-23 21:54:56 -04:00
std::pair<GeneticNode**, size_t> moveSubtree(int n);
void insertSubtree(int n, GeneticNode** tree, size_t size);
void processImage(unsigned char* pixels);
static double evaluate(const unsigned char* pixels);
double evaluate();
2023-07-18 21:59:41 -04:00
void deleteTree(){
for (int i = 0; i < size; i++) {
delete nodes[i];
nodes[i] = nullptr;
}
}
2023-07-19 19:38:52 -04:00
[[nodiscard]] inline int getSize() const {
return size;
}
2023-07-19 22:06:04 -04:00
void mutate();
2023-07-23 21:54:56 -04:00
void crossover(GeneticTree* other);
static GeneticTree* breed(GeneticTree* parent1, GeneticTree* parent2);
2023-07-18 21:59:41 -04:00
~GeneticTree(){
deleteTree();
delete[] nodes;
}
};
class Program {
private:
2023-07-19 19:38:52 -04:00
struct ImNode_t
{
int height{};
int index{};
FunctionID id;
ImVec2 pos{};
bool selected{};
ImNodes::Ez::SlotInfo inputs[1]{};
ImNodes::Ez::SlotInfo outputs[2]{};
};
std::vector<ImNode_t> treeNodes;
2023-07-18 21:59:41 -04:00
unsigned char pixels[WIDTH * HEIGHT * CHANNELS];
2023-07-19 19:38:52 -04:00
GeneticTree* tree;
2023-07-23 21:54:56 -04:00
GeneticTree* last_tree = nullptr;
GeneticTree* saved_tree = nullptr;
2023-07-18 21:59:41 -04:00
2023-07-19 19:38:52 -04:00
void regenTreeDisplay();
2023-07-23 21:54:56 -04:00
float renderProgress = 0;
2023-07-18 21:59:41 -04:00
public:
2023-07-19 19:38:52 -04:00
Program() = default;
2023-07-18 21:59:41 -04:00
void run();
2023-07-19 19:38:52 -04:00
void draw();
2023-07-18 21:59:41 -04:00
2023-07-19 19:38:52 -04:00
[[nodiscard]] float getRenderProgress() const{
return renderProgress;
2023-07-18 21:59:41 -04:00
}
inline unsigned char* getPixels(){
return pixels;
}
2023-07-19 19:38:52 -04:00
~Program(){
delete tree;
}
2023-07-18 21:59:41 -04:00
};
}
#endif //PARKSNREC_PROGRAM_V3_H