113 lines
2.4 KiB
C++
113 lines
2.4 KiB
C++
|
|
|
|
#include <unistd.h>
|
|
|
|
#include "values/DnaManager.hpp"
|
|
|
|
UiUnit DnaManager::next(DnaManagerData *data)
|
|
{
|
|
if (data->queued >= NUM_PER_GEN)
|
|
{
|
|
return {nullptr, Liked::tbd, -1};
|
|
}
|
|
|
|
Dna *ret = &data->vector[data->queued];
|
|
int index = data->queued++;
|
|
return {ret, Liked::tbd, index};
|
|
}
|
|
|
|
bool DnaManager::like(UiUnit unit, DnaManagerData *data)
|
|
{
|
|
int found = -1;
|
|
if (unit.index == data->showed)
|
|
{
|
|
found = data->showed;
|
|
}
|
|
|
|
if (found == -1)
|
|
{
|
|
// RUN OUT OF GEN WAITING FOR NEW GEN
|
|
return false;
|
|
}
|
|
if (unit.liked == Liked::yes)
|
|
{
|
|
data->liked.push_back(found);
|
|
}
|
|
else if (unit.liked == Liked::no)
|
|
{
|
|
data->disliked.push_back(found);
|
|
}
|
|
else
|
|
{
|
|
// could be infinite loop if something went wrong and user lost UiUnit and next is returning null thinking that it queued everiting
|
|
// maybe return true to move on and maybe tread Liked::tbd as Liked::no
|
|
return false;
|
|
}
|
|
|
|
data->showed++;
|
|
|
|
if (data->showed >= NUM_PER_GEN && data->queued >= NUM_PER_GEN) // if buffer was biger in the past showed could be more then NUM_PER_GEN so its changed to >= insted of ==
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void DnaManager::newGen(DnaManagerData *data)
|
|
{
|
|
data->queued = 0;
|
|
data->showed = 0;
|
|
data->generation += 1;
|
|
if (data->liked.size() == 0)
|
|
{
|
|
for (std::size_t i = 0; i < NUM_PER_GEN; i++)
|
|
{
|
|
DNA::newDna(&data->vector[i], &data->randSeed);
|
|
}
|
|
data->disliked.clear();
|
|
return;
|
|
}
|
|
|
|
if (data->liked.size() == 1)
|
|
{
|
|
int front = data->liked.front();
|
|
|
|
for (auto &&i : data->disliked)
|
|
{
|
|
DNA::clone(&data->vector[front], &data->vector[i], &data->randSeed);
|
|
}
|
|
|
|
data->disliked.clear();
|
|
data->liked.clear();
|
|
}
|
|
|
|
if (data->liked.size() >= 2)
|
|
{
|
|
for (auto &&i : data->disliked)
|
|
{
|
|
|
|
size_t p1 = mrand::getValue(0, data->liked.size() - 1, &data->randSeed);
|
|
size_t p2 = mrand::getValue(0, data->liked.size() - 1, &data->randSeed);
|
|
while (p1 == p2)
|
|
{
|
|
p2 = mrand::getValue(0, data->liked.size(), &data->randSeed);
|
|
}
|
|
|
|
p1 = data->liked[p1];
|
|
p2 = data->liked[p2];
|
|
Dna *p1p = &data->vector[p1];
|
|
Dna *p2p = &data->vector[p2];
|
|
Dna *c = &data->vector[i];
|
|
|
|
DNA::makeChild(p1p, p2p, c, &data->randSeed);
|
|
}
|
|
}
|
|
|
|
for (size_t i = 0; i < NUM_PER_GEN; i++)
|
|
{
|
|
DNA::mutate(&data->vector[i], NUM_OF_MUT, &data->randSeed);
|
|
}
|
|
data->disliked.clear();
|
|
data->liked.clear();
|
|
}
|