Buts: Il s'agit ici d'introduire un nouveau type de bactéries se déplaçant au moyen d'un grappin.
Le grappin de ce nouveau type de bactéries, nommées PilusMediatedBacterium, impactera sa façon :
en plus de percevoir le gradient de nutriments, la bactérie pourra étendre son grappin dans une direction aléatoire. Si le grappin touche une source de nutriments il va se rétracter en entraînant dans son mouvement la bactérie (qui atteindra ainsi la source en question). Le codage de la méthode de déplacement sera le point le plus complexe de cette partie et des indications vous seront données plus bas.
l'extension du grappin (en quête de nourriture) a un coût énergétique pour la bactérie.
la longueur maximale du grappin et sa vitesse d'extension feront partie des paramètres mutables de la bactérie.
Une bactérie à grappin se divisera d'une façon analogue à une bactérie à flagelle unique; mais la division devra bien sûr produire une PilusMediatedBacterium. Il est recommandé de décaler un peu le clone et de diriger son grappin différemment pour une meilleure observation du clonage.
[Question Q4.6] Quel(s) lien(s) d'héritage proposez-vous de mettre en place pour intégrer les PilusMediatedBacterium à l'architecture existante ?
[Question Q4.7] En vous inspirant de ce que vous avez fait pour les bactéries à flagelle unique, et en observant le contenu du fichier de configuration app.json, comment proposez-vous d'accéder aux paramètres caractérisant ce type de bactéries (comme la longueur maximale de son grappin ou sa vitesse d'extension) ?
[Question Q4.8] Quelles méthodes déjà présentes dans la hiérarchie de classes des bactéries devrez-vous impérativement redéfinir dans PilusMediatedBacterium ?
Répondez à ces questions et justifiez vos choix dans votre fichier REPONSES.
Enfin, une PilusMediatedBacterium aura deux façons de perdre de l'énergie : en se déplaçant ou en déployant son grappin.
[Question Q4.9] Les facteurs de déperdition d'énergie permettant le calcul de la perte d'énergie dans chaque cas sont donnés par les valeurs associées à ["energy"]["consumption factor"]["move"] et ["energy"]["consumption factor"]["tentacle"] dans le fichier de configuration. Quel «getters» proposez-vous d'ajouter/redéfinir à/dans votre classe pour retrouver ces valeurs lorsque nécessaires ?
Répondez à cette question et justifiez vos choix dans votre fichier REPONSES
Programmez la classe PilusMediatedBacterium en utilisant les questions / réponses précédentes.
Vous laisserez vide ce qui touche au déplacement (méthode move) tout en l'anticipant, et commencerez par dessiner la bactérie comme une MonotrichousBacterium (mais sans duplication de code !).
Le constructeur de cette classe sera codé de façon analogue à celui des bactéries à flagelle unique (avec la position de la bactérie comme seul paramètre), il devra bien sûr s'adapter aux paramètres de configuration liés à "pilus mediated" dans le fichier de configuration.
La longueur maximale du grappin et sa vitesse seront consignés comme des paramètres mutables de type valeur numérique mutable positive (inspirez-vous directement de ce que vous avez fait pour les bactéries à flagelle unique au moment de leurs constructions).
Pour modéliser le grappin, il suffit d'en modéliser l'extrêmité. C'est en effet le seul point qui nous intéresse puisqu'il va permettre à la bactérie de « s'aggriper » à des sources de nutriments.
Nous vous proposons donc d'implémenter une petite classe utilitaire Grip modélisant le grapin du grappin (c'est à dire l'extremité lui permettant de s'aggriper).
Un grapin sera construit au moyen d'une position et d'un rayon passé en paramètre.
La seule méthode utile à priori pour un grapin est une méthode permettant d'en déplacer la position (rappelez-vous de CircularBody::move).
Le grapin doit enfin bien sûr devenir un attribut de la bactérie à grappin.
Complétez votre code de sorte à l'y intégrer. Vous ajouterez à la classe PilusMediatedBacterium une méthode utilitaire void moveGrip(const Vec2d& delta) permettant de déplacer la position de son grapin.
Un bactérie à grappin se dessine jusqu'ici comme un simple cercle. Il s'agit maintenant d'ajouter à cette représentation, le dessin du grappin.
Il suffit pour cela de tracer un segment de droite entre la position de la bactérie et la position du grapin et de dessiner le grapin comme un petit cercle.
Pour dessiner un segment de droite avec SFML, vous pouvez utiliser la fonction utilitaire buildLine fournie dans src/Utility/Utility.hpp :
auto line = buildLine(position1, position2, couleur, epaisseur); target.draw(line);où position1 et position2 sont les deux extrémités du segment, couleur une couleur SFML et epaisseur l'épaisseur du trait (1 par exemple).
Pour tester le code développé jusqu'ici vous pouvez utiliser le test fourni GraphicalTest/GripTest.cpp et qui peut être lancé au moyen de la cible gripTest (que vous aurez pris soin de décommenter dans le fichier CMakeLists.txt) .
Comme les bactéries à grappin ne peuvent pas encore se déplacer, il faut les créer à des endroits favorables à leur survie!
Laissez donc une source de nutriments se développer puis créez dessus une bactérie à grappin au moyen de la touche 'P'.
Vous devriez voir apparaître une bactérie avec un grappin déjà déployé (uniquement dans le cas de ce test car à sa création une bactérie doit normalement avoir un grappin rétracté : pour les curieux, regardez comment fonctionne le test fourni).
Vous devriez voir la bactérie se nourrir, se diviser et muter (sur sa couleur). La bactérie issue de la division ne doit pas avoir de grappin déployé.
| ←Libre à vous de jouer sur les paramètre du app.json opur rendre la division plus ou moins probable |
Le mouvement d'une bactérie à grappin est un processus qui peut être modélisé par ce que l’on appelle un automate à état finis et dont voici une représentation graphique :
Ce graphique signifie que la bactérie se trouve au cours de son fonctionnement dans différents états (IDLE, DEPLOY etc.), que chaque état va nécessiter d’entreprendre un certain nombre d’actions et que la transition d’un état à un autre peut être déclenchée par un certain nombre d’événements.
La table ci-dessous complète la description de l'automate en décrivant les actions à entreprendre dans chaque état :
| Etat | Description | Actions |
| IDLE (la bactérie est dans cet état lors de sa création) |
Grappin au repos | Rien de particulier (juste passage à l'état suivant). |
| WAIT_TO_DEPLOY | Grappin se préparant au déploiement |
|
| DEPLOY | Grappin se déployant |
|
| ATTRACT | Grappin attirant la bactérie vers la nourriture |
|
| RETRACT | Grappin se rétractant |
|
| EAT | Bactérie en train de consommer de la nourriture |
|
[Question Q4.10] Un type énuméré peut être une bonne solution pour répertorier les différents états cités plus haut. Comment proposeriez-vous d'en utiliser un pour mettre en oeuvre l'algorithme de mouvement ?
Répondez à cette question dans votre fichier REPONSES.
Complétez la méthode move implémentant l'automate à état fini décrit ci-dessus.
Pour tester cette partie, vous pouvez utiliser le test fourni GraphicalTests/PilusMediatedTest.cpp qui peut être lancé au moyen de la cible pilusMediatedTest (que vous aurez pris soin de décommenter dans le fichier CMakeLists.txt) .
Ce test vous permet de créer des bactéries à grappin au moyen de la touche 'P'.
Retardez la génération des nutriments en jouant sur le paramètre ["generator"] ["nutriment delay"] et créez une ou plusieurs bactéries dans une assiette sans nutriments, proches des bords de la boite. Vous devriez pouvoir observer le fait que :
| ←Libre à vous de jouer sur les paramètre du app.json pour expérimenter différents paramètres liés aux bactéries à grappin |