diplomska_naloga/src/values/DnaManager.cpp

208 lines
3.8 KiB
C++

#include <ctime>
#include <stdio.h>
#include <unistd.h>
#include "values/DnaManager.hpp"
#include "sys.hpp"
#include <raylib.h>
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);
}
}