Buts: Introduire un nouveau type de bactéries se déplaçant en groupe.
Le nouveau type de bactéries à coder à cette étape est caractérisé essentiellement par un mode de déplacement spécifique (en groupe) : la bactérie se rapprochant le plus de sources de nutriments exercera une force d'attraction sur les autres. Il s'agit donc d'un exemple où une force régissant le déplacement n'est pas le vecteur nul !
Il vous est demandé ici de:
Les bactéries de déplaçant en groupe seront représentées au moyen d'une classe générique GroupMotilityBacterium. Chacune d'elle appartiendra à un groupe (BacteriaGroup).
Il pourra y avoir plusieurs groupes dans une boite de culture. La différence entre un groupe et l'autre se fera au niveau:
Commençons par modéliser plus précisément la notion de groupe.
Un groupe BacteriaGroup sera simplement caractérisé par :
Un BacteriaGroup sera un objet simulable dont la méthode update a pour rôle de mettre à jour la bactérie « leader » à chaque pas de simulation. Un BacteriaGroup n'est pas dessinable en tant que tel.
[Question Q4.11] : Une boite de culture contiendra désormais aussi des BacteriaGroup qu'elle doit faire évoluer. Sachant que nous souhaitons disposer d'une fonctionnalité Laboratory::addSwarm ajoutant un BacteriaGroup (vide de bactéries) dans chacune des boites de culture et invocable comme suit:
getEnv().addSwarm(id)); // id est la chaîne de caractères identifiant du groupeQuelle(s) modification(s) faites-vous et à quelle(s) classe(s) pour intégrer cela ?
Répondez à cette question dans votre fichier REPONSES et implémentez ces modifications.
Les fonctionnalités qu'il est raisonnable d'anticiper pour la BacteriaGroup sont :
Libre à vous d'ajouter d'autres méthodes si cela s'avère nécessaire.
Complétons maintenant la classe GroupMotilityBacterium ébauchée précédemment. Une GroupMotilityBacterium est une Bacterium (elle a toutes les caractéristiques génériques des bactéries). On considère pour simplifier qu'elle a connaissance du BacteriaGroup auquel elle appartient.
[Question Q4.12] : Une GroupMotilityBacterium doit disposer d'une force régissant son déplacement, exactement comme les bactéries simples. Quels liens mettez-vous en place pour modéliser cette force ?
Répondez à cette question dans votrte fichier REPONSES et codez la coquille vide de la classe GroupMotilityBacterium en mettant en place ces liens d'héritage.
Une GroupMotilityBacterium se divise comme une Bacterium, mais doit produire une GroupMotilityBacterium (appartenant au même groupe que la bactérie d'origine).
Finalement, pour simplifier, les GroupMotilityBacterium n'ont pas d'autres caractéristiques mutables que leur couleur.
[Question Q4.13] Au vu de ce qui précède, quelles méthodes déjà présentes dans la hiérarchie de classes des bactéries devrez-vous impérativement redéfinir dans GroupMotilityBacterium ?
Répondez à cette question dans votre fichier REPONSES.
Une GroupMotilityBacterium sera dessinée comme une Bacterium. S'il s'agit du « leader », faites aussi en sorte qu'en mode «debug» (fonctionnalité isDebugOn de Application.hpp), un anneau rouge se dessine autour d'elle (voir les vidéos ci-dessous).
Le constructeur d'une GroupMotilityBacterium prendra en paramètre sa position et un pointeur sur le BacteriaGroup auquel elle doit appartenir.
Le constructeur sera en charge d'ajouter la bactérie à son BacteriaGroup.
[Question Q4.14] Si vous examinez la méthode onEvent dans l'exemple de programme précédent, vous verrez que le placement d'une GroupMotilityBacterium nécessite de recourir à l'appel getEnv().addBacteriumToSwarm(id, const Vec2d& position);. Cette dernière a pour but d'ajouter une GroupMotilityBacterium à la boite courante en l'intégrant au groupe d'identificateur id de cette boite. Que devez-vous ajouter à votre code et où pour mettre en place cette fonctionnalité ?
[Question Q4.15] Une GroupMotilityBacterium est donc ajoutée à la boite comme toutes les autres (elle fait partie de la collection de bactéries de la boite). Le destructeur de BacteriaGroup doit-il faire quelque chose selon vous ?
[Question Q4.16] Lorsqu'une GroupMotilityBacterium meurt, elle ne doit plus être recensée dans son BacteriaGroup. Que devez-vous ajoutez à votre code et où pour que cette contrainte soit respectée ?
Répondez à ces questions dans votre fichier REPONSES en justifiant vos choix.
En vous inspirant de ce que vous avez fait jusqu'ici pour les autres bactéries et en tenant compte de la description faite ci-dessus, complétez toutes les fonctionnalités des BacteriaGroup hormis celle liée au déplacement (méthode move).
Pour tester cette partie, vous pouvez utiliser le test fourni GraphicalTests/GroupMotilityTest.cpp qui peut être lancé au moyen de la cible groupMotilityTest (que vous aurez pris soin de décommenter dans le fichier CMakeLists.txt).
Ce test vous permet de créer des bactéries avec comportement de groupe au moyen des touches '1' à '3'.
Lorsqu'une première source de nutriments apparaît, créez une bactérie, au moyen de la touche '1' par exemple, en la positionnant sur la source de nutriments. Cette bactérie devrait d'emblée apparaître comme étant le « leader » et commencer à se nourrir.
Créez d'autres bactéries du même BacteriaGroup (en utilisant toujours la même touche) sur d'autres sources de nutriments. Vous devriez pouvoir aussi observer des changements de « leadership » en fonction de la proximité des sources de nutriments ainsi que des phénomènes de division et de mutation de la couleur.
| ← Ici c'est d'abord la touche 1 qui est utilisée (bactéries vertes) puis la 2. Le changement de «leadership» en fonction de la proximité des nutriments doit être visible. Des changements de couleurs sont observables suite aux divisions (favorisées par la création préalable de nutriments en abondance). |
La méthode move se codera de façon analogue à ce que vous avez fait dans MonotrichousBacterium.
Les différences résideront dans les deux points suivants:
Pour tester cette partie, vous pouvez utiliser le même test que précédemment.
Ce test vous permet de créer des bactéries avec comportement de groupe au moyen des touches '1' à '2'.
Retardez la génération des nutriments en jouant sur le paramètre ["generator"] ["nutriment delay"], puis :
Vous devriez pouvoir aussi observer des changements de « leadership » en fonction de la proximité des sources de nutriments ainsi que tous les autres comportement attendus (disparition, division, mutation de la couleur etc.)
| ← Ici c'est d'abord la touche 1 qui est utilisée (bactéries vertes) puis la 2. La simulation est ralentie, avec relativement peu de nutriments, pour permettre de mieux observer la dynamique des déplacements. Avec des conditions plus rapides et d'avantages de nutriments, les divisions devraient être observables, comme dans la vidéo précédente. |
Vous avez appris récemment que les destructeurs doivent être virtuels en cas d'utilisation polymorphique.
Re-examinez les destructeurs existants dans votre code à la lumière de ce conseil (si vous ne voyez pas l'utilité de la chose posez nous des questions ;-))