TD 4 • Arène asynchrone
Cartouche
| Champ | Valeur |
|---|---|
| Auteur·e | Élise |
| Édition | 2024-06-04 |
| Durée | 2 séances |
| Taille des équipes | 1~2 personnes login des auteur·rice·s dans author.txt, séparés par des retours à la ligne |
| Rendu | via git, dépôt 2023_morpion, branche td4, droits en lecture à delivery_collector |
Préambule
Notation
Introduction
Pour le moment, votre serveur est capable de faire tourner qu’une seule partie à la fois sur un seul fil d’exécution. Il arrive cependant à gérer deux clients/joueurs sans bloquer, ce qui signifie qu’il n’est pas impossible de faire tourner une partie sans bloquer, et à terme de faire tourner plusieurs parties sans qu’elles se bloquent les unes les autres.
C’est l’objectif de ce TD : faire tourner plusieurs parties en simultané sur un même fil d’exécution.
Pour ce faire, on va faire passer votre logique de jeu vers une classe distincte, ce que vous avez peut-être déjà fait et on va la rendre elle aussi non bloquante, là où aujourd’hui elle a probablement une boucle infinie tant que la partie qu’elle contient n’est pas finie, ou que personne ne s’est déconnecté.
Le but c’est de pouvoir avoir une boucle principale qui ressemble à ceci :
int main(void)
{
GfxPlayer gfx_player;
TermPlayer term_player;
GfxPlayer gfx_player2;
StandaloneNetPlayer net_player;
GameArena arena1{&gfx_player, &term_player};
GameArena arena2{&gfx_player2, &net_player};
while (!arena1.done() && !arena2.done()) {
arena1.cycle_once();
arena2.cycle_once();
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
Et à terme de pouvoir générer des arènes avec des NetPlayer au fur et a mesure des connections.
Implémentation : arène
Implémentez une classe GameArena dont le métier est de construire une MorpionGame, et de faire avancer et suivre l’avancement de la partie de deux joueurs (IPlayer).
Elle doit pouvoir être construite avec l’adresse ou la référence de deux IPlayer. À la construction elle doit envoyer l’état initial de la partie et l’ordre de jouer au premier joueur dont c’est le tour.
La classe doit avoir les fonctions membres suivantes :
class GameArena {
public:
GameArena(IPlayer &, IPlayer &);
// cycle once, process player events
// check if current player made a mode,
// check if players are still here
void cycle_once();
// while not done, call cycle_once in a loop
void run();
// if game is done or one player has left, returns 1
// otherwise when the game is running, returns 0
bool done() const;
private:
// [the fields you need for the logic of the class]
};
Génération de parties
Pour reprendre le travail de TD 3 • StandaloneNetPlayer et client.
Adaptez votre serveur pour qu’il ai le comportement suivant :
- en argument il reçoit un nombre de partie à héberger ;
- il attend la création de 2
StandaloneNetPlayerpar partie demandée ; - il crée une
GameArenapar partie, dans laquelle il met 2StandaloneNetPlayer; - il exécute en boucle la fonction
run_oncede toutes les parties créées jusqu’à ce qu’elles soient toutes done.