diff --git a/README.md b/README.md index e7f3c2d..c0089a2 100644 --- a/README.md +++ b/README.md @@ -1 +1,59 @@ # TP Langage C +![tpcoureur](/img/tp.png) + +[![doxygen](/img/doxygen.png)](https://etheryo.fr/insa/tpcoureur/index.html) +## Introduction +Le programme tpcoureur fonctionne de manière aléatoire. + +A chaque lancement du programme les coureurs sont lu à partir du fichier +[fichier_coureur.txt](fichier_coureurs.txt). Ces derniers vont être ensuite mis dans une liste, dans le même ordre que donné par le fichier. Ce fichier possède une convention particulière, soit : +> `1` Nombre d'étapes\ +`1` Nombre d'équipe\ +`x` Nom de l'équipe *x* +>>`5x` N° de dossard, Nom, `d'un coureur de l'équipe x`\ +... + +Les variables définies +> `TEMPSMAX` Temps maximum qu'un coureur peut avoir\ +`TEMPSMIN` Temps minimum qu'un coureur peut avoir\ +`TEMPSDOP` Temps pour les joueurs dopés *(Inférieur à `TEMPSMIN`)*\ + +Chaque calcul de temps est randomisé selon ces variables. Elles peuvent être changées pour avoir des temps finaux différents. Mais surtout change la chance qu'un joueur soit dopé. + +Le programme va tout d'abord supprimer les coureurs dopés et trier avec l'algorithme du [tri bulle][bullewiki] dans l'ordre croissant. Il va ensuite afficher les équipes éliminées : une équipe est éliminée si elle possède moins de `3 joueurs`. Et enfin elle affiche le classement final des **équipes uniquement**, seuls les temps des 3 meilleurs coureurs sont comptés. + +En premier lieu les différents participants sont affichés : + +![coureurs](img/coureurs.png) + +Différents classements sont affichés. Tout d'abord le general : + +![general](img/general.png) + +Ensuite les différentes personnes dopées ainsi que les équipe éliminées : + +![general](img/elimine.png) + +Et enfin le classement final : + +![final](img/final.png) + +## Installation + +Le [Makefile](/Makefile) permet de compiler et lancer le programme. Il permet aussi de nettoyer les résidus de la compilation. Pour cela il est possible de faire différentes commandes : +``` +make +``` +*Compile et lance le programme* +``` +make clean +``` +*Supprime les fichiers d'output ainsi que l'executable* +``` +./main +``` +*Lance le programme s'il est déjà compilé* + +A noter que sur windows Le Makefile produit une erreur 127. Cela n'est produit qu'en compilation et non à l'execution. + +[bullewiki]: https://fr.wikipedia.org/wiki/Tri_%C3%A0_bulles \ No newline at end of file diff --git a/header/coureur.h b/header/coureur.h index 40809f0..f3ce772 100644 --- a/header/coureur.h +++ b/header/coureur.h @@ -1,3 +1,13 @@ +/** + * @file coureur.h + * @author Yohan Boujon (boujon@insa-toulouse.fr) + * @author Simon Paris (pari@insa-toulouse.fr) + * @version 1.0 + * @date 2022-12-01 + * + * @copyright Copyright (c) 2022 + * + */ #ifndef HEADER_COUREUR #define HEADER_COUREUR #include @@ -5,7 +15,22 @@ #include #include -typedef struct{ //definition de la structure coureur +/** + * @struct coureur + * @brief definition de la structure d'un coureur + * + * @var coureur::nom + * Nom du coureur + * @var coureur::prenom + * Prénom du coureur + * @var coureur::dossard + * Numéro de dossard du coureur + * @var coureur::equipe + * Nom de l'équipe du coureur + * @var coureur::temps + * Son temps en seconde + */ +typedef struct{ char * nom; char * prenom; int dossard; @@ -13,9 +38,46 @@ typedef struct{ //definition de la structure int temps; } coureur; -//Prototype -coureur * creerCoureur(char nom[],char prenom[],int dossard, char equipe[],int temps);//Creation d'un coureur en memoire avec recupération de son adrresse avec le parametrage de c'est different champs -void ajouterTemps(int leTemps,coureur * leCoureur); //Modifier le temps d'un coureur a partir de son adresse et d'une valeur de cumule -void afficherCoureur(coureur * leCoureur); //Afficher le temps d'un coureur stocker en seconde sous forme d'heures, de minutes et de secondes ( a partir de l'adresse de sa structure de définition) +/** + * @brief Creation d'un coureur en memoire avec recupération de son adresse avec le parametrage de ses differents champs + fonctionnement : + -strcpy pour remplir les champs + -strlen renvoie taille d'une chaine pour une allocation exacte + * + * @param nom + * @param prenom + * @param dossard + * @param equipe + * @param temps + * @return coureur* l'adresse qui pointe sur la structure cree + */ +coureur * creerCoureur(char nom[],char prenom[],int dossard, char equipe[],int temps); + +/** + * @brief Modifier le temps d'un coureur a partir de son adresse et d'une valeur de cumule + * + * @param leTemps Temps que l'on souhaite cumulee au temps actuel d'un coureur + * @param leCoureur Represente le coureur dont on modifie le temps + */ +void ajouterTemps(int leTemps,coureur * leCoureur); + +/** + * @brief Afficher le temps d'un coureur stocker en seconde sous forme d'heures, de minutes et de secondes ( a partir de l'adresse de sa structure): + * Affiche egalement le contenue des autres champs + * @param leCoureur Represente le coureur dont on souhaite affichée le temps + */ +void afficherCoureur(coureur * leCoureur); + +/** + * @brief Convertion des secondes à un format heures,minutes et secondes + * -calcul d'heures qui renvoie uniquement la partie entier + * -calcul de minutes qui renvoie uniquement la partie entier avec la prise en compte des heures soustraite en minutes + * -calcul de seconde qui renvoie uniquement la partie entier avec la prise en compte des heures soustraite en secondes et des minutes en secondes + * + * @param secondsIN les secondes à rentrer + * @param hour les heures en sortie + * @param minute les minutes en sortie + * @param second les secondes en sortie + */ void formatSecond(int secondsIN, int* hour, int* minute, int* second); #endif \ No newline at end of file diff --git a/header/liste.h b/header/liste.h index fe8c2ad..678858f 100644 --- a/header/liste.h +++ b/header/liste.h @@ -1,3 +1,13 @@ +/** + * @file liste.h + * @author Yohan Boujon (boujon@insa-toulouse.fr) + * @author Simon Paris (pari@insa-toulouse.fr) + * @version 1.0 + * @date 2022-12-01 + * + * @copyright Copyright (c) 2022 + * + */ #ifndef HEADER_LISTE #define HEADER_LISTE #include @@ -6,43 +16,322 @@ #define TEMPSMIN 80 #define TEMPSDOP 70 -struct element{ //definition de la structure qui element qui sera encaspule/chaine - coureur * coureurActuel; //"contient" l'adresse d'une structure coureur - struct element * suiv; //"contient" l'adresse d'une autre strucutre element(chainage) +/** + * @struct element + * @brief definition de la structure qui element qui sera encaspule/chaine + * + * @var element::coureurActuel + * "contient" l'adresse d'une structure coureur + * @var element::suiv + * "contient" l'adresse d'une autre strucutre element(chainage) + */ +struct element{ + coureur * coureurActuel; + struct element * suiv; }; -typedef struct{ //definition de la structure liste qui "contient" l'encaspsulation - struct element * debut; //"contient" un element en debut *voir init dans liste.c - struct element * courant; //"contient"element actuel *voir init dans liste.c - struct element * fin; //"contient"element en fin de la liste (NULL) *voir init dans liste.c +/** + * @struct liste + * @brief definition de la structure liste qui "contient" l'encaspsulation + * + * @var liste::debut + * "contient" un element en debut + * @var liste::courant + * "contient"element actuel + * @var liste::fin + * "contient"element en fin de la liste (NULL) + */ +typedef struct{ + struct element * debut; + struct element * courant; + struct element * fin; } liste; -//Prototype de fonction -struct element * initElement(void); //initialise un element en memoir qui encapsule une strucure de coureurau champs vide -liste initListe(void); //initialise chaque element de la liste a partir de initElement -void ajoutListe(liste * listeActuel,coureur * leCoureur); //ajoute un element contenant un courreur dans le chainage d'une liste -void printlist(liste l); //afficher le coureur dans chaque element d'une liste -void allerDebut(liste * l); //mettre le poiteur courant sur l'element premier d'une liste -void allerFin(liste * l); //mettre le poiteur courant sur l'element de fin d'une liste -void avancer(liste * l); //mettre le poiteur courant sur l'element suivant de la liste dans la qu'elle qu'il pointe -coureur * coureurCourant(liste * l); //rien a foutre ici -bool effacerCoureur(liste * listeActuel,coureur * coureurSuppr, bool returnSuiv);//enleve un element d'une liste a partir de l'adresse d'un courreur, sans briser le chainage +/** + * @brief initialise un element en memoire qui encapsule une strucure de coureur au champs vide + * + * @return returnElement retourne un element vierge + */ +struct element * initElement(void); + +/** + * @brief initialise chaque elements de la liste a partir de initElement + * + * + * @return l + */ +liste initListe(void); + +/** + * @brief ajout d'un element contenant un coureur dans liste + * fonctionnement : + -Creation element vierge + -l'element vierge recoi le coureur passer en parametre + -l'element vierge poite sur le premier element + -le poiteur du premier element contenu dans liste pointe sur le nouvelle element(vierge) + -le poiteur courant contenu dans la liste pointe sur le nouvelle element + * @param listeActuel liste ou l'on rajoute un element + * @param leCoureur le coureur qui sera contenu dans l'element rajoutee + */ +void ajoutListe(liste * listeActuel,coureur * leCoureur); + +/** + * @brief affiche tous les coureurs contenu dans les elements d'une liste + * fonctionnement : + -declaration d'un poiteur eCourant egale l'adresse du premiere element (variable temporaire) + -Tant que eCourant->suiv n'est pas egale a l'adresse du derniere element faire : + -affichee le coureur dans l'element d'adresse eCourant + -eCourant devient l'adresse de l'element suivant + + * @param l liste a affiche + */ +void printlist(liste l); + +/** + * @brief Mettre le poiteur courant d'une liste sur le premiere element + * + * @param l liste ou l'on modifie le poiteur courant + */ +void allerDebut(liste * l); + +/** + * @brief Mettre le poiteur courant d'une liste sur le derniee element + * + * @param l liste ou l'on modifie le poiteur courant + */ +void allerFin(liste * l); + +/** + * @brief Mettre le poiteur courant sur l'element suivant + * + * @param l liste ou l'on modifie le poiteur courant + */ +void avancer(liste * l); + +/** + * @brief Retourne le coureur encapsulee dans l'element pointer par le pointeur courant + * + * @param l liste ou l'on modifie le poiteur courant + */ +coureur * coureurCourant(liste * l); + +/** + * @brief suprime un element(a partir de l'adresse d'un coureur) dans la liste sans briser le chainage + * fonctionnement : + -declaration d'un poiteur eParcours egale l'adresse du premiere element (variable temporaire) + -declaration d'un poiteur(ePrevious) qui stockera temporairement l'adresse des elements pendant la reconstruction du chainage + -si l'element a supprimer est le premiere element de la liste : + -le poiteur courant pointe sur l'element suivant + -le poiteur pointant sur le premiere element poite sur le deuxieme + -si l'element a suppr n'est pas le deuxieme : + -ePrevious egale l'adresse du premiere element + -eParcours egale l'adresse du deuxieme element + -tant que l'element poitee par eParcours ne contient pas le coureur a supprimer faire : + -ePrevious pointe sur l'element suivant + -eParcours pointe sur l'element suivant + -l'element avant celui a suprimer pointe sur l'element sur le qu'elle poite l'element a supprimer + -supression de l'element + + * @param listeActuel Liste ou l'on suppr un element + * @param coureurSuppr le coureur qui doit etre dans l'element pour le supprimer + */ +bool effacerCoureur(liste * listeActuel,coureur * coureurSuppr, bool returnSuiv); + +/** + * @brief Cherche si un coureur existe dans une liste + * + * @param l la liste en question + * @param c le coureur cherché + * @return true / false + */ bool doesCoureurExist(liste* l,coureur * c); + +/** + * @brief A partir d'une liste source supprime tous les éléments en commun + * + * @param destination liste à modifier + * @param source liste des éléments à supprimer + * @return int nombre d'éléments supprimés + */ int effacerListe(liste * destination, liste * source); -int tailleListe(liste l); //retourne le nombre d'elements chaine d'une liste -coureur * getCoureur(liste l,int nb); //retourne le courreur contenue dans l'element nb d'une liste (on considere un element 0) -void invertCoureur(liste * l,int nb); //inverse l'element nb et nb+1 dans une liste (on considere un element 0) -void triListe(liste * l,int taille); //trie bulle des element d'une liste a partir du temps contenue dans la structure encapsule dans l'element + +/** + * @brief Renvoie le nombre d'elements d'une liste + fonctionnement : + -initilisation a 0 d'un compteur (int) + -declaration d'un poiteur elementActuel initialiser au poiteur debut present dans liste qui pointe sur le premier element du chainage + -tant que elementActuel n'est pas egale a l'adresse du derniere element faire + -increment compteur + -elementActuel pointe sur l'element suivant + -retourne le compteur + + * + * @param l l la liste dont on ve connaitre la taille + * @return int le nombre d'element (on compte a partir de 0) + */ +int tailleListe(liste l); + +/** + * @brief retourne le coureur contenu dans l'element nb d'une liste (on considere un element 0) + * fonctionnement : + -init elementCourant a l'adresse du premiere element de la liste + -pour i allant de 0 a nb-1 + -a la fin de la boucle elementcourant pointe sur l'element nb (on considere un element 0) + -renvoie le coureur encapsulee dans l'element nb + * @param l la liste ou doit se trouver l'element encapsulant le coureur + * @param nb le numero d'element rechercher + * @return coureur* + */ +coureur * getCoureur(liste l,int nb); + +/** + * @brief inverse l'element nb et nb+1 dans une liste (on considere un element 0) + * fonctionnement : + -declaration d'un poiteur elementCourant initialiser au poiteur debut present dans liste qui pointe sur le premier element du chainage + -declaration et allocation en memoire(a l'adresse *elemeentPrecedent) d'une taille de structure element de type element + -pour i allant de 0 a nb-1 faire : + -en fin de boucle elementCourant poite sur l'element nb et elementPrecendent nb-1 + + -declaration de elementsuivant qui poite sur l'element nb+1 + -elementCourant pointe sur nb+1 + -elementSuivant pointe sur nb + -si l'element a intervertir est le premier : + -le poiteur courant pointe sur l'ancien deuxieme element + -le poiteur debut pointe sur l'ancien deuxieme + -si l'element a intervertir diff du premier : + -element nb-1 pointe sur element nb + -le poiteur courant pointe sur le premier element + * @param l liste ou l'on inverse les elements + * @param nb le numero d'element inverser avec nb+1 + */ +void invertCoureur(liste * l,int nb); + +/** + * @brief trie bulle des elements d'une liste a partir du temps contenu dans la structure encapsuler dans l'element + * fonctionnement : + -pour i allant du nombre d'element dans la liste a 2 step -1 + -pour j allant de 0 a i-1 step 1 + -si lecoureur taille -i a un temps < au coureur taille-i+1 + -inverser les coureurs j et j+1 + + * @param l liste a trier + * @param taille represente la taille de la liste + */ +void triListe(liste * l,int taille); + + +/** + * @brief Initialise un tableau de chaîne de caractères + * + * @param sizeCol taille des colonnes + * @param sizeLine taille de chaque ligne + * @return int** Une matrice de caractère + */ char ** initMatrix(int sizeCol,int sizeLine); + +/** + * @brief Detecte si une chaîne de caractères est présente dans un + * tableau de chaîne de caractères + * + * @param matrix tableau de chaîne de caractères + * @param string chaîne de caractère + * @param size nombre de lignes + * @return true / false + */ bool isStringInMatrix(char ** matrix, char * string, int size); + +/** + * @brief Donne le nom de chaque équipe dans un tableau de chaîne de caractères + * + * @param matrix tableau de chaîne de caractère + * @param sizeCol taille des colonns + * @param sizeLine taille des lignes + * @param l la liste composant les noms des équipes + */ void readTeams(char ** matrix, int sizeCol, int sizeLine, liste l); + +/** + * @brief Compte le nombre de joueur dans chaque équipe et le met dans une liste + * d'entiers + * + * @param teamNames les noms de chaque équipe + * @param sizeCol taille de la colonne des noms de chaque équipe + * @param list la liste que l'ont veut analyser + * @return int* tableau en commun avec le nom des équipes du nombre de joueur + */ int * teamsCount(char ** teamNames, int sizeCol, liste list); + +/** + * @brief Elimine une équipe si elle a moins de lessThanCoureurCount + * + * @param teamNames les noms de chaque équipe + * @param sizeCol taille de la colonne des noms de chaque équipe + * @param list la liste que l'ont veut analyser + * @param coureursInTeams nombre de joueur par équipe + * @param lessThanCoureurCount int + */ void removeTeam(char ** teamNames, int sizeCol, liste * list, int * coureursInTeams, int lessThanCoureurCount); + +/** + * @brief Récupère l'élément courant de la liste + * + * @param l liste + * @return struct element* + */ struct element * getElementCourant(liste l); + +/** + * @brief Affiche les équipes et le nombre de coureurs + * + * @param teamsNames les noms de chaque équipe + * @param coureurInTeams nombre de coureur dans chaque équipe + * @param teamsNB nombre d'équipes + */ void printTeamsDetails(char ** teamsNames, int * coureurInTeams, int teamsNB); + +/** + * @brief Affiche les équipes composés d'un certain nombre de coureur + * + * @param num le nombre de coureur auquel l'équipe doit être égale + * @param teamsNames les noms de chaque équipe + * @param coureurInTeams nombre de coureur dans chaque équipe + * @param teamsNB nombre d'équipes + */ void printTeamsDetailsFor(int num, char ** teamsNames, int * coureurInTeams, int teamsNB); + +/** + * @brief Supprime les coureurs s'il y a plus de maxCoureur + * + * @param maxCoureur nombre de coureur max dans une équipe + * @param list liste à analyser + * @param teamNames nom des équipes + * @param sizeCol taille de la colonne des équipe/nombre d'équipes + */ int * keepOnlyCoureur(int maxCoureur, liste * list, char ** teamNames, int sizeCol); + +/** + * @brief Tri une liste de int ainsi qu'une liste de chaîne de caractère associé + * + * @param temps liste de int + * @param taille taille de cette liste + * @param teams liste de chaîne de caractère (doit être de la même taille) + */ void triTemps(int * temps, int taille,char ** teams); + +/** + * @brief Affiche le temps ainsi que les équipes + * + * @param temps liste de temps en int + * @param teams liste de chaîne de caractères, les équipes + * @param taille taille des deux listes (doivent être égales) + * @param ignore le chiffre qui doit être ignoré (si vous voulez le désactiver, choisissez un nombre impossible) + */ void printTeamsTimes(int * temps, char ** teams, int taille, int ignore); + +/** + * @brief Fonction de test + * + * @return int renvoie zéro si réussie + */ int test(void); #endif \ No newline at end of file diff --git a/header/readfile.h b/header/readfile.h index e0daf4e..f49a37e 100644 --- a/header/readfile.h +++ b/header/readfile.h @@ -1,3 +1,13 @@ +/** + * @file readfile.h + * @author Yohan Boujon (boujon@insa-toulouse.fr) + * @author Simon Paris (pari@insa-toulouse.fr) + * @version 1.0 + * @date 2022-12-01 + * + * @copyright Copyright (c) 2022 + * + */ #ifndef HEADER_READFILE #define HEADER_READFILE #include @@ -7,12 +17,80 @@ #include "liste.h" #define MAXLINE 50 +/** + * @brief Récupère le nombre de ligne d'un fichier + * + * @param readFile le fichier en question + * @return int nombre de ligne + */ int getNbLines(void); + +/** + * @brief Converti les caractères d'un fichier dans la liste de coureur. + * + * @param nbLines nombre de ligne du fichier qui va être lu + * @param size renvoie la taille de la chaîne de caractère + * @param stepsNb int * renvoi le nombre d'étapes + * @param teamsNb int * renvoi le nombre d'équipes + * @return liste de coureurs + */ int getFileSize(FILE * readFile); + +/** + * @brief récupère la taille du fichier, est assez grossier et ne sert qu'à + * initialiser les tableaux pour ne pas avoir une taille à prédéfinir. + * + * @param readFile fichier en question + * @return int taille du fichier + */ liste getListFromFile(int nbLines,int * size, int * stepsNb,int * teamsNb); + +/** + * @brief /!\/!\/!\ Debug uniquement /!\/!\/!\ : + * récupère une ligne, non optimisé donc inutilisable + * + * @param string la chaîne de caractère à analyser + * @param line int la ligne à récupérer + * @return char* la ligne sous un string + */ char * getLine(char * string,int line); + +/** + * @brief /!\/!\/!\ INUTILISE CAR OBSELETE /!\/!\/!\ : + * Renvoi une liste à partir d'une chaîne de caractère contenant + * les équipes ainsi que les coureurs avec leur nom, leur prénom et numéro de dossard + * + * @param string chaîne de caractère + * @param nbLines nombre de ligne max de la chaîne de caractère + * @return liste des coureurs + */ liste string2Liste(char * string,int nbLines); + +/** + * @brief A partir d'une ligne récupère les informations sur le coureur, + * Notamment son numéro de dossard, son nom et son prénom + * + * @param string char * ligne textuel + * @param nom char * renvoi le nom du coureur, doit être vide + * @param prenom char * renvoi le nom du coureur, doit être vide + * @param dossard int * renvoi le numéro du dossard + */ void string2Coureur(char * string,char * nom, char * prenom, int * dossard); + +/** + * @brief Supprime les retours à la ligne dans les chaînes de caractère. + * Attention ! les remplace par le caractère signifiant la fin de la chaîne. + * + * @param string chaîne de caractère + */ void deleteLineFeed(char * string); + +/** + * @brief /!\/!\/!\ Debug uniquement /!\/!\/!\ : + * Permet d'observer les valeurs de chaque caractère. + * la taille n'est pas demandée pour observer au delà de l'espace mémoire donné + * + * @param string un tableau de caractère + */ void printHexString(char * string); #endif \ No newline at end of file diff --git a/img/coureurs.png b/img/coureurs.png new file mode 100644 index 0000000..d88bddd Binary files /dev/null and b/img/coureurs.png differ diff --git a/img/doxygen.png b/img/doxygen.png new file mode 100644 index 0000000..a0c3fca Binary files /dev/null and b/img/doxygen.png differ diff --git a/img/elimine.png b/img/elimine.png new file mode 100644 index 0000000..38d3508 Binary files /dev/null and b/img/elimine.png differ diff --git a/img/final.png b/img/final.png new file mode 100644 index 0000000..e9b2744 Binary files /dev/null and b/img/final.png differ diff --git a/img/general.png b/img/general.png new file mode 100644 index 0000000..28438c1 Binary files /dev/null and b/img/general.png differ diff --git a/img/tp.png b/img/tp.png new file mode 100644 index 0000000..0ebb6c2 Binary files /dev/null and b/img/tp.png differ diff --git a/src/coureur.c b/src/coureur.c index 59d4d72..3911b03 100644 --- a/src/coureur.c +++ b/src/coureur.c @@ -1,18 +1,17 @@ -#include "../header/coureur.h" //inclure le fichier "coureur.h" qui contien les libs, structure et prototypes - /** - * @brief Creation d'un coureur en memoire avec recupération de son adrresse avec le parametrage de c'est different champs - fonctionnement : - -strcpy pour remplir les champs - -strlen renvoie taille d'une chaine pour une allocation exacte + * @file coureur.c + * @author Yohan Boujon (boujon@insa-toulouse.fr) + * @author Simon Paris (pari@insa-toulouse.fr) + * @brief Gère les coureurs + * @version 1.0 + * @date 2022-12-01 + * + * @copyright Copyright (c) 2022 * - * @param nom - * @param prenom - * @param dossard - * @param equipe - * @param temps - * @return coureur* l'adresse qui pointe sur la structure cree */ +#include "../header/coureur.h" + + coureur * creerCoureur(char nom[],char prenom[],int dossard, char equipe[],int temps) { coureur * leCoureur = malloc(sizeof(coureur)); @@ -30,23 +29,12 @@ coureur * creerCoureur(char nom[],char prenom[],int dossard, char equipe[],int t return leCoureur; } -/** - * @brief Modifier le temps d'un coureur a partir de son adresse et d'une valeur de cumule - * - * @param leTemps Temps que l'on souhaite cumulee au temps actuel d'un coureur - * @param leCoureur Represente le coureur dont on modifie le temps - */ + void ajouterTemps(int leTemps,coureur * leCoureur) { leCoureur->temps+=leTemps; } -/** - * @brief Afficher le temps d'un coureur stocker en seconde sous forme d'heures, de minutes et de secondes ( a partir de l'adresse de sa structure): - -initilisation de 3 variable temporaires - - * @param leCoureur Represente le coureur dont on souhaite affichée le temps - */ void afficherCoureur(coureur * leCoureur) { int heure,minute,seconde; @@ -55,17 +43,7 @@ void afficherCoureur(coureur * leCoureur) printf("Nom : %s\tPrenom : %s\tDossard : %d\tEquipe : %s\tTemps : %d:%d:%d\n",leCoureur->nom,leCoureur->prenom,leCoureur->dossard,leCoureur->equipe,heure,minute,seconde); } -/** - * @brief Convertion des seconds à un format heures,minutes et secondes - * -calcul d'heures qui renvoie uniquement la partie entier - * -calcul de minutes qui renvoie uniquement la partie entier avec la prise en compte des heures soustraite en minutes - * -calcul de seconde qui renvoie uniquement la partie entier avec la prise en compte des heures soustraite en secondes et des minutes en secondes - * - * @param secondsIN les secondes à rentrer - * @param hour les heures en sortie - * @param minute les minutes en sortie - * @param second les secondes en sortie - */ + void formatSecond(int secondsIN, int* hour, int* minute, int* second) { *hour = (int)(secondsIN)/3600; diff --git a/src/liste.c b/src/liste.c index 382a4e5..340d1f6 100644 --- a/src/liste.c +++ b/src/liste.c @@ -1,7 +1,81 @@ +/** + * @file liste.c + * @author Yohan Boujon (boujon@insa-toulouse.fr) + * @author Simon Paris (pari@insa-toulouse.fr) + * @brief Gère les listes + * @version 1.0 + * @date 2022-12-01 + * + * @copyright Copyright (c) 2022 + * + */ #include "../header/readfile.h" #include "../header/liste.h" #define MAXTEAMATES 3 +/*! \mainpage TP Coureur par Simon Paris et Yohan Boujon +# TP Langage C +## Introduction +Le programme tpcoureur fonctionne de manière aléatoire. + +A chaque lancement du programme les coureurs sont lu à partir du fichier +[fichier_coureur.txt](fichier_coureurs.txt). Ces derniers vont être ensuite mis dans une liste, dans le même ordre que donné par le fichier. Ce fichier possède une convention particulière, soit : +> `1` Nombre d'étapes + +> `1` Nombre d'équipe + +> `x` Nom de l'équipe *x* + +> `5x` n° du dossard, Nom, `d'un coureur de l'équipe x` + +> ... + +Les variables définies +> `TEMPSMAX` Temps maximum qu'un coureur peut avoir\ +`TEMPSMIN` Temps minimum qu'un coureur peut avoir\ +`TEMPSDOP` Temps pour les joueurs dopés *(Inférieur à `TEMPSMIN`)*\ + +Chaque calcul de temps est randomisé selon ces variables. Elles peuvent être changées pour avoir des temps finaux différents. Mais surtout change la chance qu'un joueur soit dopé. + +Le programme va tout d'abord supprimer les coureurs dopés et trier avec l'algorithme du [tri bulle][bullewiki] dans l'ordre croissant. Il va ensuite afficher les équipes éliminées : une équipe est éliminée si elle possède moins de `3 joueurs`. Et enfin elle affiche le classement final des **équipes uniquement**, seuls les temps des 3 meilleurs coureurs sont comptés. + +En premier lieu les différents participants sont affichés : + +![coureurs](img/coureurs.png) + +Différents classements sont affichés. Tout d'abord le general : + +![general](img/general.png) + +Ensuite les différentes personnes dopées ainsi que les équipe éliminées : + +![general](img/elimine.png) + +Et enfin le classement final : + +![final](img/final.png) + +## Installation + +Le [Makefile](/Makefile) permet de compiler et lancer le programme. Il permet aussi de nettoyer les résidus de la compilation. Pour cela il est possible de faire différentes commandes : +``` +make +``` +*Compile et lance le programme* +``` +make clean +``` +*Supprime les fichiers d'output ainsi que l'executable* +``` +./main +``` +*Lance le programme s'il est déjà compilé* + +A noter que sur windows Le Makefile produit une erreur 127. Cela n'est produit qu'en compilation et non à l'execution. + +[bullewiki]: https://fr.wikipedia.org/wiki/Tri_%C3%A0_bulles + */ + int main(void) { int size, stepsNb, teamsNb, listeTaille, dopageCount; @@ -49,11 +123,6 @@ int main(void) return 0; } -/** - * @brief initialise un element en memoire qui encapsule une strucure de coureur au champs vide - * - * @return returnElement retourne un element vierge - */ struct element * initElement(void) { struct element * returnElement = (struct element *)malloc(sizeof(struct element)); @@ -62,12 +131,6 @@ struct element * initElement(void) return returnElement; } -/** - * @brief initialise chaque element de la liste a partir de initElement - * - * - * @return l - */ liste initListe(void) { liste l; @@ -77,17 +140,6 @@ liste initListe(void) return l; } -/** - * @brief ajout d'un element contenant un coureur dans liste - * fonctionnement : - -Creation element vierge - -l'element vierge recoi le coureur passer en parametre - -l'element vierge poite sur le premier element - -le poiteur de premiere element contenue dans liste pointe sur le nouvelle element(vierge) - -le poiteur courant contenue dans la liste pointe sur le nouvelle element - * @param listeActuel liste ou l'on rajoute un element - * @param leCoureur le coureur qui sera contenue dans l'element rajoutee - */ void ajoutListe(liste * listeActuel,coureur * leCoureur) { struct element * elementActuel = (struct element *)malloc(sizeof(struct element)); @@ -97,16 +149,6 @@ void ajoutListe(liste * listeActuel,coureur * leCoureur) listeActuel->courant=elementActuel; } -/** - * @brief affiche tous les coureurs contenue dans les elements d'une liste - * fonctionnement : - -decleration d'un poiteur eCourant egale l'adresse du premiere element (variable temporaire) - -Tant que eCourant->suiv n'est pas egale a l'adresse du derniere element faire : - -affichee le coureur dans l'element d'adresse eCourant - -eCourant devient l'adresse de l'element suivant - - * @param l liste a affiche - */ void printlist(liste l) { struct element * eCourant = l.debut; @@ -118,66 +160,26 @@ void printlist(liste l) printf("NULL \n"); } -/** - * @brief Mettre le poiteur courant d'une liste sur le premiere element - * - * @param l liste ou l'on modifie le poiteur courant - */ void allerDebut(liste * l) { l->courant = l->debut; } -/** - * @brief Mettre le poiteur courant d'une liste sur le derniee element - * - * @param l liste ou l'on modifie le poiteur courant - */ void allerFin(liste * l) { l->courant = l->fin; } -/** - * @brief Mettre le poiteur courant sur l'element suivant - * - * @param l liste ou l'on modifie le poiteur courant - */ void avancer(liste * l) { l->courant = l->courant->suiv; } -/** - * @brief Retourne le coureur encapsulee dans l'element pointer par le pointeur courant - * - * @param l liste ou l'on modifie le poiteur courant - */ coureur * coureurCourant(liste * l) { return l->courant->coureurActuel; } -/** - * @brief suprime un element(a partir de l'adresse d'un coureur) dans la liste sans briser le chainage - * fonctionnement : - -declaration d'un poiteur eParcours egale l'adresse du premiere element (variable temporaire) - -declaration d'un poiteur(ePrevious) qui stockera temporairement l'adresse des elements pendant la reconstruction du chainage - -si l'element a supprimer est le premiere element de la liste : - -le poiteur courant pointe sur l'element suivant - -le poiteur pointant sur le premiere element poite sur le deuxieme - -si l'element a suppr n'est pas le deuxieme : - -ePrevious egale l'adresse du premiere element - -eParcours egale l'adresse du deuxieme element - -tant que l'element poitee par eParcours ne contient pas le courreur a supprimer faire : - -ePrevious pointe sur l'element suivant - -eParcours pointe sur l'element suivant - -l'element avant celui a suprimer pointe sur l'element sur le qu'elle poite l'element a supprimer - -supression de l'element - - * @param listeActuel Liste ou l'on suppr un element - * @param coureurSuppr le coureur qui doit etre dans l'element pour le supprimer - */ bool effacerCoureur(liste * listeActuel,coureur * coureurSuppr, bool returnSuiv) { if(!doesCoureurExist(listeActuel,coureurSuppr)) @@ -208,13 +210,6 @@ bool effacerCoureur(liste * listeActuel,coureur * coureurSuppr, bool returnSuiv) return true; } -/** - * @brief Cherche si un coureur existe dans une liste - * - * @param l la liste en question - * @param c le coureur cherché - * @return true / false - */ bool doesCoureurExist(liste* l,coureur * c) { struct element * eDebut = l->debut; @@ -229,13 +224,6 @@ bool doesCoureurExist(liste* l,coureur * c) return false; } -/** - * @brief A partir d'une liste source supprime tous les éléments en commun - * - * @param destination liste à modifier - * @param source liste des éléments à supprimer - * @return int nombre d'éléments supprimés - */ int effacerListe(liste * destination, liste * source) { int returnValue=0; @@ -251,20 +239,6 @@ int effacerListe(liste * destination, liste * source) return returnValue; } -/** - * @brief Renvoie le nombre d'elements d'une liste - fonctionnement : - -initilisation a 0 d'un compteur (int) - -decleration d'un poiteur elementActuel initialisee au poiteur debut present dans liste qui pointe sur le premier element du chainage - -tant que elementActuel n'est pas egale a l'adresse du derniere element faire - -increment compteur - -elementActuel pointe sur l'element suivant - -retourne le compteur - - * - * @param l l la liste dont on ve connaitre la taille - * @return int le nombre d'element (on compte a partir de 0) - */ int tailleListe(liste l) { int returnValue=0; @@ -278,17 +252,6 @@ int tailleListe(liste l) allerDebut(&l); } -/** - * @brief retourne le courreur contenue dans l'element nb d'une liste (on considere un element 0) - * fonctionnement : - -init elementCourant a l'adresse du premiere element de la liste - -pour i allant de 0 a nb-1 - -a la fin de la boucle elementcourant pointe sur l'element nb (on considere un element 0) - -renvoie le coureur encapsulee dans l'element nb - * @param l la liste ou doit se trouver l'element encapsulant le coureur - * @param nb le numero d'element rechercher - * @return coureur* - */ coureur * getCoureur(liste l,int nb) { struct element * elementCourant = l.debut; @@ -299,26 +262,6 @@ coureur * getCoureur(liste l,int nb) return elementCourant->coureurActuel; } -/** - * @brief inverse l'element nb et nb+1 dans une liste (on considere un element 0) - * fonctionnement : - -decleration d'un poiteur elementCourant initialisee au poiteur debut present dans liste qui pointe sur le premier element du chainage - -declaration et allocation en memoire(a l'adresse *elemeentPrecedent) d'une taille de structure element de type element - -pour i allant de 0 a nb-1 faire : - -en fin de boucle elementCourant poite sur l'element nb et elementPrecendent nb-1 - - -declaration de elementsuivant qui poite sur l'element nb+1 - -elementCourant pointe sur nb+1 - -elementSuivant pointe sur nb - -si l'element a intervertir est le premier : - -le poiteur courant pointe sur l'ancien deuxieme element - -le poiteur debut pointe sur l'ancien deuxieme - -si l'element a intervertir diff du premier : - -element nb-1 pointe sur element nb - -le poiteur courant pointe sur le premier element - * @param l liste ou l'on inverse les elements - * @param nb le numero d'element inverser avec nb+1 - */ void invertCoureur(liste * l,int nb) { struct element * elementDebut = l->debut; @@ -342,17 +285,6 @@ void invertCoureur(liste * l,int nb) } } -/** - * @brief trie bulle des element d'une liste a partir du temps contenue dans la structure encapsule dans l'element - * fonctionnement : - -pour i allant du nombre d'element dans la liste a 2 step -1 - -pour j allant de 0 a i-1 step 1 - -si leCourreur taille -i a un temps < au coureur taille-i+1 - -inverser les courreurs j et j+1 - - * @param l liste a trier - * @param taille represente la taille de la liste - */ void triListe(liste * l,int taille) { bool tabOrdered = true; @@ -365,7 +297,7 @@ void triListe(liste * l,int taille) invertCoureur(l,j); tabOrdered = false; } - //printlist(*l); + } if(tabOrdered) { @@ -374,13 +306,6 @@ void triListe(liste * l,int taille) } } -/** - * @brief Initialise un tableau de chaîne de caractères - * - * @param sizeCol taille des colonnes - * @param sizeLine taille de chaque ligne - * @return int** Une matrice de caractère - */ char ** initMatrix(int sizeCol,int sizeLine) { char ** matrix; @@ -392,15 +317,6 @@ char ** initMatrix(int sizeCol,int sizeLine) return matrix; } -/** - * @brief Detecte si une chaîne de caractères est présente dans un - * tabealu de chaîne de caractères - * - * @param matrix tableau de chaîne de caractères - * @param string chaîne de caractère - * @param size nombre de lignes - * @return true / false - */ bool isStringInMatrix(char ** matrix, char * string, int size) { for(int i=0;icourant; @@ -485,7 +375,7 @@ void removeTeam(char ** teamNames, int sizeCol, liste * list, int * coureursInTe { if((strcmp(teamNames[i],elementCourant->coureurActuel->equipe)) == 0 && (coureursInTeams[i]coureurActuel); + effacerCoureur(list,elementCourant->coureurActuel,false); elementCourant=getElementCourant(*list); } @@ -494,24 +384,11 @@ void removeTeam(char ** teamNames, int sizeCol, liste * list, int * coureursInTe } } -/** - * @brief Récupère l'élément courant de la liste - * - * @param l liste - * @return struct element* - */ struct element * getElementCourant(liste l) { return l.courant; } -/** - * @brief Affiche les équipes et le nombre de coureurs - * - * @param teamsNames les noms de chaque équipe - * @param coureurInTeams nombre de coureur dans chaque équipe - * @param teamsNB nombre d'équipes - */ void printTeamsDetails(char ** teamsNames, int * coureurInTeams, int teamsNB) { for(int i=0;i