Ajouts et modifications

- Mort de l'organisme entraine directement la libération de sa position
- Les animaux sont désormais genrés (aléatoire)
- Reproduction des moutons
This commit is contained in:
Mylloon 2022-04-13 15:31:57 +02:00
parent bc6b87222c
commit 3b3159f3d3
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
9 changed files with 196 additions and 37 deletions

View file

@ -13,6 +13,13 @@
* fuira */
class Animal: public Organisme {
// 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`
template<typename Espece>
void rechercheEspece(int, std::vector<Espece *> &) noexcept;
protected:
const int m_age_max; // age maximale que peut atteindre l'organisme
@ -22,30 +29,44 @@ class Animal: public Organisme {
int m_age = 0; // age actuel de l'organisme
bool m_reproduire = true; // est-ce que l'animal peut se reproduire ?
// nombre de tour avant accouchement (-1 = quand pas enceinte)
short m_reproduire = -1;
// vrai si l'animal doit déposé des sédiment au sol à sa mort
Animal * m_partenaire = nullptr;
// Vrai si l'animal doit déposé des sédiment au sol à sa mort
bool m_deposer_sediment = true;
// Renvoie une vitesse aléatoire (+ élevé = + rapide)
virtual int generationVitesse(void) const noexcept = 0;
// Renvoie un genre choisit aléatoirement
int choixGenre(void) const noexcept;
// Renvoie la liste des cases accesible depuis la position de l'animal
std::vector<int> casesPossible(void) const noexcept;
// Renvoie la liste des animaux environnants
template<typename Espece>
void animauxEnvirons(std::vector<Espece *> &) noexcept;
const int genre; // genre, 0 = masculin, 1 = féminin
public:
const int vitesse; // vitesse de l'organisme
// ID de l'univers, age max, faim max, vitesse
Animal(int, int, int, int);
// ID de l'univers, index dans l'univers, age max, faim max, vitesse
// ID de l'univers, age max, faim max, vitesse, genre
Animal(int, int, int, int, int);
// ID de l'univers, index dans l'univers, age max, faim max, vitesse, genre
Animal(int, int, int, int, int, int);
~Animal(void);
// Animal carnivore ?
virtual bool carnivore(void) const noexcept = 0;
};
#include "animal_template.hpp" // définition du template
#endif

View file

@ -0,0 +1,75 @@
#ifndef ECOSYSTEME_ANIMAL_TEMPLATE_HPP
#define ECOSYSTEME_ANIMAL_TEMPLATE_HPP 1
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;
}
}
}
}
}
}
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);
}
}
#endif

View file

@ -6,6 +6,8 @@
class Mouton: public Animal {
const char _m_lettre = 'M'; // caractère représentant le mouton
const short m_attente_reproduction = 1;
// Défini la vitesse du mouton
int generationVitesse(void) const noexcept;

View file

@ -18,12 +18,14 @@ class Organisme {
int m_index; // Location dans l'univers
// Supprime l'organisme des vecteur (argument = type de l'organisme)
void suppresionVecteurs(bool = true) noexcept;
// Supprime l'organisme des vecteur
void suppresionVecteurs(void) noexcept;
public:
const int ID; // ID unique pour chaque organisme
const bool m_superposable; // Type de l'organisme
bool mort = false; // vrai si l'organisme est mort
// ID de l'Univers, type de l'organisme, index dans l'univers
@ -42,6 +44,9 @@ class Organisme {
// Renvoie les coordonées de l'organisme en format "echequier"
std::string coordoneeeEchequier(void) const noexcept;
// Fais mourir l'organisme en libérant sa position
void mortOrganisme(bool = true) noexcept;
};
#endif

View file

@ -1,19 +1,25 @@
#include "../includes/animal.hpp"
Animal::Animal(const int univers_ID, const int index, const int age_max,
const int faim_max, const int p_vitesse): Organisme(univers_ID, false, index),
m_age_max(age_max),
m_faim_max(faim_max),
vitesse(p_vitesse) { }
const int faim_max, const int p_vitesse, int p_genre): Organisme(univers_ID, false, index),
m_age_max(age_max), m_faim_max(faim_max),
genre(p_genre), vitesse(p_vitesse)
{ }
Animal::Animal(const int univers_ID, const int age_max,
const int faim_max, const int p_vitesse): Organisme(univers_ID, false),
m_age_max(age_max),
m_faim_max(faim_max),
vitesse(p_vitesse) { }
const int faim_max, const int p_vitesse, int p_genre): Organisme(univers_ID, false),
m_age_max(age_max), m_faim_max(faim_max),
genre(p_genre), vitesse(p_vitesse)
{ }
Animal::~Animal(void) {
suppresionVecteurs(false);
suppresionVecteurs();
// Si l'animal se reproduisait, on annule pour la mère
if(m_partenaire != nullptr) {
m_partenaire->m_partenaire = nullptr;
m_partenaire->m_reproduire = -1;
}
// Vérifie si l'ont doit déposé des sédiments
if(m_deposer_sediment) {
@ -122,3 +128,11 @@ std::vector<int> Animal::casesPossible(void) const noexcept {
return vec;
}
int Animal::choixGenre(void) const noexcept {
std::random_device nombre_aleatoire;
std::default_random_engine graine(nombre_aleatoire());
std::uniform_int_distribution<int> aleatoire(0, 1);
return aleatoire(graine);
}

View file

@ -1,10 +1,10 @@
#include "../includes/loup.hpp"
Loup::Loup(const int univers_ID): Animal(univers_ID, 60, 10, Loup::generationVitesse()) {
Loup::Loup(const int univers_ID): Animal(univers_ID, 60, 10, Loup::generationVitesse(), Loup::choixGenre()) {
m_correspondance[ID] = _m_lettre;
}
Loup::Loup(const int univers_ID, const int index): Animal(univers_ID, index, 60, 10, Loup::generationVitesse()) {
Loup::Loup(const int univers_ID, const int index): Animal(univers_ID, index, 60, 10, Loup::generationVitesse(), Loup::choixGenre()) {
m_correspondance[ID] = _m_lettre;
}
@ -37,7 +37,7 @@ void Loup::action(void) {
/* TODO */
if(m_age > m_age_max || m_faim > m_faim_max) { // meurt si trop vieux ou trop faim
mort = true;
mortOrganisme(m_superposable);
} else {
++m_age; // augmente l'âge
++m_faim; // augmente la faim

View file

@ -1,10 +1,10 @@
#include "../includes/mouton.hpp"
Mouton::Mouton(const int univers_ID): Animal(univers_ID, 50, 5, Mouton::generationVitesse()) {
Mouton::Mouton(const int univers_ID): Animal(univers_ID, 50, 5, Mouton::generationVitesse(), Mouton::choixGenre()) {
m_correspondance[ID] = _m_lettre;
}
Mouton::Mouton(const int univers_ID, const int index): Animal(univers_ID, index, 50, 5, Mouton::generationVitesse()) {
Mouton::Mouton(const int univers_ID, const int index): Animal(univers_ID, index, 50, 5, Mouton::generationVitesse(), Mouton::choixGenre()) {
m_correspondance[ID] = _m_lettre;
}
@ -32,18 +32,54 @@ void Mouton::action(void) {
for(auto organisme: Univers::m_organismes_univers[m_univers_ID]) { // regarde tout les organismes
if(organisme->position().first == m_index) { // si sur ma position
if(dynamic_cast<Herbe *>(organisme)) { // si c'est de l'herbe
organisme->mort = true;
organisme->mortOrganisme(organisme->m_superposable);;
m_faim = 0;
break;
}
}
}
// S'accouple si besoin
/* TODO */
// Si l'animal est une femelle
if(genre == 1) {
if(m_reproduire == -1) { // si l'animal peut se reproduire
std::vector<Mouton *> pretendants;
animauxEnvirons<Mouton>(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);
Mouton * 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<Mouton *>(m_partenaire)->m_partenaire = nullptr;
m_partenaire = nullptr;
std::vector<int> cases_possible_enfant = this->casesPossible();
std::uniform_int_distribution<int> aleatoire_enfant(0, cases_possible_enfant.size() - 1);
new Mouton(m_univers_ID, cases_possible_enfant[static_cast<uint64_t>(aleatoire_enfant(graine))]);
m_reproduire -= m_attente_reproduction; // doit attendre avant de pouvoir se reproduire encore
} else {
if(m_reproduire == -1 - m_attente_reproduction) {
m_reproduire = -1;
}
}
}
}
}
if(m_age > m_age_max || m_faim > m_faim_max) { // meurt si trop vieux ou trop faim
mort = true;
mortOrganisme(m_superposable);
} else {
++m_age; // augmente l'âge
++m_faim; // augmente la faim

View file

@ -3,7 +3,8 @@
// organisme.hpp, donc si on importe univers.hpp dans organisme.hpp
// alors univers.hpp ne pourra pas s'initalisé correctement
Organisme::Organisme(const int univers_ID, const bool superposable, const int index): m_univers_ID(univers_ID), m_index(index), ID(m_total_ID + 1) {
Organisme::Organisme(const int univers_ID, const bool superposable, const int index): m_univers_ID(univers_ID), m_index(index),
ID(m_total_ID + 1), m_superposable(superposable) {
// S'il n'y a plus d'index de libres
if(superposable) {
if(Univers::m_index_libres_univers[m_univers_ID].first.size() == 0) {
@ -67,15 +68,7 @@ std::string Organisme::coordoneeeEchequier(void) const noexcept {
return y + std::to_string(x);
}
void Organisme::suppresionVecteurs(const bool type) noexcept {
// On se supprime du vecteur
auto debut = Univers::m_organismes_univers[m_univers_ID].begin();
auto fin = Univers::m_organismes_univers[m_univers_ID].end();
auto it = std::find(debut, fin, this);
if(it != fin) {
Univers::m_organismes_univers[m_univers_ID].erase(it);
}
void Organisme::mortOrganisme(const bool type) noexcept {
// On remet notre index dans le vecteur des index vide
// puis on remélange notre vecteur
if(type) { // vecteur différent en fonction du type
@ -85,4 +78,17 @@ void Organisme::suppresionVecteurs(const bool type) noexcept {
Univers::m_index_libres_univers[m_univers_ID].second.push_back(m_index);
Univers::melange(&Univers::m_index_libres_univers[m_univers_ID].second);
}
// On déclare mort l'organisme
mort = true;
}
void Organisme::suppresionVecteurs(void) noexcept {
// On se supprime du vecteur
auto debut = Univers::m_organismes_univers[m_univers_ID].begin();
auto fin = Univers::m_organismes_univers[m_univers_ID].end();
auto it = std::find(debut, fin, this);
if(it != fin) {
Univers::m_organismes_univers[m_univers_ID].erase(it);
}
}

View file

@ -17,7 +17,7 @@ Sel::~Sel(void) {
void Sel::action(void) {
if(m_age == 1) { // devient de l'herbe au bout d'un tour
mort = true;
mortOrganisme(m_superposable);
} else {
++m_age;
}