208 lines
3.8 KiB
C++
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);
|
|
}
|
|
} |