791 lines
22 KiB
C
791 lines
22 KiB
C
#include<string.h>
|
|
#include<stdio.h>
|
|
#include<stdlib.h>
|
|
|
|
#define NameLength 16
|
|
#define NameLengthScanf "%16s"
|
|
|
|
/* 1 */
|
|
|
|
/*
|
|
Le graphe représente les objets personnes rencontrés pendant la série.
|
|
Chaque case représente le départ d'une flèche vers un autre personnage (ou · pour pas de flèche) qui correspond à :
|
|
|
|
```
|
|
--------------
|
|
| 1 | 2 |
|
|
------------
|
|
| | 3 |
|
|
| nom |-----|
|
|
| | 4 |
|
|
-------------
|
|
| 6 | 5 |
|
|
-------------
|
|
```
|
|
1. Pointeur vers le père
|
|
2. Pointeur vers la mère
|
|
3. Chainage des frères et sœurs coté du père
|
|
4. Chainage des frères et sœurs coté de la mère
|
|
5. Pointeur vers le premier enfant
|
|
6. Liste de tous les personnages
|
|
|
|
|
|
Le chainage crée une «liste» accessible depuis n'importe lequel des membres
|
|
|
|
Pour le pointeur 6, la flèche pointant sur jihair représente le début de la liste.
|
|
*/
|
|
|
|
/* 2 */
|
|
|
|
// Le sexe des personnes qui sont parent peut être retrouvé (il suffit de regarder leur premier enfant, si ils en sont le père ou la mère).
|
|
// Les autres, on peut dire qu'on s'en fiche, leur sexe sera «défini» au moment ou un couple les contenant aura un enfant.
|
|
|
|
/* 3 */
|
|
|
|
// Le chainage général permet de pouvoir lister les personnage, et ainsi de pouvoir par exemple chercher un personnage de par son nom, ou toute autre information stoqué dedans.
|
|
|
|
/* 4 */
|
|
// L'avantage de ces listes chainées horizontales est qu'elle sont accessibles simplement depuis n'importe quel membre de la liste.
|
|
|
|
/* 5 */
|
|
|
|
struct personnage{
|
|
|
|
char* nom;
|
|
struct personnage* pere;
|
|
struct personnage* mere;
|
|
struct personnage* frereSuivantPapa;
|
|
struct personnage* frereSuivantMaman;
|
|
struct personnage* premierEnfant;
|
|
struct personnage* chaineGlobale;
|
|
|
|
char shouldFreeNom;
|
|
|
|
};
|
|
|
|
/* 6 */
|
|
|
|
struct personnage* getByName(struct personnage* origin, char* name){
|
|
|
|
while(origin!=NULL && strcmp(name,origin->nom)!=0){
|
|
origin = origin->chaineGlobale;
|
|
}
|
|
return origin;
|
|
|
|
}
|
|
|
|
/* 7 */
|
|
|
|
struct personnage* newUnrelatedM(struct personnage** originp, char* name, char shouldFreeNom){
|
|
if(name==NULL)return NULL;
|
|
struct personnage* dest = (struct personnage*) malloc(sizeof(struct personnage));
|
|
dest->nom = name;
|
|
dest->shouldFreeNom = shouldFreeNom;
|
|
dest->frereSuivantPapa = dest->frereSuivantMaman = dest;
|
|
dest->pere = dest->mere = dest->premierEnfant = NULL;
|
|
|
|
dest->chaineGlobale = *originp;
|
|
*originp = dest;
|
|
|
|
return dest;
|
|
}
|
|
|
|
struct personnage* newUnrelated(struct personnage** originp, char* name){
|
|
return newUnrelatedM(originp, name, 0);
|
|
}
|
|
|
|
/* 8 */
|
|
int papounet(struct personnage* pere, struct personnage* enfant){
|
|
if(pere==NULL || enfant==NULL)return 1;
|
|
enfant->pere = pere;
|
|
if(pere->premierEnfant==NULL){
|
|
pere->premierEnfant = enfant;
|
|
} else {
|
|
struct personnage* fraterie = pere->premierEnfant;
|
|
while(fraterie->frereSuivantPapa!=pere->premierEnfant)fraterie = fraterie->frereSuivantPapa;
|
|
// Fraterie est maintenant le dernier né du père
|
|
fraterie->frereSuivantPapa = enfant;
|
|
}
|
|
enfant->frereSuivantPapa = pere->premierEnfant;
|
|
return 0;
|
|
}
|
|
|
|
/* 9 */
|
|
int mamounette(struct personnage* mere, struct personnage* enfant){
|
|
if(mere==NULL || enfant==NULL)return 1;
|
|
enfant->mere = mere;
|
|
if(mere->premierEnfant==NULL){
|
|
mere->premierEnfant = enfant;
|
|
} else {
|
|
struct personnage* fraterie = mere->premierEnfant;
|
|
while(fraterie->frereSuivantMaman!=mere->premierEnfant)fraterie = fraterie->frereSuivantMaman;
|
|
// Fraterie est maintenant le dernier né de la mère
|
|
fraterie->frereSuivantMaman = enfant;
|
|
}
|
|
enfant->frereSuivantMaman = mere->premierEnfant;
|
|
return 0;
|
|
}
|
|
|
|
/* 10 */
|
|
char* nomOr(struct personnage* perso, char* orElse){
|
|
if(perso==NULL)return orElse;
|
|
return perso->nom;
|
|
}
|
|
|
|
void dumpState(struct personnage* liste){
|
|
|
|
printf("Liste des personnes chargées :\n");
|
|
|
|
while(liste!=NULL){
|
|
|
|
printf("%s : père %s et mère %s, frère-sœur coté père %s, et frère-sœur coté mère %s, son premier enfant est %s\n",
|
|
liste->nom, nomOr(liste->pere, "inconnu"), nomOr(liste->mere, "inconnue"),
|
|
liste->frereSuivantPapa->nom, liste->frereSuivantMaman->nom, nomOr(liste->premierEnfant, "aucun")
|
|
);
|
|
liste = liste->chaineGlobale;
|
|
}
|
|
|
|
printf(": seégrahc sennosrep sed etsiL\n");
|
|
|
|
}
|
|
|
|
/* 11 */
|
|
int scanfs(char* dest, int length){
|
|
|
|
if(fgets(dest, length-1, stdin)==NULL){
|
|
return 1;// Une erreur est survenue lors de la lecture (trop long ?)
|
|
}
|
|
|
|
// On doit supprimer le retour à la ligne qu'a capturé fgets.
|
|
int i;
|
|
for(i=0;i<length && (dest)[i]!='\n';i++){}
|
|
if(i>=length){// On a Overflow
|
|
// On nettoie les caracteres ecrits en trop
|
|
while( (!strchr(dest,'\n')) && (!strchr(dest,EOF)))
|
|
if(!fgets(dest, length-1,stdin))
|
|
break;
|
|
return 2;
|
|
}
|
|
dest[i] = '\0';
|
|
return 0;
|
|
}
|
|
|
|
struct personnage* addRegistryEntryM(struct personnage** liste, char* enfantN, char* pereN, char* mereN, char shouldFreeNoms){
|
|
if(enfantN==NULL) return NULL;
|
|
struct personnage *enfant, *pere, *mere;
|
|
|
|
enfant = getByName(*liste, enfantN);
|
|
if(enfant==NULL)enfant = newUnrelatedM(liste, enfantN, shouldFreeNoms&0b100);
|
|
if(pereN!=NULL){
|
|
pere = getByName(*liste, pereN);
|
|
if(pere==NULL)pere = newUnrelatedM(liste, pereN, shouldFreeNoms&0b010);
|
|
papounet(pere, enfant);
|
|
}
|
|
if(mereN!=NULL){
|
|
mere = getByName(*liste, mereN);
|
|
if(mere==NULL)mere = newUnrelatedM(liste, mereN, shouldFreeNoms&0b001);
|
|
mamounette(mere, enfant);
|
|
}
|
|
|
|
return enfant;
|
|
|
|
}
|
|
|
|
struct personnage* addRegistryEntry(struct personnage** liste, char* enfantN, char* pereN, char* mereN){
|
|
return addRegistryEntryM(liste, enfantN, pereN, mereN, 0);
|
|
}
|
|
|
|
struct personnage* askRegistryEntry(struct personnage** liste){
|
|
char* enfantN = malloc(NameLength*sizeof(char));
|
|
if(enfantN==NULL)return NULL;
|
|
char* pereN = malloc(NameLength*sizeof(char));
|
|
if(pereN==NULL){free(enfantN);return NULL;}
|
|
char* mereN = malloc(NameLength*sizeof(char));
|
|
if(mereN==NULL){free(pereN),free(enfantN);return NULL;}
|
|
|
|
do{
|
|
printf("Nom de l'enfant : ");
|
|
} while(scanfs(enfantN,NameLength));
|
|
do{
|
|
printf("Nom du père (vide pour non renseigné) : ");
|
|
} while(scanfs(pereN,NameLength));
|
|
do{
|
|
printf("Nom de la mère (vide pour non renseigné) : ");
|
|
} while(scanfs(mereN,NameLength));
|
|
|
|
// La chaine vide est représentée par un pointeur vers '\0' (la fin de la chaine)
|
|
if(*pereN=='\0'){free(pereN);pereN = NULL;}
|
|
if(*mereN=='\0'){free(mereN);mereN = NULL;}
|
|
|
|
return addRegistryEntryM(liste,enfantN, pereN, mereN, 0b111);
|
|
}
|
|
|
|
|
|
/* 12 */
|
|
// Voir le main à la fin du code.
|
|
|
|
/* 13 */
|
|
|
|
void paspapa(struct personnage* batard){
|
|
if(batard==NULL || batard->pere==NULL)return;// On n'enleve aucun lien
|
|
if(batard->frereSuivantPapa != batard){
|
|
if(batard->pere->premierEnfant == batard)batard->pere->premierEnfant = batard->frereSuivantPapa;
|
|
struct personnage* fraterie = batard;
|
|
while(fraterie->frereSuivantPapa!=batard)fraterie = fraterie->frereSuivantPapa;
|
|
// Fraterie est maintenant «juste avant» le batard
|
|
fraterie->frereSuivantPapa = batard->frereSuivantPapa;
|
|
batard->frereSuivantPapa = batard;
|
|
} else {
|
|
batard->pere->premierEnfant = NULL;
|
|
}
|
|
|
|
batard->pere = NULL;
|
|
}
|
|
|
|
/* 14 */
|
|
|
|
void pasmaman(struct personnage* batard){
|
|
if(batard==NULL || batard->mere==NULL)return;
|
|
if(batard->frereSuivantMaman != batard){
|
|
if(batard->mere->premierEnfant == batard)batard->mere->premierEnfant = batard->frereSuivantMaman;
|
|
struct personnage* fraterie = batard;
|
|
while(fraterie->frereSuivantMaman!=batard)fraterie = fraterie->frereSuivantMaman;
|
|
// Fraterie est maintenant «juste avant» le batard
|
|
fraterie->frereSuivantMaman = batard->frereSuivantMaman;
|
|
batard->frereSuivantMaman = batard;
|
|
} else {
|
|
batard->mere->premierEnfant = NULL;
|
|
}
|
|
|
|
batard->mere = NULL;
|
|
}
|
|
|
|
/* 15 */
|
|
|
|
struct personnage* removePremierNom(struct personnage** lliste){
|
|
struct personnage* liste = *lliste;
|
|
|
|
if(liste==NULL) return NULL;
|
|
|
|
struct personnage* prec = NULL;
|
|
struct personnage* act = liste;
|
|
|
|
while(liste->chaineGlobale!=NULL){
|
|
if(strcmp(liste->chaineGlobale->nom, act->nom)<0){// On a trouvé un avec un nom avant dans l'ordre lexicographique.
|
|
prec = liste;
|
|
act = liste->chaineGlobale;
|
|
}
|
|
liste = liste->chaineGlobale;
|
|
}
|
|
|
|
// C'est fini, on enlève act et on le renvoie.
|
|
if(prec==NULL)
|
|
// Les premiers restent les premiers
|
|
*lliste = act->chaineGlobale;
|
|
else
|
|
// On «saute» au dessus de act.
|
|
prec->chaineGlobale = act->chaineGlobale;
|
|
|
|
act->chaineGlobale = NULL;
|
|
return act;
|
|
}
|
|
|
|
void orderPersos(struct personnage** listeP){
|
|
|
|
struct personnage* liste = *listeP;
|
|
|
|
if(liste==NULL)return;
|
|
struct personnage* newList = removePremierNom(&liste);
|
|
struct personnage* lastAdded = newList;
|
|
|
|
while(liste!=NULL){
|
|
struct personnage* toAdd = removePremierNom(&liste);
|
|
lastAdded->chaineGlobale = toAdd;
|
|
lastAdded = toAdd;
|
|
}
|
|
|
|
*listeP = newList;
|
|
}
|
|
|
|
// Je ne comprends pas la deuxième partie de la question ...
|
|
|
|
/* 16 */
|
|
|
|
|
|
// L'objectif était de faire une sortie illisible, surtout lorsqu'il y a beaucoup de générations.
|
|
// Mais je peux mettre des parentheses
|
|
#define ParenthesesVraiNom 1
|
|
void printVraiNom(struct personnage* perso){
|
|
if(perso==NULL){
|
|
printf("personne");return;
|
|
}
|
|
if(ParenthesesVraiNom)printf("(");
|
|
printf("%s", perso->nom);
|
|
if(perso->mere !=NULL){
|
|
printf(", enfant de ");
|
|
printVraiNom(perso->mere);
|
|
if(perso->pere !=NULL){
|
|
printf(" et de ");
|
|
printVraiNom(perso->pere);
|
|
}
|
|
} else if (perso->pere != NULL){
|
|
printf(", enfant de ");
|
|
printVraiNom(perso->pere);
|
|
}
|
|
if(ParenthesesVraiNom)printf(")");
|
|
}
|
|
|
|
int printNthGP(struct personnage* racine, int hauteur, int dejafait){
|
|
if(racine==NULL)return 0;
|
|
if(hauteur==0){
|
|
printf(dejafait?", %s":"%s", racine->nom);
|
|
return dejafait+1;
|
|
} else {
|
|
if(racine->mere !=NULL)
|
|
if(racine->pere !=NULL)
|
|
return printNthGP(racine->mere, hauteur-1, printNthGP(racine->pere, hauteur-1, dejafait));
|
|
else
|
|
return printNthGP(racine->mere, hauteur-1, dejafait);
|
|
else if (racine->pere != NULL)
|
|
return printNthGP(racine->pere, hauteur-1, dejafait);
|
|
return dejafait;
|
|
}
|
|
}
|
|
|
|
|
|
void dumpAncetres(struct personnage* racine){
|
|
if(racine==NULL)return;
|
|
printf("Ancêtres de %s\n", racine->nom);
|
|
|
|
printf("Parents connus: ");
|
|
if(printNthGP(racine, 1, 0)){
|
|
int h = 2;
|
|
printf("\nGrand-parents connus : ");
|
|
while(printNthGP(racine, h, 0)){
|
|
h++;
|
|
printf("\nArrière-");
|
|
for(int i=3;i<h;i++)printf("arrière-");
|
|
printf("grand-parents connus : ");
|
|
}
|
|
printf("aucun\n");
|
|
} else {
|
|
printf("aucun\n");
|
|
}
|
|
|
|
|
|
printf(".sertecna sed niF\n");
|
|
}
|
|
|
|
/* 17 */
|
|
int dumpNthDescendents(struct personnage* vieux, int gen){
|
|
if(vieux==NULL)return 0;
|
|
int count = 0;
|
|
if(vieux->premierEnfant == NULL)return 0;
|
|
int sexe = vieux->premierEnfant->pere != vieux;// 1 si femme
|
|
struct personnage* fraterie = vieux->premierEnfant;
|
|
|
|
if(gen==0){
|
|
do{
|
|
printf("%s ", fraterie->nom);
|
|
count++;
|
|
fraterie = (sexe?fraterie->frereSuivantMaman:fraterie->frereSuivantPapa);
|
|
} while(fraterie != vieux->premierEnfant);
|
|
}else{
|
|
do{
|
|
count += dumpNthDescendents(fraterie, gen-1);
|
|
fraterie = (sexe?fraterie->frereSuivantMaman:fraterie->frereSuivantPapa);
|
|
} while(fraterie != vieux->premierEnfant);
|
|
}
|
|
return count;
|
|
|
|
}
|
|
|
|
/* 18 */
|
|
void dumpDescendenceUntil(struct personnage* vieux, int maxh){
|
|
|
|
if(vieux==NULL)return;
|
|
|
|
printf("Déscendence de %s\n", vieux->nom);
|
|
|
|
printf("Enfants connus: ");
|
|
if(dumpNthDescendents(vieux, 0)){
|
|
int h = 1;
|
|
printf("\nPetits-enfants connus : ");
|
|
while(dumpNthDescendents(vieux, h) || h>maxh){
|
|
h++;
|
|
printf("\nArrière-");
|
|
for(int i=2;i<h;i++)printf("arrière-");
|
|
printf("petits-enfants connus : ");
|
|
}
|
|
printf("aucun\n");
|
|
} else {
|
|
printf("aucun\n");
|
|
}
|
|
|
|
|
|
printf(".ecnedecsed al ed niF\n");
|
|
|
|
}
|
|
|
|
/* 19 */
|
|
int estSMoinsGeneration(struct personnage* moi, struct personnage* autre, int limit){
|
|
if(moi==NULL || autre==NULL)return 0;
|
|
if(limit==0)return 1;// On a fait trop de tours de récursivité ! Forcément une problème.
|
|
if(moi->premierEnfant == NULL)return 0;
|
|
int sexe = moi->premierEnfant->pere != moi;// 1 si femme
|
|
struct personnage* fraterie = moi->premierEnfant;
|
|
|
|
|
|
do{
|
|
if(fraterie==autre)return 1;
|
|
if(estSMoinsGeneration(fraterie,autre,limit-1))
|
|
return 1;
|
|
fraterie = (sexe?fraterie->frereSuivantMaman:fraterie->frereSuivantPapa);
|
|
} while(fraterie != moi->premierEnfant);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int countPersos(struct personnage* liste){
|
|
int counter = 0;
|
|
while(liste!=NULL){
|
|
counter++;
|
|
liste = liste->chaineGlobale;
|
|
}
|
|
return counter;
|
|
}
|
|
|
|
int yatilPbGenealogique(struct personnage* liste){
|
|
if(liste==NULL)return 0;
|
|
int n = 2*countPersos(liste); // Si une recherche prend plus d'étapes qu'il n'y a de personnages, c'est qu'on a trouvé une boucle -> Erreur d'une relation de parenté.
|
|
while(liste->chaineGlobale!=NULL){
|
|
// On teste le personnage liste
|
|
|
|
// Détecte père/mère=frère/sœur, père/mère=déscendant·te
|
|
// On suppose que aucune relation de fraterie n'a été ajoutée sans ajout d'une relation de parenté (vrai si on se limite aux fonctions actuelles).
|
|
if(estSMoinsGeneration(liste, liste, n))return 1;
|
|
|
|
liste = liste->chaineGlobale;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* 20 */
|
|
void freeListe(struct personnage* origin){
|
|
struct personnage* ori2 = origin;
|
|
while(ori2!=NULL){
|
|
origin = ori2->chaineGlobale;
|
|
if(ori2->shouldFreeNom)free(ori2->nom);
|
|
free(ori2);
|
|
ori2 = origin;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
///// Main pour les tests
|
|
void loadTestRegistry(struct personnage** liste){
|
|
addRegistryEntry(liste ,"Brandon","Jihair","Saoul-Helene");
|
|
addRegistryEntry(liste,"Jessica","Jihair","Saoul-Helene");
|
|
addRegistryEntry(liste,"Jennifer","Jihair","Saoul-Helene");
|
|
addRegistryEntry(liste,"Jonatan","Huggy","Pamella");
|
|
addRegistryEntry(liste,"Brenda","Huggy","Pamella");
|
|
addRegistryEntry(liste,"Kevin","Huggy", "Pamella");
|
|
addRegistryEntry(liste,"Jacques",NULL, NULL);
|
|
addRegistryEntry(liste,"Valery","Jonathan","Jennifer");
|
|
addRegistryEntry(liste,"Georges","Jonathan","Jennifer");
|
|
addRegistryEntry(liste,"François","Jonathan","Jessica");
|
|
addRegistryEntry(liste,"Charles","Kevin","Jessica");
|
|
}
|
|
int mainTests(){
|
|
|
|
struct personnage* liste = NULL;
|
|
|
|
loadTestRegistry(&liste);
|
|
|
|
// Entrée rendant la structure incohérente.
|
|
//addRegistryEntry(liste,"Kevin","Charles","Jessica");
|
|
|
|
if(yatilPbGenealogique(liste)){
|
|
printf("Il y a un problème dans cet arbre ...\n");
|
|
return 42;
|
|
}
|
|
dumpState(liste);
|
|
|
|
orderPersos(&liste);
|
|
|
|
printVraiNom(liste->chaineGlobale->chaineGlobale);
|
|
printf("\n");
|
|
dumpAncetres(liste->chaineGlobale->chaineGlobale);
|
|
dumpDescendenceUntil(getByName(liste, "Jihair"),3);
|
|
printf("\n");
|
|
dumpState(liste);
|
|
|
|
|
|
|
|
freeListe(liste);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void printHelp(){
|
|
printf("Bienvenue sur l'interface pour regarder votre série préférée.\n");
|
|
printf("'n $nom' pour ajouter un personnage;\n");
|
|
printf("'p $père' déclare un nouvel enfant à son père;\n");
|
|
printf("'m $mère' déclare un nouvel enfant à sa mère;\n");
|
|
printf("'c' afficher l'état actuel;\n");
|
|
printf("'e' demande d'une entrée de registre;\n");
|
|
printf("'P $enfant' suppression d'un lien père-enfant;\n");
|
|
printf("'M $enfant' suppression d'un lien mère-enfant;\n");
|
|
printf("'o' trier la liste par ordre alphabétique;\n");
|
|
printf("'v $nom' affiche le nom COMPLET d'un personnage;\n");
|
|
printf("'a $nom' affiche les ancètres de génération donnée d'un personnage;\n");
|
|
printf("'A $nom' affiche tous les ancètres d'un personnage;\n");
|
|
printf("'d $nom' affiche les déscendants d'une génération donnée d'un personnage\n");
|
|
printf("'D $nom' affiche les déscendants jusqu'à une génération donnée d'un personnage;\n");
|
|
printf("'x' vérifie la cohérence du graphe généalogique.;\n");
|
|
printf("'l' charge les données de la fiche;\n");
|
|
printf("'h' pour réavoir ce message;\n");
|
|
printf("'q' pour quitter (vous ne vous amusez pas ?)\n");
|
|
}
|
|
|
|
int main(){
|
|
|
|
struct personnage* liste = NULL;
|
|
char c;
|
|
char p1[NameLength+1], p2[NameLength+1];
|
|
struct personnage *pp1, *pp2;
|
|
char* newName;
|
|
int pg;
|
|
|
|
printHelp();
|
|
|
|
while(1){
|
|
printf("Commande ? ");
|
|
c = getchar();
|
|
getchar();// On bouffe l'espace ou le retour à la ligne
|
|
|
|
switch(c){
|
|
case 'n':
|
|
scanf(NameLengthScanf, p1);getchar();
|
|
p1[NameLength] = '\0';
|
|
newName = malloc((strlen(p1)+1)*sizeof(char));
|
|
if(newName==NULL)
|
|
goto mallocErr;
|
|
|
|
strcpy(newName, p1);
|
|
newUnrelatedM(&liste, newName, 1);
|
|
|
|
printf("Le personnage %s a été créé.\n", newName);
|
|
|
|
break;
|
|
case 'p':
|
|
scanf(NameLengthScanf, p1);getchar();
|
|
p1[NameLength] = '\0';
|
|
|
|
pp1 = getByName(liste, p1);
|
|
if(pp1==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p1);
|
|
break;
|
|
}
|
|
printf("Qui a la chance d'avoir %s comme papa ? ", p1);
|
|
scanf(NameLengthScanf, p2);getchar();
|
|
p2[NameLength] = '\0';
|
|
pp2 = getByName(liste, p2);
|
|
if(pp2==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p2);
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
papounet(pp1, pp2);
|
|
printf("%s est l'heureux papounet de %s !\n", p1, p2);
|
|
|
|
break;
|
|
case 'm':
|
|
scanf(NameLengthScanf, p1);getchar();
|
|
p1[NameLength] = '\0';
|
|
|
|
pp1 = getByName(liste, p1);
|
|
if(pp1==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p1);
|
|
break;
|
|
}
|
|
printf("Qui a la chance d'avoir %s comme maman ? ", p1);
|
|
scanf(NameLengthScanf, p2);getchar();
|
|
p2[NameLength] = '\0';
|
|
pp2 = getByName(liste, p2);
|
|
if(pp2==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p2);
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
mamounette(pp1, pp2);
|
|
printf("%s est l'heureuse mamounette de %s !\n", p1, p2);
|
|
|
|
break;
|
|
case 'c':
|
|
dumpState(liste);
|
|
break;
|
|
case 'e':
|
|
askRegistryEntry(&liste);
|
|
break;
|
|
case 'P':
|
|
scanf(NameLengthScanf, p1);getchar();
|
|
p1[NameLength] = '\0';
|
|
|
|
pp1 = getByName(liste, p1);
|
|
if(pp1==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p1);
|
|
break;
|
|
}
|
|
|
|
paspapa(pp1);
|
|
printf("%s est maintenant orphelin de son pére (vous êtes un monstre).\n", p1);
|
|
|
|
break;
|
|
|
|
case 'M':
|
|
scanf(NameLengthScanf, p1);getchar();
|
|
p1[NameLength] = '\0';
|
|
|
|
pp1 = getByName(liste, p1);
|
|
if(pp1==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p1);
|
|
break;
|
|
}
|
|
|
|
pasmaman(pp1);
|
|
printf("%s est maintenant orphelin de sa mère (vous êtes un monstre).\n", p1);
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
orderPersos(&liste);
|
|
printf("La liste des personnages a été triée.\n");
|
|
break;
|
|
|
|
case 'v':
|
|
scanf(NameLengthScanf, p1);getchar();
|
|
p1[NameLength] = '\0';
|
|
|
|
pp1 = getByName(liste, p1);
|
|
if(pp1==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p1);
|
|
break;
|
|
}
|
|
|
|
printVraiNom(pp1);
|
|
printf("\n");
|
|
|
|
break;
|
|
case 'a':
|
|
scanf(NameLengthScanf, p1);getchar();
|
|
p1[NameLength] = '\0';
|
|
|
|
pp1 = getByName(liste, p1);
|
|
if(pp1==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p1);
|
|
break;
|
|
}
|
|
printf("Vous voulez quelle génération ? ");
|
|
scanf("%d", &pg);getchar();
|
|
if(pg<0){
|
|
printf("Ce n'est pas un numéro de génération valide\n");
|
|
break;
|
|
}
|
|
|
|
printf("Ancetres de génération %d : ",pg);
|
|
printNthGP(pp1, pg, 0);
|
|
printf("\n");
|
|
break;
|
|
case 'A':
|
|
scanf(NameLengthScanf, p1);getchar();
|
|
p1[NameLength] = '\0';
|
|
|
|
pp1 = getByName(liste, p1);
|
|
if(pp1==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p1);
|
|
break;
|
|
}
|
|
|
|
dumpAncetres(pp1);
|
|
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
scanf(NameLengthScanf, p1);getchar();
|
|
p1[NameLength] = '\0';
|
|
|
|
pp1 = getByName(liste, p1);
|
|
if(pp1==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p1);
|
|
break;
|
|
}
|
|
printf("Vous voulez quelle génération ? ");
|
|
scanf("%d", &pg);getchar();
|
|
pg++;
|
|
if(pg<=0){
|
|
printf("Ce n'est pas un numéro de génération valide\n");
|
|
break;
|
|
}
|
|
|
|
printf("Ses décendants de génération %d sont : ", pg);
|
|
dumpNthDescendents(pp1, pg);
|
|
printf("\n");
|
|
|
|
break;
|
|
case 'D':
|
|
scanf(NameLengthScanf, p1);getchar();
|
|
p1[NameLength] = '\0';
|
|
|
|
pp1 = getByName(liste, p1);
|
|
if(pp1==NULL){
|
|
printf("Personnne ne répond au nom de %s\n", p1);
|
|
break;
|
|
}
|
|
printf("Vous voulez jusqu'à quelle génération ? ");
|
|
scanf("%d", &pg);getchar();
|
|
pg++;
|
|
if(pg<=0){
|
|
printf("Ce n'est pas un numéro de génération valide\n");
|
|
break;
|
|
}
|
|
|
|
|
|
dumpDescendenceUntil(pp1, pg);
|
|
break;
|
|
|
|
|
|
case 'x':
|
|
if(yatilPbGenealogique(liste))
|
|
printf("Il y a un problème dans cet arbre ...\n");
|
|
else
|
|
printf("Aucun problème de généalogie détéctée.\n");
|
|
break;
|
|
case 'l':
|
|
loadTestRegistry(&liste);
|
|
printf("La liste par défaut a été chargée.\n");
|
|
break;
|
|
case 'h':
|
|
printHelp();
|
|
break;
|
|
case 'q':
|
|
goto fend;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
fend: freeListe(liste);
|
|
return 0;
|
|
|
|
mallocErr: freeListe(liste);
|
|
return 1;
|
|
}
|