2022-04-13 15:31:57 +02:00
|
|
|
#ifndef ECOSYSTEME_ANIMAL_TEMPLATE_HPP
|
|
|
|
#define ECOSYSTEME_ANIMAL_TEMPLATE_HPP 1
|
|
|
|
|
2022-04-13 18:56:54 +02:00
|
|
|
// On regarde tout les organismes, dès qu'on trouve un organisme
|
|
|
|
// à l'index regardé, on vérifie qu'il correspond à l'espece que
|
|
|
|
// l'on recherche et qu'il est bien du genre opposé.
|
|
|
|
// Ensuite on l'ajoute si tout est bon au vecteur `animaux`
|
2022-04-13 15:31:57 +02:00
|
|
|
template<typename Espece>
|
|
|
|
void Animal::rechercheEspece(int i, std::vector<Espece *> &animaux) noexcept {
|
|
|
|
for(auto it: Univers::m_organismes_univers[m_univers_ID]) {
|
|
|
|
if(it->position().first == i) { // vérification index
|
|
|
|
if(auto animal = dynamic_cast<Espece *>(it)) { // vérification espece
|
|
|
|
if(genre != animal->genre) { // vérification genre
|
|
|
|
if(animal->m_partenaire == nullptr) { // animal pas déjà occupé
|
|
|
|
animaux.push_back(animal);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 18:56:54 +02:00
|
|
|
// Renvoie la liste des animaux environnants
|
2022-04-13 15:31:57 +02:00
|
|
|
template<typename Espece>
|
|
|
|
void Animal::animauxEnvirons(std::vector<Espece *> &animaux) noexcept {
|
|
|
|
int longueur_univers = Univers::m_dimensions_univers[m_univers_ID].first,
|
|
|
|
taille_max_univers = longueur_univers * Univers::m_dimensions_univers[m_univers_ID].second,
|
|
|
|
i;
|
|
|
|
|
|
|
|
// En haut à gauche
|
|
|
|
i = m_index - longueur_univers - 1;
|
|
|
|
if(i >= 0 && i % longueur_univers < longueur_univers - 1) {
|
|
|
|
rechercheEspece(i, animaux);
|
|
|
|
}
|
|
|
|
|
|
|
|
// En haut
|
|
|
|
i = m_index - longueur_univers;
|
|
|
|
if(i >= 0) {
|
|
|
|
rechercheEspece(i, animaux);
|
|
|
|
}
|
|
|
|
|
|
|
|
// En haut à droite
|
|
|
|
i = m_index - longueur_univers + 1;
|
|
|
|
if(i >= 0 && i % longueur_univers != 0) {
|
|
|
|
rechercheEspece(i, animaux);
|
|
|
|
}
|
|
|
|
|
|
|
|
// A gauche
|
|
|
|
i = m_index - 1;
|
|
|
|
if(i >= 0 && i % longueur_univers < longueur_univers - 1) {
|
|
|
|
rechercheEspece(i, animaux);
|
|
|
|
}
|
|
|
|
|
|
|
|
// A droite
|
|
|
|
i = m_index + 1;
|
|
|
|
if(i < taille_max_univers && i % longueur_univers != 0) {
|
|
|
|
rechercheEspece(i, animaux);
|
|
|
|
}
|
|
|
|
|
|
|
|
// En bas à gauche
|
|
|
|
i = m_index + longueur_univers - 1;
|
|
|
|
if(i < taille_max_univers && i % longueur_univers < longueur_univers - 1) {
|
|
|
|
rechercheEspece(i, animaux);
|
|
|
|
}
|
|
|
|
|
|
|
|
// En bas
|
|
|
|
i = m_index + longueur_univers;
|
|
|
|
if(i < taille_max_univers) {
|
|
|
|
rechercheEspece(i, animaux);
|
|
|
|
}
|
|
|
|
|
|
|
|
// En bas à droite
|
|
|
|
i = m_index + longueur_univers + 1;
|
|
|
|
if(i < taille_max_univers && i % longueur_univers != 0) {
|
|
|
|
rechercheEspece(i, animaux);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 18:56:54 +02:00
|
|
|
// Permet l'accouplement avec un autre animal
|
2022-04-13 15:44:54 +02:00
|
|
|
template<typename Espece>
|
|
|
|
void Animal::procreation(void) noexcept {
|
|
|
|
// Si l'animal est une femelle
|
|
|
|
if(genre == 1) {
|
|
|
|
std::random_device nombre_aleatoire;
|
|
|
|
std::default_random_engine graine(nombre_aleatoire());
|
|
|
|
|
|
|
|
if(m_reproduire == -1) { // si l'animal peut se reproduire
|
|
|
|
std::vector<Espece *> pretendants;
|
|
|
|
animauxEnvirons<Espece>(pretendants); // recuperation des animaux libre aux alentours
|
|
|
|
|
|
|
|
// S'il y a des prétendants
|
|
|
|
if(pretendants.size() > 0) {
|
|
|
|
// On choisit aléatoirement un prétendant
|
|
|
|
std::uniform_int_distribution<int> aleatoire_pretendant(0, pretendants.size() - 1);
|
|
|
|
Espece * partenaire = pretendants[static_cast<uint64_t>(aleatoire_pretendant(graine))];
|
|
|
|
|
|
|
|
m_partenaire = partenaire;
|
|
|
|
partenaire->m_partenaire = this;
|
|
|
|
|
|
|
|
m_reproduire = 1; // accouchement dans 1 tour
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(m_reproduire >= 0) { // si l'animal est déjà entrain de se reproduire
|
|
|
|
--m_reproduire;
|
|
|
|
if(m_reproduire == -1) { // si reproduction terminée
|
|
|
|
static_cast<Espece *>(m_partenaire)->m_partenaire = nullptr;
|
|
|
|
m_partenaire = nullptr;
|
|
|
|
|
2022-04-13 17:05:51 +02:00
|
|
|
std::vector<int> cases_possible_enfant = casesPossible();
|
2022-04-13 18:40:51 +02:00
|
|
|
if(!cases_possible_enfant.empty()) { // on vérifie qu'il y a de la place dans l'univers pour accueillir l'enfant
|
|
|
|
std::uniform_int_distribution<int> aleatoire_enfant(0, cases_possible_enfant.size() - 1);
|
2022-04-13 15:44:54 +02:00
|
|
|
|
2022-04-18 03:12:14 +02:00
|
|
|
auto enfant = new Espece(m_univers_ID, cases_possible_enfant[static_cast<uint64_t>(aleatoire_enfant(graine))]);
|
|
|
|
std::cout << "'" << lettre(ID) << "' (" << ID << "/" << coordoneeeEchequier() <<") fait naître '" << lettre(enfant->ID) << "' (" << enfant->ID << "/" << enfant->coordoneeeEchequier() << ")" << std::endl;
|
2022-04-13 18:40:51 +02:00
|
|
|
} // sinon il ne nait pas
|
2022-04-13 15:44:54 +02:00
|
|
|
|
|
|
|
m_reproduire -= m_attente_reproduction; // doit attendre avant de pouvoir se reproduire encore
|
|
|
|
} else {
|
|
|
|
if(m_reproduire == -1 - m_attente_reproduction) {
|
|
|
|
m_reproduire = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 15:31:57 +02:00
|
|
|
#endif
|