#include #include #include #include "values/DnaManager.hpp" #include "sys.hpp" #include void DnaManager::init() { if (sys::fileExists("id")) { sys::loadDataFromFile("id", (char *)&id, sizeof(uint128)); } else { id = mrand::getState(time(nullptr)); sys::saveDataToFile("id", (const char *)&id, sizeof(uint128)); } if (sys::fileExists("data")) { const char *filename = sys::transformFilePath("data"); FILE *file = fopen(filename, "rb"); if (file == NULL) return; size_t ret = fread(&randSeed, 1, sizeof(uint128), file); fclose(file); } else { randSeed = id; } vector.resize(NUM_PER_GEN); for (std::size_t i = 0; i < NUM_PER_GEN; i++) { DNA::newDna(&vector[i], &randSeed); queued.push_back(i); } } void DnaManager::deinit() { const char *filename = sys::transformFilePath("data"); FILE *file = fopen(filename, "wb"); if (file == NULL) return; size_t ret = fwrite(&randSeed, 1, sizeof(uint128), file); fclose(file); } Unit DnaManager::next() { int index = queued.front(); queued.pop_front(); showed.push_back(index); Dna *ret = &vector[index]; return {ret, Liked::tbd}; } void DnaManager::like(Unit unit) { int found = -1; for (auto &&i : showed) { if (&vector[i] == unit.dna) found = i; } if (found == -1) { TraceLog(LOG_ERROR, "NOT FOUND UNIT"); return; } if (unit.liked == Liked::yes) { liked.push_back(found); } else if (unit.liked == Liked::no) { disliked.push_back(found); } else { TraceLog(LOG_ERROR, "LIKED WITH NO VAULE"); return; } showed.remove(found); if (showed.size() == 0 && queued.size() == 0) { newGen(); } } void DnaManager::newGen() { if (liked.size() == 0) { for (std::size_t i = 0; i < NUM_PER_GEN; i++) { DNA::newDna(&vector[i], &randSeed); queued.push_back(i); } disliked.clear(); return; } for (auto &&i : liked) { queued.push_back(i); } if (liked.size() == 1) { int front = liked.front(); for (auto &&i : disliked) { DNA::clone(&vector[front], &vector[i], &randSeed); queued.push_back(i); } disliked.clear(); liked.clear(); return; } if (liked.size() >= 2) { for (auto &&i : disliked) { size_t p1 = mrand::getValue(0, liked.size() - 1, &randSeed); size_t p2 = mrand::getValue(0, liked.size() - 1, &randSeed); while (p1 == p2) { p2 = mrand::getValue(0, liked.size(), &randSeed); } p1 = liked[p1]; p2 = liked[p2]; Dna *p1p = &vector[p1]; Dna *p2p = &vector[p2]; Dna *c = &vector[i]; DNA::makeChild(p1p, p2p, c, &randSeed); queued.push_back(i); } } if (queued.size() == NUM_PER_GEN) { for (auto &&i : queued) { DNA::mutate(&vector[i], NUM_OF_MUT, &randSeed); } return; } }