TD 3 • StandaloneNetPlayer et client
Cartouche
| Champ | Valeur |
|---|---|
| Auteur·e | Élise |
| Édition | 2024-05-15 |
| 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 td3, droits en lecture à delivery_collector |
Préambule
Notation
- Protocole : 6 points
StandaloneNetPlayer: 7 points- Client : 7 points
Un rendu sale et du code qui ne respecte pas la norme peut vous faire perdre une partie ou la totalité des points acquis.
Introduction
Maintenant que vous avez de quoi gérer de l’asynchrone sur vos joueurs d’une partie en cours et un client graphique asynchrone : on va se concentrer sur le fait d’avoir un joueur sur le réseau.
Votre travail va porter sur :
- quelles données transmettre sur le réseau côté client et côté serveur ;
- l’initialisation côté serveur d’un joueur réseau (avec l’attente de la connexion d’un joueur distant) ;
- l’initialisation côté client, connexion a un serveur ;
- la boucle principale côté client qui :
- regarde si un message est reçu du serveur, l’interprête et passe l’info à un GfxPlayer,
- regarde si le GfxPlayer à fait un move (si on en attendait un) ou s’il a quitté (pour savoir s’il faut fermer la connexion et arrêter le client).
Protocole
Associez à chaque fonction membre de IPlayer un message textuel que vous ferez transiter sur le réseau pour la communication client serveur.
Exemple pour une demande de move suivie d’une réponse du client :
- Server:
ASK_MOVE X - Client:
MOVE 6
Implémentation StandaloneNetPlayer
Côté serveur on va commencer par essayer de gérer un seul client à distance en écrivant une classe qui :
- à la construction listen sur un port et accepte un seul client
- on avait vu comment faire ça dans TP 2 • SFML Network
- une fois la socket acceptée, on peut la conserver elle et détruire le listener.
- implémente votre
IPLayerset_win,set_draw,ask_for_move(ou équivalent), etc. envoient un message sur la socketprocess_events(ou équivalent) vérifie si un message a été reçu, si un move était attendu : stocke le move dans un champ de la classe ;get_move(ou équivalent) renvoie un move si il y en a un qui était attendu et qu’il a été set parprocess_events
Une fois cette classe écrite, vous deviez pouvoir jouer avec un client graphique et en vous connectant avec netcat -N 127.0.0.1 [votre port d'écoute].
Implémentation Client
Pour le côté client on ne va pas créer un deuxième projet : au lancement du programme morpion vous allez ajouter la possibilité de choisir si on veut lancer un serveur, un client ou juste une partie en locale avec deux clients graphiques. Vous êtes libres de l’implémentation, vous devez documenter dans votre readme.md comment utiliser un mode ou un autre.
Pour le mode client, vous allez utiliser .connect sur une sf::TcpSocket pour vous connecter au serveur. Vous allez aussi instancier un GfxPlayer. Une fois connectés vous devez avoir une boucle d’exécution qui ressemble à ceci :
- vérifiez si un message est disponible sur la socket, si oui :
- parsez-le et appelez la fonction membre
GfxPlayerqui correspond à la commande reçu (set_board,ask_for_move, etc.)
- parsez-le et appelez la fonction membre
process_events(ou équivalent) sur leGfxPlayer:- si la fenêtre est fermée, arrêtez le client
- si un move était attendu
get_movepour voir si un move a été fait :- si oui, générez le message qui correspond et envoyez-le sur la socket