164 lines
2.9 KiB
C++
164 lines
2.9 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", (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;
|
|
}
|
|
} |