#include <random>
#include <vector>
#include <string>
#include <fstream>
#include <algorithm>
#include <tuple>
#include <iomanip>

const unsigned int
  LENGTH = 70
, POPULATION = 20
, MUTATION = 1
;

struct Primate
{
	std::string dna, line;
	enum fingers
	{
		  lPinky, lRing, lMiddle, lIndex, lThumb
		, rThumb, rIndex, rMiddle, rRing, rPinky
	};

	double intelligence;
	bool best;	
};

struct Text
{
	std::vector<std::string> lines;
	unsigned int editions; // number of cycles
	int current_line;
};

struct Population
{
	bool better;
	int best, generations;
	double fitness_reference;
};

void log(std::vector<Primate>& monkeys, Text& book, Population& troop, int selector);
std::tuple<int, double, bool> decode(std::string& dna, int& idx);
char keyboard(int& first, double& second, bool& third);

void initialize(std::vector<Primate>& monkey, Text& book, Population& troop);
void restart(Text& book, Population& troop);
void reset(std::vector<Primate>& monkeys, Population& troop);

void evaluation(std::vector<Primate>& monkeys, Text& book, Population& troop, bool& next);
void selection(std::vector<Primate>& monkeys, Text& book, Population& troop);
void reproduction(std::vector<Primate>& monkeys);
void mutation(std::vector<Primate>& monkeys);