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 ;
2022-04-18 11:54:12 +02:00
std : : cout < < " Reproduction entre ' " < < lettre ( ID ) < < " ' ( " < < coordoneeeEchequier ( ) < < " ) et ' " < < lettre ( partenaire - > ID ) < < " ' ( " < < partenaire - > coordoneeeEchequier ( ) < < " ) " < < std : : endl ;
2022-04-13 15:44:54 +02:00
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