#include #include #include #include "values/DnaManager.hpp" #include "sys.hpp" #include void DnaManager::init() { if (sys::fileExists("id")) { sys::loadDataFromFile("id", &id, sizeof(uint128)); } else { id = mrand::getState(time(nullptr)); sys::saveDataToFile("id", &id, sizeof(uint128)); } if (sys::fileExists("data")) { const char *filename = sys::transformFilePath("data"); 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); liked.push_back(tmp); } fread(&size, sizeof(size), 1, file); for (int i = 0; i < size; i++) { fread(&tmp, sizeof(tmp), 1, file); disliked.push_back(tmp); } fclose(file); } else { randSeed = id; queued = 0; showed = 0; generation = 0; } vector.resize(NUM_PER_GEN); if (sys::fileExists("array")) { sys::loadDataFromFile("array", vector.data(), sizeof(Dna) * NUM_PER_GEN); } else { for (std::size_t i = 0; i < NUM_PER_GEN; i++) { DNA::newDna(&vector[i], &randSeed); } } } void DnaManager::deinit() { } void DnaManager::saveData() { const char *filename = sys::transformFilePath("data"); 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("array"); FILE *file = fopen(filename, "wb"); if (file == NULL) return; fwrite(vector.data(), sizeof(Dna) * NUM_PER_GEN, 1, file); fclose(file); } Unit DnaManager::next() { Dna *ret = &vector[queued]; int index = queued++; return {ret, Liked::tbd, index}; } void DnaManager::like(Unit unit) { int found = -1; if (unit.index == showed) { found = showed; } 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++; if (showed == NUM_PER_GEN && queued == NUM_PER_GEN) { newGen(); queued = 0; showed = 0; generation += 1; saveVec(); } saveData(); } void DnaManager::newGen() { if (liked.size() == 0) { for (std::size_t i = 0; i < NUM_PER_GEN; i++) { DNA::newDna(&vector[i], &randSeed); } disliked.clear(); return; } if (liked.size() == 1) { int front = liked.front(); for (auto &&i : disliked) { DNA::clone(&vector[front], &vector[i], &randSeed); } disliked.clear(); liked.clear(); } 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); } } for (size_t i = 0; i < NUM_PER_GEN; i++) { DNA::mutate(&vector[i], NUM_OF_MUT, &randSeed); } }