Contrôle Final 1 – Année 2021/2022
- Durée du CF: 2h
- Tous les documents sont autorisés
- Vous avez à votre disposition le code des fichiers server_code_etudiant.h, server_code_etudiant.c et Makefile.
Echauffement (3 points)
1 point
maj_to_min
2 points
frame 2 puis p buff_in (ou print buff_in)
Motus (12 points)
Le but de cet exercice est d'ajouter une dimension ludique à la chatroom étudiée lors du cours intégré 10 en y intégrant le jeu Motus (ou Wordle). Les règles du jeu sont simples:
- Au démarrage de la partie (lorsque la commande /motus est saisie par un joueur), un mot de 7 lettres est choisi au hasard dans un dictionnaire, par exemple INITIEE. Il s'agit du mot_a_trouver.
- Les joueurs peuvent proposer avec la commande /unmot des mots de 7 lettres appelés mot_propose (par exemple: INTERNE) pour deviner le mot_a_trouver;
- Chacune des 7 lettres du mot_propose est comparée à la lettre placée à la même position dans mot_a_trouver:
- Si la ième lettre du mot_propose est la même que la ième lettre de mot_a_trouver, le serveur affiche la lettre en majuscule;
- Si la ième lettre du mot_propose apparaît à une autre position dans mot_a_trouver, le serveur affiche la lettre en minuscule;
- Si la ième lettre du mot_propose n'apparaît pas dans mot_a_trouver, le serveur affiche un tiret (-) à la place.
Par exemple, si le mot_a_trouver est INITIEE et qu'un joueur propose INTERNE, le serveur affiche INte-nE:
- I est correctement positionné;
- N est correctement positionné;
- t n'est pas en 3ème position du mot_a_trouver, mais apparaît ailleurs (en 4ème position);
- e n'est pas en 4ème position du mot_a_trouver, mais apparaît ailleurs (en 6ème position);
- r n'apparaît pas dans le mot_a_trouver et est donc remplacé par -;
- n n'est pas en 6ème position du mot_a_trouver, mais apparaît ailleurs (en 2ème position);
- E est correctement positionné;
La partie s'achève lorsqu'un joueur propose le mot_a_trouver. Voici un exemple de déroulement d'une partie:
2 points
Dans un premier temps, il est nécessaire de générer un fichier contenant tous les mots valides. On suppose qu'on dispose d'un script generate.sh nom_fichier qui crée le fichier nom_fichier.
Quelles modifications faut-il apporter au fichier Makefile pour que la commande make gènère le fichier word_list.dat s'il n'existe pas ?
5 points
- Calcul de la taille du fichier: 2 points
- Lecture du mot: 2 points
- Ouverture/fermeture du fichier: 1 point
2 points
Implémentez la fonction void process_cmd_motus(client_t* client, char *param);. Cette fonction, qui est appelée lorsqu'un client lance la commande /motus, doit appeler la fonction get_random_word et stocker le résultat dans la variable globale mot_a_trouver. La fonction crée ensuite la chaîne de caractères mot_masque qui contient WORD_LEN caractères: la première lettre du mot_a_trouver suivie de tirets ('-'). Enfin, la fonction envoie un message à tous, par exemple:
On considère que la variable globale mot_a_trouver a été déclarée de cette façon:
On considère que dans handle_incoming_cmd(), le code suivant a été ajouté:
- Appel à get_random_word: 0.5 pt
- Création du mot_masque: 1 pt
- Envoi du message: 0.5 pt
3 points
Implémentez la fonction static int comparer_mots(char mot_propose[WORD_LEN+1], char mot_masque[WORD_LEN+1]).
Cette fonction, qui est appelée lorsqu'un client lance la commande /unmot motproposé, doit comparer les lettres du mot_propose avec les lettres du mot_a_trouver. La fonction rempli mot_masque, et indique, pour chaque lettre du mot_propose:
- si elle est correctement placée. Dans ce cas, la lettre est écrite en majuscule dans mot_masque;
- si elle incorrectement placée (c'est à dire que la lettre apparait dans mot_a_trouver, mais à une autre position), la lettre est écrite en minuscule dans mot_masque;
- si elle n'est pas présente dans mot_a_trouver, la lettre est remplacée par le caractère '-' dans mot_masque.
- 2.5 points pour l'algo général
- 0.5 point pour le '\0' final
Leaderboard (8 points)
On souhaite maintenant pouvoir afficher un classement des meilleurs joueurs de MOTUS. Lorsqu'un joueur devine le mot_a_trouver, il gagne 100 points.
Pour gérer ce classement, il vous est demandé d'implémenter une liste chaînée des joueurs triée par score. Ainsi le joueur ayant le score le plus élevé est stocké au début de la liste, le second du classement est en deuxième position, etc.
La liste leaderboard est définie comme suit:
3 points
Implémentez la fonction void process_cmd_classement(client_t* client, char*param);. Cette fonction, qui est appelée lorsqu'un client lance la commande /classement, doit parcourir la liste chaînée leaderboard et envoyer à tous les clients le classement. Par exemple:
- Parcours de la liste: 2 points
- Affichage correct: 1 point
On considère que dans handle_incoming_cmd(), le code suivant a été ajouté:
5 points
Lorsqu'un joueur trouve le mot_a_trouver, il marque 100 points et le classement doit être mis à jour. Pour cela, implémentez la fonction void add_points(client_t* client, int nb_points). Cette fonction est appelée par process_cmd_unmot. Le paramètre client est le client auquel il fait ajouter nb_points points.
Implémentez la fonction add_points en suivant l'algorithme suivant:
- Rechercher le struct joueur correspondant à client dans la liste leaderboard, et l'enlever de la liste chaînée.
- Si le joueur était présent dans la liste, ajouter nb_points à son score;
- Sinon, allouer un struct joueur et l'initialiser.
- Insérer le struct joueur dans la liste chaînée leaderboard. La liste doit rester triée par score descendant (le score le plus élévé en début de liste)
- recherche/suppression du joueur: 2 points
- allocation/modification du score: 1 point
- Insertion dans la liste: 2 points