diff --git a/inc/App.hpp b/inc/App.hpp index 81dece9..2c43985 100644 --- a/inc/App.hpp +++ b/inc/App.hpp @@ -1,6 +1,6 @@ #include #include "canvas/Canvas.hpp" -#include "values/DnaManager.hpp" +#include "DnaStore.hpp" class App { @@ -36,7 +36,7 @@ private: std::array unit = {0}; - DnaManager manager; + DnaManagerData manager; Rectangle likedTextBox; Rectangle genTextBox; diff --git a/inc/DnaStore.hpp b/inc/DnaStore.hpp new file mode 100644 index 0000000..bac51cd --- /dev/null +++ b/inc/DnaStore.hpp @@ -0,0 +1,9 @@ +#include "values/DnaManager.hpp" + +namespace DnaStore +{ + void load(DnaManagerData *data); + void saveData(DnaManagerData *data); + void saveVec(DnaManagerData *data); + void saveGen(DnaManagerData *data); +} // namespace DnaStore diff --git a/inc/values/DnaManager.hpp b/inc/values/DnaManager.hpp index ebb3c43..8776e29 100644 --- a/inc/values/DnaManager.hpp +++ b/inc/values/DnaManager.hpp @@ -28,19 +28,9 @@ struct NetUnit static_assert(24 == sizeof(NetUnit)); -class DnaManager +struct DnaManagerData { -public: - void init(); - void deinit(); - UiUnit next(); - void like(UiUnit unit); int generation; - -private: - void saveData(); - void saveVec(); - void saveGen(); uint128 randSeed; uint128 id; int queued; @@ -48,6 +38,11 @@ private: std::vector vector; std::vector liked; std::vector disliked; - - void newGen(); +}; + +namespace DnaManager +{ + UiUnit next(DnaManagerData *data); + bool like(UiUnit unit, DnaManagerData *data); + void newGen(DnaManagerData *data); }; diff --git a/src/App.cpp b/src/App.cpp index ccbbca9..ae0735e 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -67,7 +67,7 @@ void App::init(int screenWidth, int screenHeight) canvasTexure[i] = LoadRenderTexture(screenWidth, screenWidth); } - manager.init(); + DnaStore::load(&manager); upTex(Liked::tbd); while (!canvas.tick(canvasTexure[TOP])) { @@ -108,9 +108,17 @@ void App::upTex(Liked liked) if (liked != Liked::tbd) { unit[TOP].liked = liked; - manager.like(unit[TOP]); + bool ng = DnaManager::like(unit[TOP], &manager); + + if (ng) + { + DnaStore::saveGen(&manager); + DnaManager::newGen(&manager); + DnaStore::saveVec(&manager); + } + DnaStore::saveData(&manager); } - unit[TOP] = manager.next(); + unit[TOP] = DnaManager::next(&manager); if (unit[TOP].dna != nullptr) { canvas.newGen(canvasTexure[TOP], unit[TOP].dna); @@ -212,5 +220,4 @@ void App::deinit() UnloadRenderTexture(canvasTexure[i]); } canvas.deinit(); - manager.deinit(); } \ No newline at end of file diff --git a/src/DnaStore.cpp b/src/DnaStore.cpp new file mode 100644 index 0000000..5a388b2 --- /dev/null +++ b/src/DnaStore.cpp @@ -0,0 +1,144 @@ +#include +#include + +#include "sys.hpp" +#include "DnaStore.hpp" + +#include + +#define ID_FILE_NAME "ID.bin" +#define DATA_FILE_NAME "DATA.bin" +#define VECTOR_FILE_NAME "VECTOR.bin" + +void DnaStore::load(DnaManagerData *data) +{ + if (sys::fileExists(ID_FILE_NAME)) + { + sys::loadDataFromFile(ID_FILE_NAME, &data->id, sizeof(uint128)); + } + else + { + data->id = mrand::getState(time(nullptr)); + sys::saveDataToFile(ID_FILE_NAME, &data->id, sizeof(uint128)); + } + + if (sys::fileExists(DATA_FILE_NAME)) + { + const char *filename = sys::transformFilePath(DATA_FILE_NAME); + + FILE *file = fopen(filename, "rb"); + if (file == NULL) + return; + + fread(&data->randSeed, 1, sizeof(uint128), file); + fread(&data->generation, 1, sizeof(int), file); + fread(&data->showed, 1, sizeof(int), file); + data->queued = data->showed; + int size, tmp; + + fread(&size, sizeof(size), 1, file); + for (int i = 0; i < size; i++) + { + fread(&tmp, sizeof(tmp), 1, file); + if (tmp >= NUM_PER_GEN) // out of bounds error prevention if buffer was in the past biiger then its now + continue; + data->liked.push_back(tmp); + } + + fread(&size, sizeof(size), 1, file); + for (int i = 0; i < size; i++) + { + fread(&tmp, sizeof(tmp), 1, file); + if (tmp >= NUM_PER_GEN) // out of bounds error prevention if buffer was in the past biiger then its now + continue; + data->disliked.push_back(tmp); + } + fclose(file); + } + else + { + data->randSeed = data->id; + data->queued = 0; + data->showed = 0; + data->generation = 0; + } + + data->vector.resize(NUM_PER_GEN); + if (sys::fileExists(VECTOR_FILE_NAME)) + { + sys::loadDataFromFile(VECTOR_FILE_NAME, data->vector.data(), sizeof(Dna) * NUM_PER_GEN); + } + else + { + for (std::size_t i = 0; i < NUM_PER_GEN; i++) + { + DNA::newDna(&data->vector[i], &data->randSeed); + } + saveVec(data); + } +} + +void DnaStore::saveData(DnaManagerData *data) +{ + const char *filename = sys::transformFilePath(DATA_FILE_NAME); + + FILE *file = fopen(filename, "wb"); + if (file == NULL) + return; + fwrite(&data->randSeed, 1, sizeof(uint128), file); + fwrite(&data->generation, 1, sizeof(int), file); + fwrite(&data->showed, 1, sizeof(int), file); + + int tmp; + tmp = data->liked.size(); + fwrite(&tmp, sizeof(tmp), 1, file); + fwrite(data->liked.data(), sizeof(int) * tmp, 1, file); + + tmp = data->disliked.size(); + + fwrite(&tmp, sizeof(tmp), 1, file); + fwrite(data->disliked.data(), sizeof(tmp) * tmp, 1, file); + + fclose(file); +} + +void DnaStore::saveVec(DnaManagerData *data) +{ + const char *filename = sys::transformFilePath(VECTOR_FILE_NAME); + FILE *file = fopen(filename, "wb"); + if (file == NULL) + return; + fwrite(data->vector.data(), sizeof(Dna) * NUM_PER_GEN, 1, file); + fclose(file); +} + +void DnaStore::saveGen(DnaManagerData *data) +{ + std::vector gen; + gen.resize(NUM_PER_GEN); + for (std::size_t i = 0; i < NUM_PER_GEN; i++) + { + unsigned int *hash = ComputeMD5((unsigned char *)&data->vector[i], sizeof(Dna)); + gen[i].hash.a = hash[0]; + gen[i].hash.b = hash[1]; + gen[i].hash.c = hash[2]; + gen[i].hash.d = hash[3]; + + gen[i].liked = Liked::tbd; + gen[i].index = i; + } + + for (auto &&i : data->liked) + { + gen[i].liked = Liked::yes; + } + + for (auto &&i : data->disliked) + { + gen[i].liked = Liked::no; + } + + const char *fileName = TextFormat("gen%04d.bin", data->generation); + + sys::saveDataToFile(fileName, gen.data(), sizeof(NetUnit) * NUM_PER_GEN); +} diff --git a/src/values/Dna.cpp b/src/values/Dna.cpp index e2eaf25..ecdc928 100644 --- a/src/values/Dna.cpp +++ b/src/values/Dna.cpp @@ -3,8 +3,6 @@ #include "values/Dna.hpp" -#include - namespace DNA { diff --git a/src/values/DnaManager.cpp b/src/values/DnaManager.cpp index af3cc48..51e7c95 100644 --- a/src/values/DnaManager.cpp +++ b/src/values/DnaManager.cpp @@ -1,257 +1,112 @@ -#include -#include + + #include #include "values/DnaManager.hpp" -#include "sys.hpp" -#include - -#define ID_FILE_NAME "ID.bin" -#define DATA_FILE_NAME "DATA.bin" -#define VECTOR_FILE_NAME "VECTOR.bin" - -void DnaManager::init() +UiUnit DnaManager::next(DnaManagerData *data) { - if (sys::fileExists(ID_FILE_NAME)) - { - sys::loadDataFromFile(ID_FILE_NAME, &id, sizeof(uint128)); - } - else - { - id = mrand::getState(time(nullptr)); - sys::saveDataToFile(ID_FILE_NAME, &id, sizeof(uint128)); - } - - if (sys::fileExists(DATA_FILE_NAME)) - { - const char *filename = sys::transformFilePath(DATA_FILE_NAME); - - FILE *file = fopen(filename, "rb"); - if (file == NULL) - return; - - fread(&randSeed, 1, sizeof(uint128), file); - fread(&generation, 1, sizeof(int), file); - fread(&showed, 1, sizeof(showed), file); - queued = showed; - int size, tmp; - - fread(&size, sizeof(size), 1, file); - for (int i = 0; i < size; i++) - { - fread(&tmp, sizeof(tmp), 1, file); - if (tmp >= NUM_PER_GEN) // out of bounds error prevention if buffer was in the past biiger then its now - continue; - liked.push_back(tmp); - } - - fread(&size, sizeof(size), 1, file); - for (int i = 0; i < size; i++) - { - fread(&tmp, sizeof(tmp), 1, file); - if (tmp >= NUM_PER_GEN) // out of bounds error prevention if buffer was in the past biiger then its now - continue; - disliked.push_back(tmp); - } - fclose(file); - } - else - { - randSeed = id; - queued = 0; - showed = 0; - generation = 0; - } - - vector.resize(NUM_PER_GEN); - if (sys::fileExists(VECTOR_FILE_NAME)) - { - sys::loadDataFromFile(VECTOR_FILE_NAME, vector.data(), sizeof(Dna) * NUM_PER_GEN); - } - else - { - for (std::size_t i = 0; i < NUM_PER_GEN; i++) - { - DNA::newDna(&vector[i], &randSeed); - } - saveVec(); - } -} - -void DnaManager::deinit() -{ -} - -void DnaManager::saveData() -{ - const char *filename = sys::transformFilePath(DATA_FILE_NAME); - - FILE *file = fopen(filename, "wb"); - if (file == NULL) - return; - fwrite(&randSeed, 1, sizeof(uint128), file); - fwrite(&generation, 1, sizeof(int), file); - fwrite(&showed, 1, sizeof(showed), file); - - int tmp; - tmp = liked.size(); - fwrite(&tmp, sizeof(tmp), 1, file); - fwrite(liked.data(), sizeof(int) * tmp, 1, file); - - tmp = disliked.size(); - - fwrite(&tmp, sizeof(tmp), 1, file); - fwrite(disliked.data(), sizeof(tmp) * tmp, 1, file); - - fclose(file); -} - -void DnaManager::saveVec() -{ - const char *filename = sys::transformFilePath(VECTOR_FILE_NAME); - FILE *file = fopen(filename, "wb"); - if (file == NULL) - return; - fwrite(vector.data(), sizeof(Dna) * NUM_PER_GEN, 1, file); - fclose(file); -} - -UiUnit DnaManager::next() -{ - if (queued >= NUM_PER_GEN) + if (data->queued >= NUM_PER_GEN) { return {nullptr, Liked::tbd, -1}; } - Dna *ret = &vector[queued]; - int index = queued++; + Dna *ret = &data->vector[data->queued]; + int index = data->queued++; return {ret, Liked::tbd, index}; } -void DnaManager::like(UiUnit unit) +bool DnaManager::like(UiUnit unit, DnaManagerData *data) { int found = -1; - if (unit.index == showed) + if (unit.index == data->showed) { - found = showed; + found = data->showed; } if (found == -1) { // RUN OUT OF GEN WAITING FOR NEW GEN - return; + return false; } if (unit.liked == Liked::yes) { - liked.push_back(found); + data->liked.push_back(found); } else if (unit.liked == Liked::no) { - disliked.push_back(found); + data->disliked.push_back(found); } else { - TraceLog(LOG_ERROR, "LIKED WITH NO VAULE"); - return; + // could be infinite loop if something went wrong and user lost UiUnit and next is returning null thinking that it queued everiting + // maybe return true to move on and maybe tread Liked::tbd as Liked::no + return false; } - showed++; + data->showed++; - if (showed >= NUM_PER_GEN && queued >= NUM_PER_GEN) // if buffer was biger in the past showed could be more then NUM_PER_GEN so its changed to >= insted of == + if (data->showed >= NUM_PER_GEN && data->queued >= NUM_PER_GEN) // if buffer was biger in the past showed could be more then NUM_PER_GEN so its changed to >= insted of == { - saveGen(); - newGen(); - queued = 0; - showed = 0; - generation += 1; - saveVec(); + return true; } - saveData(); + return false; } -void DnaManager::saveGen() +void DnaManager::newGen(DnaManagerData *data) { - std::vector gen; - gen.resize(NUM_PER_GEN); - for (std::size_t i = 0; i < NUM_PER_GEN; i++) - { - unsigned int *hash = ComputeMD5((unsigned char *)&vector[i], sizeof(Dna)); - gen[i].hash.a = hash[0]; - gen[i].hash.b = hash[1]; - gen[i].hash.c = hash[2]; - gen[i].hash.d = hash[3]; - - gen[i].liked = Liked::tbd; - gen[i].index = i; - } - - for (auto &&i : liked) - { - gen[i].liked = Liked::yes; - } - - for (auto &&i : disliked) - { - gen[i].liked = Liked::no; - } - - const char *fileName = TextFormat("gen%04d.bin", generation); - - sys::saveDataToFile(fileName, gen.data(), sizeof(NetUnit) * NUM_PER_GEN); -} - -void DnaManager::newGen() -{ - if (liked.size() == 0) + data->queued = 0; + data->showed = 0; + data->generation += 1; + if (data->liked.size() == 0) { for (std::size_t i = 0; i < NUM_PER_GEN; i++) { - DNA::newDna(&vector[i], &randSeed); + DNA::newDna(&data->vector[i], &data->randSeed); } - disliked.clear(); + data->disliked.clear(); return; } - if (liked.size() == 1) + if (data->liked.size() == 1) { - int front = liked.front(); + int front = data->liked.front(); - for (auto &&i : disliked) + for (auto &&i : data->disliked) { - DNA::clone(&vector[front], &vector[i], &randSeed); + DNA::clone(&data->vector[front], &data->vector[i], &data->randSeed); } - disliked.clear(); - liked.clear(); + data->disliked.clear(); + data->liked.clear(); } - if (liked.size() >= 2) + if (data->liked.size() >= 2) { - for (auto &&i : disliked) + for (auto &&i : data->disliked) { - size_t p1 = mrand::getValue(0, liked.size() - 1, &randSeed); - size_t p2 = mrand::getValue(0, liked.size() - 1, &randSeed); + size_t p1 = mrand::getValue(0, data->liked.size() - 1, &data->randSeed); + size_t p2 = mrand::getValue(0, data->liked.size() - 1, &data->randSeed); while (p1 == p2) { - p2 = mrand::getValue(0, liked.size(), &randSeed); + p2 = mrand::getValue(0, data->liked.size(), &data->randSeed); } - p1 = liked[p1]; - p2 = liked[p2]; - Dna *p1p = &vector[p1]; - Dna *p2p = &vector[p2]; - Dna *c = &vector[i]; + p1 = data->liked[p1]; + p2 = data->liked[p2]; + Dna *p1p = &data->vector[p1]; + Dna *p2p = &data->vector[p2]; + Dna *c = &data->vector[i]; - DNA::makeChild(p1p, p2p, c, &randSeed); + DNA::makeChild(p1p, p2p, c, &data->randSeed); } } for (size_t i = 0; i < NUM_PER_GEN; i++) { - DNA::mutate(&vector[i], NUM_OF_MUT, &randSeed); + DNA::mutate(&data->vector[i], NUM_OF_MUT, &data->randSeed); } - disliked.clear(); - liked.clear(); -} \ No newline at end of file + data->disliked.clear(); + data->liked.clear(); +}