En ce qui concerne la boucle de recherche elle doit être bornée par nbjoueurs (20 est juste le nombre maximal supporté).
Sinon, en relation avec ce sujet, il faudrait aussi :
s'assurer que l'on ne puisse pas désigner un joueur déjà éliminé
s'assurer que l'on ne puisse pas choisir en début de partir de dénommer son joueur avec le même pseudo qu'un autre joueur.
Ici, la désignation du joueur à éliminer se fait en tapant son pseudo. On pourrait aussi juste afficher une liste numérotée des joueurs restants en jeu et demander quel numéro de joueur est celui à éliminer.
Il faudrait aussi gérer des saisies composées de plusieurs mots, car %s s'arrêtera au premier.
int joueur_elimine(double nbjoueurs, char joueurElimine[], struct Joueurs *joueurs)
{
// Recherche du n° du joueur éliminé (en faire une petite fonction)
int num_elim = -1 ; // initialisation à une valeur invalide
for (int i = 0 ; i < nbjoueurs ; i++)
{
if (strcmp(joueurElimine, joueurs[i].pseudo) == 0)
num_elim = i;
else if(i<0 || i>19)
printf("Joueur elimine introuvable");
}
return num_elim;
}
//On essaye la fonction
int num_elim = joueur_elimine(nbjoueurs, joueurElimine, &joueurs[20]);
printf("Le joueur %s a ete elimine\n", joueurs[num_elim].pseudo);
joueurs[num_elim].ingame = false;
if(joueurs[num_elim].role == MR_WHITE)
{
printf("Mr.White a ete demasque, il peut encore gagner en devinant le mot principal :\n");
scanf("%s", proposition);
if((random == 1 && strcmp(proposition, motPrincipal1) == 0) || (random == 2 && strcmp(proposition, motPrincipal2) == 0) || (random == 3 && strcmp(proposition, motPrincipal3) == 0))
{
printf("Mr.White gagne la partie !!");
return 0;
}
else{printf("Les civils gagnent la partie !");return 0;}
}
Pour l'instant j'ai 4 belles erreurs de compilation sur la ligne strcmp s.c||In function 'joueur_elimine':| s.c|104|error: stray '\240' in program|
C'est vrai Dlks je devrais gérer les cas que tu mentionne, je vais y aller petit à petit
Au fait j'ai essayé d'écrire exhaustivement les règles pour vous donner une idée plus précise des règles de fonctionnement du jeu :
On demande le nombre de joueurs entre 3 et 20 joueurs. Le nombre de civils est le résultat de l'arrondi supérieur de la division du nombre de joueurs par 2. Le nombre de Mr.White est 1 jusqu'à 10 joueurs puis 2 de 11 à 17 joueurs puis 3 jusqu'à 20 joueurs. On offre la possibilité de moduler le nombre de joueurs tant qu'il y a au moins un undercover ou un Mr.White en les remplaçant soit par des undercover, Mr.White ou civils tant que les civils sont majoritaires ou au moins égaux à la somme des undercover et des Mr.White. On demande alternativement le pseudo des joueurs en leur délivrant au hasard un rôle qui leur est masqué et qui défini le mot qu'ils reçoivent. Les civils obtiennent le mot principal (ex: chaton), les undercover le mot secondaire (ex:chiot) et Mr.White n'a pas de mot. Les tours de jeu commencent par un joueur au hasard sans que Mr.White ne puisse débuter la partie. Chacun propose un mot en relation avec leur mot et à chaque fin de tour un joueur est éliminé à la majorité. La partie se termine si Mr.White est démasqué, il gagne uniquement s'il arrive à deviner le mot principal. Autrement les civils gagnent sauf s'il ne reste qu'un civil en jeu aux côtés des undercover et Mr.White.
Pour l'instant j'ai 4 belles erreurs de compilation sur la ligne strcmp
s.c||In function 'joueur_elimine':| s.c|104|error: stray '\240' in program|
Je crois que cette erreur se produit lorsqu'il y un caractère spécial dans le code. Par exemple si tu utilises `c` au lieu de 'c'. C'est peut-être un caractère non affichable qui provient d'un copier-coller.
Comme tu me l'a suggéré Dlks j'ai réglé le problème que soulève les pseudos identiques et ceux composés d'espaces, j'interdit les premiers et autorise les seconds.
Un problème se pose également sur le joueurElimine mais je ne sais pas comment aborder sa résolution sachant que j'ai le strcmp (qui lie joueurElimine au joueurs[i].pseudo) dans une boucle. La boucle fait parfois plusieurs tours avant de trouver la correspondance donc si on propose un nom qui n'existe pas ou un nom qui a déjà été éliminé je ne peux pas émettre la condition dans la boucle sinon elle ne trouve jamais la correspondance. Une idée ? (Ligne : 321)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <ctype.h>
enum roles { CIVIL, UNDERCOVER, MR_WHITE };
const char * str_role[] = {
[CIVIL] = "Civil",
[UNDERCOVER] = "Undercover",
[MR_WHITE] = "Mr. White"
};
struct Joueurs {
char pseudo[100];
enum roles role;
bool ingame;
} joueurs[20] = { '\0' };
void viderBuffer()
{
int c = 0;
while (c != '\n' && c != EOF)
{
c = getchar();
}
}
int lire(char *chaine, int longueur)
{
// On vide le buffer avant de commencer
fflush (stdin);
char *positionEntree = NULL;
// On lit le texte saisi au clavier
if (fgets(chaine, longueur, stdin) != NULL) // Pas d'erreur de saisie ?
{
positionEntree = strchr(chaine, '\n'); // On recherche l'"Entrée"
if (positionEntree != NULL) // Si on a trouvé le retour à la ligne
{
*positionEntree = '\0'; // On remplace ce caractère par \0
}
else
{
viderBuffer();
}
return 1; // On renvoie 1 si la fonction s'est déroulée sans erreur
}
else
{
viderBuffer();
return 0; // On renvoie 0 s'il y a eu une erreur
}
}
double nombre_joueurs()
{
double nbjoueurs;
do
{
printf("Combien de joueurs sont de la partie ? [3 min, 20 max]\n");
scanf("%lf", &nbjoueurs);
}
while(nbjoueurs<3 || nbjoueurs>20);
return nbjoueurs;
}
void modif_joueurs(double *nbcivils, double *nbundercover, double *nbmrwhite)
{
char choix;
printf("Bienvenue dans la modification de l'equipe, ici se fait l'ajout/suppression.\n");
do
{
printf("Supprimer un Undercover[:U]/Mr.White[:M] au profit d'un civil ? Non[:N]\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'U'&& *nbundercover>0 && *nbmrwhite>0)
{
*nbundercover -= 1;
*nbcivils +=1;
}
else if(choix == 'M'&& *nbmrwhite>0 && *nbundercover>0)
{
*nbmrwhite -= 1;
*nbcivils +=1;
}
else
{
printf("Bien, on continue.\n");
}
if(*nbcivils>*nbundercover+*nbmrwhite+1)
{
printf("Civils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", *nbcivils, *nbundercover, *nbmrwhite);
printf("Ajouter un Undercover[:U]/Mr.White[:M] au depend d'un civil ? Non[:N]\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'U')
{
*nbundercover += 1;
*nbcivils -=1;
}
if(choix == 'M')
{
*nbmrwhite += 1;
*nbcivils -=1;
}
else
{
printf("Voulez-vous continuer la modification ? (:Y/:N)\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'Y')
{
printf("On continue la modification.\n");
printf("Civils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", *nbcivils, *nbundercover, *nbmrwhite);
}
else
{
break;
}
}
}
else
{
break;
}
}while(*nbcivils>=*nbundercover+*nbmrwhite && (*nbundercover!=0 && *nbmrwhite!=0));
}
int main (void)
{//Definition des participants
srand(time(NULL));
double nbjoueurs, nbcivils, nbundercover, nbmrwhite;
nbjoueurs = nombre_joueurs();
nbcivils=ceil(nbjoueurs/2);
if(nbjoueurs<11)
nbmrwhite=1;
else if(nbjoueurs>=11 && nbjoueurs<17)
nbmrwhite=2;
else
nbmrwhite=3;
nbundercover=nbjoueurs-nbcivils-nbmrwhite;
printf("Joueurs : %0.lf\n_____________\nCivils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", nbjoueurs, nbcivils, nbundercover, nbmrwhite);
//Ajout, Supression de joueurs
modif_joueurs(&nbcivils, &nbundercover, &nbmrwhite);
printf("Joueurs : %0.lf\n_____________\nCivils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", nbjoueurs, nbcivils, nbundercover, nbmrwhite);
//Attribution des pseudos
for(int i=0; i<nbjoueurs; i++)
for(unsigned long long int j=0; j<sizeof(joueurs[i].pseudo[100]);j++)
{
printf("Donnez le nom du joueur %d\n",i+1);
lire(&joueurs[i].pseudo[j], 100);
for(int k=nbjoueurs-1; k>0; k--)
{
if(strcmp(&joueurs[i].pseudo[j], &joueurs[i-k].pseudo[j]) == 0)
{
i--;
printf("Vous ne pouvez donner 2 noms de joueurs identique.\n");
}
}
}
//Attribution des rôles exhaustivement
int j = 0;
for (int i = 0; i < nbcivils; i++)
joueurs[j++].role = CIVIL;
for (int i = 0; i < nbundercover; i++)
joueurs[j++].role = UNDERCOVER;
for (int i = 0; i < nbmrwhite; i++)
joueurs[j++].role = MR_WHITE;
//Mélange des rôles https://fr.wikipedia.org/wiki/M%C3%A9lange_de_Fisher-Yates
for (int i = nbjoueurs - 1; i >= 1; i--) {
int j = rand() % (int)nbjoueurs;
enum roles temp = joueurs[i].role;
joueurs[i].role = joueurs[j].role;
joueurs[j].role = temp;
}
//Affichage des pseudos & rôles
for (int i = 0; i < nbjoueurs; i++)
printf("Joueur %s - role %s\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
//Ecriture des mots principaux/secondaires dans le fichier .txt
FILE* fichier = NULL;
fichier = fopen("undercover.txt", "w+");
if (fichier != NULL)
{
int nombreDeLignes = 3;
char motPrincipal1[] = "Chat", motSecondaire1[] = "Chien", motPrincipal2[] = "Fast_&_Furious", motSecondaire2[] = "Need_for_speed", motPrincipal3[] = "Faucon", motSecondaire3[] = "Aigle";
size_t taillemotPrincipal1 = sizeof(motPrincipal1), taillemotSecondaire1 = sizeof(motSecondaire1), taillemotPrincipal2 = sizeof(motPrincipal2), taillemotSecondaire2 = sizeof(motSecondaire2), taillemotPrincipal3 = sizeof(motPrincipal3), taillemotSecondaire3 = sizeof(motSecondaire3);
fprintf(fichier,"%s %s\n", motPrincipal1, motSecondaire1);
fprintf(fichier,"%s %s\n", motPrincipal2, motSecondaire2);
fprintf(fichier,"%s %s\n", motPrincipal3, motSecondaire3);
char lireMotPrincipal1[taillemotPrincipal1], lireMotSecondaire1[taillemotSecondaire1], lireMotPrincipal2[taillemotPrincipal2], lireMotSecondaire2[taillemotSecondaire2], lireMotPrincipal3[taillemotPrincipal3], lireMotSecondaire3[taillemotSecondaire3];
rewind(fichier);
fscanf(fichier, "%s %s", lireMotPrincipal1, lireMotSecondaire1);
fscanf(fichier, "%s %s", lireMotPrincipal2, lireMotSecondaire2);
fscanf(fichier, "%s %s", lireMotPrincipal3, lireMotSecondaire3);
//Attribution des mots de manière aléatoire en gardant la logique de répartition (Civil = motprincipal, Undercover = motsecondaire, Mr.White = pas de mots)
int random = (rand() % nombreDeLignes)+1;
if(random == 1)
{
for (int i = 0; i <nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal1);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire1);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else if(random == 2)
{
for (int i = 0; i <nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal2);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire2);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else if(random == 3)
{
for (int i = 0; i <nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal3);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire3);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else
{
printf("Hors random");
}
//Mélange d'ordre de passage des joueurs dans le jeu
int i = 1;
for(int j = nbjoueurs-1; j >= 1; j--)
{
i = (rand()%(int)nbjoueurs);
struct Joueurs temp = joueurs[i];
joueurs[i] = joueurs[j];
joueurs[j] = temp;
//On impose que Mr.White ne puisse commencer la partie donc on remélange s'il est en position 0
if (joueurs[0].role == MR_WHITE)
{
while (joueurs[i].role == MR_WHITE)
i++;
struct Joueurs temp = joueurs[0];
joueurs[0] = joueurs[i];
joueurs[i] = temp;
}
}
int tour, manche;
char proposition[100];
char joueurElimine[100];
for(int i=0;i<nbjoueurs; i++)
{
joueurs[i].ingame = true;
}
//Il reste à rajouter les conditions : s'il reste un seul civil et qu'il reste au moins un undercover et un Mr.White, les undercover gagnent la partie
//Et si tout les civils ET les undercover ont ete elimines, Mr.White gagne la partie
for(manche=0; manche<nbjoueurs; manche++)
{
int joueursEnJeu = (int)nbjoueurs-manche;
if(manche>0)
printf("Il reste donc %d joueurs en jeu\n", joueursEnJeu);
for(tour=0; tour<nbjoueurs; tour++)
{//Tour de jeu : Un joueur propose un mot à l'équipe
if(joueurs[tour].ingame)
{
printf("Le joueur %s propose un mot :\n", joueurs[tour].pseudo);
lire(proposition, 100);
}
}//Après enquête et concertation l'équipe décide d'éliminer un joueur
printf("Il est maintenant temps d'eliminer le joueur qui vous parait suspect\n");
printf("Apres concertation les joueurs ont decides d'eliminer le joueur :\n");
lire(joueurElimine, 100);
int j=-1;
for(int i=0; i<nbjoueurs; i++)
{
if(strcmp(joueurElimine, joueurs[i].pseudo)==0)
j=i;
}
printf("Le joueur %s a ete elimine\n", joueurs[j].pseudo);
joueurs[j].ingame = false;
if(joueurs[j].role == MR_WHITE)
{
printf("Mr.White a ete demasque, il peut encore gagner en devinant le mot principal :\n");
scanf("%s", proposition);
if((random == 1 && strcmp(proposition, motPrincipal1) == 0) || (random == 2 && strcmp(proposition, motPrincipal2) == 0) || (random == 3 && strcmp(proposition, motPrincipal3) == 0))
{
printf("Mr.White gagne la partie !!");
return 0;
}
else{printf("Les civils gagnent la partie !");return 0;}
}
else
{
printf("Next round\n");
}
for(int i=0; i<nbjoueurs; i++)
{
if(joueurs[i].ingame)
{
printf("Il reste en jeu les joueurs %s\n", joueurs[i].pseudo);
}
}
}
fclose(fichier);
}
else
{
printf("Impossible d'ouvrir le fichier undercover.txt");
}
return 0;
}
Tu dois lire la proposition au clavier tant qu'elle ne correspond pas à un joueur existant (strcmp() == 0) non éliminé (ingame == true).
Cela nécessite de gérer une boucle tant que ces deux conditions ne sont pas respectées.
Tu as intérêt à te faire une fonction int saisie_joueur_a_eliminer(struct Joueurs * joueurs, int nbjoueurs); qui retourne l'index du joueur qui sera éliminé pour ce tour de jeu.
for(int i=0; i<nbjoueurs; i++)
for(unsigned long long int j=0; j<sizeof(joueurs[i].pseudo[100]);j++)
{
printf("Donnez le nom du joueur %d\n",i+1);
lire(&joueurs[i].pseudo[j], 100);
for(int k=nbjoueurs-1; k>0; k--)
{
if(strcmp(&joueurs[i].pseudo[j], &joueurs[i-k].pseudo[j]) == 0)
{
i--;
printf("Vous ne pouvez donner 2 noms de joueurs identique.\n");
}
}
}
Tu manques vraiment de bases en C, sachant que ta fonction lire() prend en paramètre un char * (edit: et un int), et que strcmp() prend deux char *.
Correction:
int i=0;
do {
printf("Donnez le nom du joueur %d\n",i+1);
lire(joueurs[i].pseudo,100);
int j;
for(j=i-1;j>=0;j--)
if(strcmp(joueurs[i].pseudo,joueurs[j].pseudo)==0) {
printf("Vous ne pouvez donner 2 noms de joueurs identiques.\n");
break;
}
if(j<0)
i++;
} while(i<nbjoueurs);
Et, franchement, des quantités de personne en double
- Edité par edgarjacobs 21 novembre 2022 à 18:29:55
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
C'est vrai edgard je manque de bases en C c'est pour ça que je m'entraine et j'avais résolu temporairement la solution des pseudos identiques avec ma proposition.
Je suis content que tu me proposes une correction et je verrai demain comment faire en sorte qu'elle ne me sorte plus de Warnings : s.c|199|warning: this 'for' clause does not guard... [-Wmisleading-indentation]| s.c|204|note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'| ||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|
Pour la question des joueurs à éliminer j'ai commencé à faire la fonction qui marche tant qu'on ne donne pas un joueurElimine qui n'existe pas.
Encore une fois l'utilisation du goto n'est sûrement pas adapté (je crois qu'on s'en sert plus dans les macros) mais elle me simplifie drôlement la vie.
int saisie_joueur_a_eliminer(struct Joueurs *joueurs, int nbjoueurs, char* joueurElimine)
{
int j = -1;
for(int i=0; i<nbjoueurs; i++)
{ boucle:
if(strcmp(joueurElimine, joueurs[i].pseudo)==0 && !joueurs[i].ingame)
{
printf("Le joueur a deja ete elimine. Un autre svp :\n");
lire(joueurElimine, 100);
i--;
goto boucle;
}
else if (strcmp(joueurElimine, joueurs[i].pseudo)==0 && joueurs[i].ingame)
{
j=i;
printf("Le joueur %s a ete elimine\n", joueurs[j].pseudo);
joueurs[j].ingame = false;
}
}
return j;
}
Dans le main :
for(manche=0; manche<nbjoueurs; manche++)
{
int joueursEnJeu = (int)nbjoueurs-manche;
if(manche>0)
printf("Il reste donc %d joueurs en jeu\n", joueursEnJeu);
for(tour=0; tour<nbjoueurs; tour++)
{//Tour de jeu : Un joueur propose un mot à l'équipe
if(joueurs[tour].ingame)
{
printf("Le joueur %s propose un mot :\n", joueurs[tour].pseudo);
lire(proposition, 100);
}
}//Après enquête et concertation l'équipe décide d'éliminer un joueur
int j=-1;
printf("Il est maintenant temps d'eliminer le joueur qui vous parait suspect\n");
printf("Apres concertation les joueurs ont decides d'eliminer le joueur :\n");
lire(joueurElimine, 100);
//----------------------------------------------------------------------------------------------------------------------------------------------------------
j = saisie_joueur_a_eliminer(joueurs, nbjoueurs, joueurElimine);
if(joueurs[j].role == MR_WHITE)
{
printf("Mr.White a ete demasque, il peut encore gagner en devinant le mot principal :\n");
scanf("%s", proposition);
if((random == 1 && strcmp(proposition, motPrincipal1) == 0) || (random == 2 && strcmp(proposition, motPrincipal2) == 0) || (random == 3 && strcmp(proposition, motPrincipal3) == 0))
{
printf("Mr.White gagne la partie !!");
return 0;
}
else
{
printf("Les civils gagnent la partie !");
return 0;
}
}
else
{
printf("Next round\n");
}
for(int i=0; i<nbjoueurs; i++)
{
if(joueurs[i].ingame)
{
printf("Il reste en jeu les joueurs %s\n", joueurs[i].pseudo);
}
}
}
fclose(fichier);
Pour contourner si le pseudo existe je pourrai en effet demander de rentrer un nombre plutôt qu'un pseudo, en listant les joueurs à l'utilisateur.
Mais en gardant la possibilité d'entrer les pseudos je vais devoir trouver comment faire.
Sur saisie_joueur_a_eliminer() je t'avais proposé un prototype :
int saisie_joueur_a_eliminer(struct Joueurs *joueurs, int nbjoueurs);
qui gère la saisie, fait les vérifications et retourne un index de joueur valide à éliminer.
Tu proposes un autre prototype où tu passes une proposition d'élimination dans un 3ème paramètre résultant d'une première lecture... autant tout mettre dans la fonction, non (y compris la lecture initiale) ?
Ensuite, ton algorithme n'est pas très cohérent.
Imagine que tu as une pile de cartes où sont inscrits les noms des joueurs et une case cochée s'ils sont éliminés.
Voilà une description d'un algorithme qui pourrait résoudre ce problème :
je demande le nom d'un joueur à éliminer
je parcours le paquet de cartes à partir du début et jusqu'à la fin
pour chaque carte, je vérifie si la carte porte ce nom
si oui : je vérifie si la carte indique qu'il est déjà éliminé : (i) si oui, je me plains d'une erreur, j'arrête de parcourir le paquet et je repars en 1. ; (ii) sinon, j'ai terminé, j'arrête de parcourir le paquet et je vais en 7.
sinon, je continue à parcourir le paquet
si j'arrive au bout du paquet et qu'aucune carte ne porte ce nom, je me plains d'une erreur et je boucle en 1.
je retourne le numéro de la carte
Ta fonction ne fait pas cela. Elle ne parcourt la liste des joueurs qu'une seule fois, alors qu'en cas d'erreur, elle doit être revue de nouveau du début.
Tu peux très bien faire tout cela sans goto. Essaye.
Ce n'est pas vrai que cela te simplifie la vie. Dans quel cours as-tu appris à faire des boucles avec goto ?
Vois ton cours, manuel de référence ou des tutoriels sur les boucles en C et applique ce qui y figure.
Lorsque tu as un bloc de trucs que tu dois répéter, tu dois avoir des conditions de sortie pour éviter une boucle infinie.
tu peux gérer cela avec
while (condition) { /* contenu de la boucle */ }
si tu peux évaluer ta condition de sortie à l'entrée du bloc (tu entres dans le bloc seulement si la condition est vraie et tu le répètes tant que la condition est vraie).
une boucle for fonctionne, d'ailleurs, de la même façon et tu n'as aucune difficulté à l'utiliser.
tu peux aussi gérer cela avec une boucle
do { /* contenu de la boucle */ } while (condition);
si tu peux évaluer ta condition de sortie après une première exécution du bloc et en fin de bloc (tu entres dans le bloc et tu le répètes tant que la condition est vraie).
et il y a une variante que je t'ai mentionnée, que tu peux utiliser quand tu sais que tu dois répéter le bloc et que tes conditions de sortie peuvent être évaluées à différents endroits dans ton bloc et que ce n'est pas pratique de regrouper leur évaluation au début du bloc ou à la fin. Tu peux alors écrire une boucle infinie et définir les conditions de sortie dans le code de la boucle en sortant de celle-ci avec break; lorsque tu peux faire cette évaluation.
while (1) { // boucle infinie
/* faire des choses */
if (truc)
break; // sortir
/* faire d'autres choses */
}
Je t'ai donné un exemple de code ici, qui comprend une boucle infinie while (1) qui utilise break; (pour sortir de la boucle quand il le faut) et continue; (pour continuer sur la prochaine itération de la boucle sans exécuter la suite du bloc sur cette itération). Ce sont des sortes de "goto". Le premier saute à l'extérieur de la boucle après celle-ci. Le second saute au début de la boucle immédiatement sans attendre la fin de bloc.
@edgardjacobs : Ah oui effectivement les parenthèses règlent le warning. C'est vrai que ta fonction est plus claire.
@Dlks : Oui j'ai rajouté joueurElimine dans le prototype de la fonction autrement je ne m'en sortais pas. Tu as raison autant tout grouper dedans, du premier appel au retour d'indice.
J'ai essayé de reproduire ton algorithme que je vais poster plus bas, il fonctionne comme souhaité. Je prends bonne note de la façon dont tu les rédigent avant de commencer à coder.
Alors j'utilise les boucles goto depuis que j'ai 10 ans sur ma première calculette programmable, puis je m'en suis servi dans AHK pour faire des macros sur un MMORPG. Je crois l'avoir revu sur un cours en C++ d'openclassroom ce qui m'a donné envie de l'utiliser.
Effectivement il est écrit dans le cours en C que toute les boucles sont gérables avec des for, while, do...while.
Voici donc ma proposition avec tes indications :
int saisie_joueur_a_eliminer(struct Joueurs *joueurs, int nbjoueurs, char* joueurElimine)
{
int j = -1;
//1.Je demande le nom d'un joueur à éliminer
printf("Il est maintenant temps d'eliminer le joueur qui vous parait suspect\n");
printf("Apres concertation les joueurs ont decides d'eliminer le joueur :\n");
lire(joueurElimine, 100);
//2.Je parcours le paquet de cartes à partir du début et jusqu'à la fin
for(int i=0; i<nbjoueurs; i++)
{
//3.Pour chaque carte, je vérifie si la carte porte ce nom.
if(strcmp(joueurElimine, joueurs[i].pseudo) == 0)
{
//4.Si oui: je vérifie si la carte indique qu'il est déjà éliminé.
if(!joueurs[i].ingame)
{
//(i.)Si oui, je me plains d'une erreur, j'arrête de parcourir le paquet et je vais en 7.
printf("Erreur : Le joueur a deja ete elimine.\n");
break;
}
//(ii.)Sinon, j'ai terminé, j'arrête de parcourir le paquet et je vais en 7.
else
{
j=i;
joueurs[i].ingame = false;
return j;
}
}
//5.Sinon je continue à parcourir le paquet
}//6.Si j'arrive au bout du paquet et qu'aucune carte ne porte ce nom, je me plains d'eune erreur et je boucle en 1.
printf("Erreur : Le joueur designe est introuvable.\n");
saisie_joueur_a_eliminer(joueurs, nbjoueurs, joueurElimine);
return j;
}
Et dans le main :
for(manche=0; manche<nbjoueurs; manche++)
{
int joueursEnJeu = (int)nbjoueurs-manche;
if(manche>0)
printf("Il reste donc %d joueurs en jeu\n", joueursEnJeu);
for(tour=0; tour<nbjoueurs; tour++)
{//Tour de jeu : Un joueur propose un mot à l'équipe
if(joueurs[tour].ingame)
{
printf("Le joueur %s propose un mot :\n", joueurs[tour].pseudo);
lire(proposition, 100);
}
}//Après enquête et concertation l'équipe décide d'éliminer un joueur
//----------------------------------------------------------------------------------------------------------------------------------------------------------
j = saisie_joueur_a_eliminer(joueurs, nbjoueurs, joueurElimine);
if(joueurs[j].role == MR_WHITE)
{
printf("Mr.White a ete demasque, il peut encore gagner en devinant le mot principal :\n");
scanf("%s", proposition);
if((random == 1 && strcmp(proposition, motPrincipal1) == 0) || (random == 2 && strcmp(proposition, motPrincipal2) == 0) || (random == 3 && strcmp(proposition, motPrincipal3) == 0))
{
printf("Mr.White gagne la partie !!");
return 0;
}
else
{
printf("Les civils gagnent la partie !");
return 0;
}
}
else
{
printf("Next round\n");
}
for(int i=0; i<nbjoueurs; i++)
{
if(joueurs[i].ingame)
{
printf("Il reste en jeu les joueurs %s\n", joueurs[i].pseudo);
}
}
}
Merci de votre aide les gars.
Je vais devoir maintenant gérer les conditions : - Le jeu se termine si : 1) Il ne reste que Mr.White (il gagne) 2) Il ne reste que Mr.White, au moins un undercover et un seul civil (undercover gagne) 3) --déjà traité : si Mr.White est démasqué, il peut essayer de deviner le mot principal (vrai=il gagne, faux=les civils gagnent). Pour la condition 1) elle est à tester seulement s'il y a au moins un Mr.White en début de partie Pour la condition 2) elle est à tester seulement s'il y a au moins un Undercover en début de partie
(Exemple sur la condition 2) : Pour dénombrer les rôles (civils: 1, undercover: 2, mr.white: 3) doit-on : a) faire une boucle sur nbjoueurs b) vérifier si (joueurs[i].ingame && (str_role[joueurs[i].role] == 1) ==1 && (str_role[joueurs[i].role] == 2) >0) c) terminer la partie en désignant les undercover gagnants
int saisie_joueur_a_eliminer(struct Joueurs *joueurs, int nbjoueurs) {
int j = -1;
char joueurElimine[256];
printf("Il est maintenant temps d'eliminer le joueur "
"qui vous parait suspect\n");
printf("Apres concertation saisissez son pseudo parmi "
"les joueurs encore en jeu :\n");
for (int i = 0; i < nbjoueurs; i++)
if (joueurs[i].ingame)
printf("%s\n", joueurs[i].pseudo);
while (1) {
//1.
printf("\nQuel est le pseudo du joueur que vous eliminez :\n");
lire(joueurElimine, 100);
//2.
int i;
for (i = 0; i < nbjoueurs; i++) {
//3.
if (strcmp(joueurElimine, joueurs[i].pseudo) == 0) {
//4.
if (!joueurs[i].ingame) {
//(i)
printf("Erreur : Le joueur a deja "
"ete elimine.\n");
break;
}
//(ii)
else {
j = i;
break; // sortir du for
}
}
//5.
}
//6.
if (j == -1 && i == nbjoueurs)
printf("Erreur : Le joueur designe est introuvable.\n");
else if (j != -1)
break; // sortir du while
}
//7.
return j;
}
et dans main :
int j;
j = saisie_joueur_a_eliminer(joueurs, nbjoueurs);
joueurs[j].ingame = false;
Sur ta question additionnelle.
Pour gérer les conditions de fin de partie selon les règles que tu définis, il parait évident que tu dois d'abord totaliser le nombre de CIVIL, UNDERCOVER et MR_WHITE à la fin de chaque élimination, et ensuite déterminer si on on est dans l'un des cas de fin de partie selon les conditions à réunir.
Malinx Dlks ! Effectivement comptabiliser le nombre de Civils, Undercover, Mr_White permet rapidement de poser les conditions !
Super ta fonction au passage.
Je crois qu'on y est merci les amis
EDIT après indentation correcte :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <ctype.h>
enum roles { CIVIL, UNDERCOVER, MR_WHITE };
const char * str_role[] = {
[CIVIL] = "Civil",
[UNDERCOVER] = "Undercover",
[MR_WHITE] = "Mr. White"
};
struct Joueurs {
char pseudo[100];
enum roles role;
bool ingame;
} joueurs[20] = { '\0' };
void viderBuffer()
{
int c = 0;
while (c != '\n' && c != EOF)
{
c = getchar();
}
}
int lire(char *chaine, int longueur)
{
// On vide le buffer avant de commencer
//fflush (stdin);
char *positionEntree = NULL;
// On lit le texte saisi au clavier
if (fgets(chaine, longueur, stdin) != NULL) // Pas d'erreur de saisie ?
{
positionEntree = strchr(chaine, '\n'); // On recherche l'"Entrée"
if (positionEntree != NULL) // Si on a trouvé le retour à la ligne
{
*positionEntree = '\0'; // On remplace ce caractère par \0
}
else
{
viderBuffer();
}
return 1; // On renvoie 1 si la fonction s'est déroulée sans erreur
}
else
{
viderBuffer();
return 0; // On renvoie 0 s'il y a eu une erreur
}
}
double nombre_joueurs()
{
double nbjoueurs;
do
{
printf("Combien de joueurs sont de la partie ? [3 min, 20 max]\n");
scanf("%lf", &nbjoueurs);
}
while(nbjoueurs<3 || nbjoueurs>20);
return nbjoueurs;
}
void modif_joueurs(double *nbcivils, double *nbundercover, double *nbmrwhite)
{
char choix;
printf("Bienvenue dans la modification de l'equipe, ici se fait l'ajout/suppression.\n");
do
{
printf("Supprimer un Undercover[:U]/Mr.White[:M] au profit d'un civil ? Non[:N]\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'U'&& *nbundercover>0 && *nbmrwhite>0)
{
*nbundercover -= 1;
*nbcivils +=1;
}
else if(choix == 'M'&& *nbmrwhite>0 && *nbundercover>0)
{
*nbmrwhite -= 1;
*nbcivils +=1;
}
else
{
printf("Bien, on continue.\n");
}
if(*nbcivils>*nbundercover+*nbmrwhite+1)
{
printf("Civils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", *nbcivils, *nbundercover, *nbmrwhite);
printf("Ajouter un Undercover[:U]/Mr.White[:M] au depend d'un civil ? Non[:N]\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'U')
{
*nbundercover += 1;
*nbcivils -=1;
}
if(choix == 'M')
{
*nbmrwhite += 1;
*nbcivils -=1;
}
else
{
printf("Voulez-vous continuer la modification ? (:Y/:N)\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'Y')
{
printf("On continue la modification.\n");
printf("Civils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", *nbcivils, *nbundercover, *nbmrwhite);
}
else
{
break;
}
}
}
else
{
break;
}
}while(*nbcivils>=*nbundercover+*nbmrwhite && (*nbundercover!=0 && *nbmrwhite!=0));
}
/*
int saisie_joueur_a_eliminer(struct Joueurs *joueurs, int nbjoueurs)
{
char joueurElimine[100];
int j = -1;
//1.Je demande le nom d'un joueur à éliminer
printf("Il est maintenant temps d'eliminer le joueur qui vous parait suspect\n");
printf("Apres concertation les joueurs ont decides d'eliminer le joueur :\n");
lire(joueurElimine, 100);
//2.Je parcours le paquet de cartes à partir du début et jusqu'à la fin
for(int i=0; i<nbjoueurs; i++)
{
//3.Pour chaque carte, je vérifie si la carte porte ce nom.
if(strcmp(joueurElimine, joueurs[i].pseudo) == 0)
{
//4.Si oui: je vérifie si la carte indique qu'il est déjà éliminé.
if(!joueurs[i].ingame)
{
//(i.)Si oui, je me plains d'une erreur, j'arrête de parcourir le paquet et je vais en 7.
printf("Erreur : Le joueur a deja ete elimine.\n");
break;
}
//(ii.)Sinon, j'ai terminé, j'arrête de parcourir le paquet et je vais en 7.
else
{
j=i;
joueurs[i].ingame = false;
return j;
}
}
//5.Sinon je continue à parcourir le paquet
}//6.Si j'arrive au bout du paquet et qu'aucune carte ne porte ce nom, je me plains d'une erreur et je boucle en 1.
printf("Erreur : Le joueur designe est introuvable.\n");
saisie_joueur_a_eliminer(joueurs, nbjoueurs);
return j;
}
*/
int saisie_joueur_a_eliminer(struct Joueurs *joueurs, int nbjoueurs)
{//Correction de Dlks
int j = -1;
char joueurElimine[256];
printf("Il est maintenant temps d'eliminer le joueur qui vous parait suspect\n");
printf("Apres concertation saisissez son pseudo parmi les joueurs encore en jeu : \n");
for (int i = 0; i < nbjoueurs; i++)
if (joueurs[i].ingame)
printf("%s\n", joueurs[i].pseudo);
while (1)
{//1.
printf("\nQuel est le pseudo du joueur que vous eliminez :\n");
lire(joueurElimine, 100);
//2.
int i;
for (i = 0; i < nbjoueurs; i++)
{
if (strcmp(joueurElimine, joueurs[i].pseudo) == 0)
{
if (!joueurs[i].ingame)
{//(i)
printf("Erreur : Le joueur a deja ete elimine.\n");
break;
}
//(ii)
else
{
j = i;
break;
}
}//5.
}//6.
if (j == -1 && i == nbjoueurs)
printf("Le joueur est introuvable.\n");
else if (j != -1)
break;
}//7.
return j;
}
int main (void)
{//Definition des participants
srand(time(NULL));
double nbjoueurs, nbcivils, nbundercover, nbmrwhite;
nbjoueurs = nombre_joueurs();
nbcivils=ceil(nbjoueurs/2);
if(nbjoueurs<11)
nbmrwhite=1;
else if(nbjoueurs>=11 && nbjoueurs<17)
nbmrwhite=2;
else
nbmrwhite=3;
nbundercover=nbjoueurs-nbcivils-nbmrwhite;
printf("Joueurs : %0.lf\n_____________\nCivils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", nbjoueurs, nbcivils, nbundercover, nbmrwhite);
//Ajout, Supression de joueurs
modif_joueurs(&nbcivils, &nbundercover, &nbmrwhite);
printf("Joueurs : %0.lf\n_____________\nCivils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", nbjoueurs, nbcivils, nbundercover, nbmrwhite);
//Attribution des pseudos
/* edgardjacobs trouve ça moche
for(int i=0; i<nbjoueurs; i++)
for(unsigned long long int j=0; j<sizeof(joueurs[i].pseudo[100]);j++)
{
printf("Donnez le nom du joueur %d\n",i+1);
lire(&joueurs[i].pseudo[j], 100);
for(int k=nbjoueurs-1; k>0; k--)
{
if(strcmp(&joueurs[i].pseudo[j], &joueurs[i-k].pseudo[j]) == 0)
{
i--;
printf("Vous ne pouvez donner 2 noms de joueurs identique.\n");
}
}
}
*/
//Ici sa proposition
int i=0;
do{
printf("Donnez le nom du joueur %d\n", i+1);
lire(joueurs[i].pseudo, 100);
int j;
for(j=i-1; j>=0; j--)
{
if(strcmp(joueurs[i].pseudo, joueurs[j].pseudo)==0)
{
printf("Vous ne pouvez donner 2 noms de joueurs identiques.\n");
break;
}
}
if(j<0)
i++;
} while(i<nbjoueurs);
//Attribution des rôles exhaustivement
int j = 0;
for (int i = 0; i < nbcivils; i++)
joueurs[j++].role = CIVIL;
for (int i = 0; i < nbundercover; i++)
joueurs[j++].role = UNDERCOVER;
for (int i = 0; i < nbmrwhite; i++)
joueurs[j++].role = MR_WHITE;
//Mélange des rôles https://fr.wikipedia.org/wiki/M%C3%A9lange_de_Fisher-Yates
for (int i = nbjoueurs - 1; i >= 1; i--)
{
int j = rand() % (int)nbjoueurs;
enum roles temp = joueurs[i].role;
joueurs[i].role = joueurs[j].role;
joueurs[j].role = temp;
}
//Affichage des pseudos & rôles (à cacher lorsqu'on jouera)
for (int i = 0; i < nbjoueurs; i++)
printf("Joueur %s - role %s\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
//Ecriture des mots principaux/secondaires dans le fichier .txt
FILE* fichier = NULL;
fichier = fopen("undercover.txt", "w+");
if (fichier != NULL)
{
int nombreDeLignes = 3;
char motPrincipal1[] = "Chat", motSecondaire1[] = "Chien", motPrincipal2[] = "Fast_&_Furious", motSecondaire2[] = "Need_for_speed", motPrincipal3[] = "Faucon", motSecondaire3[] = "Aigle";
size_t taillemotPrincipal1 = sizeof(motPrincipal1), taillemotSecondaire1 = sizeof(motSecondaire1), taillemotPrincipal2 = sizeof(motPrincipal2), taillemotSecondaire2 = sizeof(motSecondaire2), taillemotPrincipal3 = sizeof(motPrincipal3), taillemotSecondaire3 = sizeof(motSecondaire3);
fprintf(fichier,"%s %s\n", motPrincipal1, motSecondaire1);
fprintf(fichier,"%s %s\n", motPrincipal2, motSecondaire2);
fprintf(fichier,"%s %s\n", motPrincipal3, motSecondaire3);
char lireMotPrincipal1[taillemotPrincipal1], lireMotSecondaire1[taillemotSecondaire1], lireMotPrincipal2[taillemotPrincipal2], lireMotSecondaire2[taillemotSecondaire2], lireMotPrincipal3[taillemotPrincipal3], lireMotSecondaire3[taillemotSecondaire3];
rewind(fichier);
fscanf(fichier, "%s %s", lireMotPrincipal1, lireMotSecondaire1);
fscanf(fichier, "%s %s", lireMotPrincipal2, lireMotSecondaire2);
fscanf(fichier, "%s %s", lireMotPrincipal3, lireMotSecondaire3);
//Attribution des mots de manière aléatoire en gardant la logique de répartition (Civil = motprincipal, Undercover = motsecondaire, Mr.White = pas de mots)
int random = (rand() % nombreDeLignes)+1;
if(random == 1)
{
for (int i = 0; i <nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal1);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire1);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else if(random == 2)
{
for (int i = 0; i <nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal2);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire2);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else if(random == 3)
{
for (int i = 0; i <nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal3);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire3);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else
{
printf("Hors random");
}
//Mélange d'ordre de passage des joueurs dans le jeu
int i = 1;
for(int j = nbjoueurs-1; j >= 1; j--)
{
i = (rand()%(int)nbjoueurs);
struct Joueurs temp = joueurs[i];
joueurs[i] = joueurs[j];
joueurs[j] = temp;
//On impose que Mr.White ne puisse commencer la partie donc on remélange s'il est en position 0
if (joueurs[0].role == MR_WHITE)
{
while (joueurs[i].role == MR_WHITE)
i++;
struct Joueurs temp = joueurs[0];
joueurs[0] = joueurs[i];
joueurs[i] = temp;
}
}
int tour, manche;
char proposition[100];
for(int i=0;i<nbjoueurs; i++)
{
joueurs[i].ingame = true;
}
for(manche=0; manche<nbjoueurs; manche++)
{
int joueursEnJeu = (int)nbjoueurs-manche;
if(joueursEnJeu==1)
{
printf("Mr.White remporte la partie !");
return 0;
}
if(manche>0)
printf("Il reste donc %d joueurs en jeu\n", joueursEnJeu);
for(tour=0; tour<nbjoueurs; tour++)
{
//Tour de jeu : Un joueur propose un mot à l'équipe
if(joueurs[tour].ingame)
{
printf("Le joueur %s propose un mot :\n", joueurs[tour].pseudo);
lire(proposition, 100);
}
}
//Après enquête et concertation l'équipe décide d'éliminer un joueur
j = saisie_joueur_a_eliminer(joueurs, nbjoueurs);
joueurs[j].ingame = false;
//On totalise les joueurs après chaque éliminations.
if(joueurs[j].role == CIVIL)
nbcivils--;
if(joueurs[j].role == UNDERCOVER)
nbundercover--;
if(joueurs[j].role == MR_WHITE)
nbmrwhite--;
//Puis on pose les conditions de jeu
if(nbcivils == 1 && nbundercover>=1 && nbmrwhite>=1)
{
printf("Les undercover gagnent la partie !");
return 0;
}
if(joueurs[j].role == MR_WHITE)
{
printf("Mr.White a ete demasque, il peut encore gagner en devinant le mot principal :\n");
lire(proposition, 100);
if((random == 1 && strcmp(proposition, motPrincipal1) == 0) || (random == 2 && strcmp(proposition, motPrincipal2) == 0) || (random == 3 && strcmp(proposition, motPrincipal3) == 0))
{
printf("Mr.White gagne la partie !!");
return 0;
}
else
{
printf("Les civils gagnent la partie !");
return 0;
}
}
else
{
printf("Next round !!\n");
}
}
fclose(fichier);
}
else
{
printf("Impossible d'ouvrir le fichier undercover.txt");
}
return 0;
}
En fait j'ai rajouté le fflush() car sinon il reste un "ENTER" dans le buffer et je ne peux nommer convenablement le joueur 1
Sortie de console :
Combien de joueurs sont de la partie ? [3 min, 20 max]
4
Joueurs : 4
_____________
Civils : 2
Undercover : 1
Mr.White : 1
Bienvenue dans la modification de l'equipe, ici se fait l'ajout/suppression.
Supprimer un Undercover[:U]/Mr.White[:M] au profit d'un civil ? Non[:N]
n
Bien, on continue.
Joueurs : 4
_____________
Civils : 2
Undercover : 1
Mr.White : 1
Donnez le nom du joueur 1
Donnez le nom du joueur 2
S'il y a un "ENTER" dans le buffer, c'est que ton application l'y a mis (probablement un scanf()).
Après chaque scanf() (en fait après chaque utilisation du buffer par une fonction interagissant au clavier avec l'utilisateur et laissant quelque chose dans le buffer, y compris fgets() qui peut laisser des choses selon le cas, ce que tu traites déjà dans lire() - vois ton code) tu dois purger le buffer qui garde toujours, au moins, '\n'.
Tu fais cela avec viderBuffer() dont tu as mis le code dans ton programme et qui est la façon standard de gérer le problème.
Tu ne fais pas cela avant ton fgets() dans ta fonction, car tu ne sais pas dans quel contexte cette fonction est appelée et si le buffer est déjà vide.
J'avais fait des erreurs surtout sur les if..if que je décalais systématiquement même lorsqu'ils n'étaient pas dépendants.
EDIT : Je vais voir ce que je peux fonctionnaliser pour réduire la fonction principale :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <ctype.h>
enum roles { CIVIL, UNDERCOVER, MR_WHITE };
const char * str_role[] = {
[CIVIL] = "Civil",
[UNDERCOVER] = "Undercover",
[MR_WHITE] = "Mr. White"
};
struct Joueurs {
char pseudo[100];
enum roles role;
bool ingame;
} joueurs[20] = { '\0' };
void viderBuffer()
{
int c = 0;
while (c != '\n' && c != EOF)
{
c = getchar();
}
}
int lire(char *chaine, int longueur)
{
// On vide le buffer avant de commencer
//fflush (stdin);
char *positionEntree = NULL;
// On lit le texte saisi au clavier
if (fgets(chaine, longueur, stdin) != NULL) // Pas d'erreur de saisie ?
{
positionEntree = strchr(chaine, '\n'); // On recherche l'"Entrée"
if (positionEntree != NULL) // Si on a trouvé le retour à la ligne
{
*positionEntree = '\0'; // On remplace ce caractère par \0
}
else
{
viderBuffer();
}
return 1; // On renvoie 1 si la fonction s'est déroulée sans erreur
}
else
{
viderBuffer();
return 0; // On renvoie 0 s'il y a eu une erreur
}
}
void nombre_joueurs(double *nbjoueurs, double *nbcivils, double *nbundercover, double *nbmrwhite, struct Joueurs *joueurs)
{
do
{
printf("Combien de joueurs sont de la partie ? [3 min, 20 max]\n");
scanf("%lf", nbjoueurs);
}
while(*nbjoueurs<3 || *nbjoueurs>20);
*nbcivils=ceil(*nbjoueurs/2);
if(*nbjoueurs<11)
*nbmrwhite=1;
else if(*nbjoueurs>=11 && *nbjoueurs<17)
*nbmrwhite=2;
else
*nbmrwhite=3;
*nbundercover=*nbjoueurs-*nbcivils-*nbmrwhite;
for(int i=0;i<*nbjoueurs; i++)
{
joueurs[i].ingame = true;
}
}
void modif_joueurs(double *nbcivils, double *nbundercover, double *nbmrwhite)
{
char choix;
printf("Bienvenue dans la modification de l'equipe, ici se fait l'ajout/suppression.\n");
do
{
printf("Supprimer un Undercover[:U]/Mr.White[:M] au profit d'un civil ? Non[:N]\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'U'&& *nbundercover>0 && *nbmrwhite>0)
{
*nbundercover -= 1;
*nbcivils +=1;
}
else if(choix == 'M'&& *nbmrwhite>0 && *nbundercover>0)
{
*nbmrwhite -= 1;
*nbcivils +=1;
}
else
{
printf("Bien, on continue.\n");
}
if(*nbcivils>*nbundercover+*nbmrwhite+1)
{
printf("Civils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", *nbcivils, *nbundercover, *nbmrwhite);
printf("Ajouter un Undercover[:U]/Mr.White[:M] au depend d'un civil ? Non[:N]\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'U')
{
*nbundercover += 1;
*nbcivils -=1;
}
if(choix == 'M')
{
*nbmrwhite += 1;
*nbcivils -=1;
}
else
{
printf("Voulez-vous continuer la modification ? (:Y/:N)\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'Y')
{
printf("On continue la modification.\n");
printf("Civils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", *nbcivils, *nbundercover, *nbmrwhite);
}
else
{
break;
}
}
}
else
{
break;
}
} while(*nbcivils>=*nbundercover+*nbmrwhite && (*nbundercover!=0 && *nbmrwhite!=0));
viderBuffer();
}
void proposition_joueur(struct Joueurs *joueurs, double *nbjoueurs)
{
int i=0;
do{
printf("Donnez le nom du joueur %d\n", i+1);
lire(joueurs[i].pseudo, 100);
int j;
for(j=i-1; j>=0; j--)
{
if(strcmp(joueurs[i].pseudo, joueurs[j].pseudo)==0)
{
printf("Vous ne pouvez donner 2 noms de joueurs identiques.\n");
break;
}
}
if(j<0)
i++;
} while(i<*nbjoueurs);
}
void affichage_pseudo_roles(double *nbjoueurs, struct Joueurs *joueurs)
{
for (int i = 0; i < *nbjoueurs; i++)
printf("Joueur %s - role %s\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
/*
int saisie_joueur_a_eliminer(struct Joueurs *joueurs, int nbjoueurs)
{
char joueurElimine[100];
int j = -1;
//1.Je demande le nom d'un joueur à éliminer
printf("Il est maintenant temps d'eliminer le joueur qui vous parait suspect\n");
printf("Apres concertation les joueurs ont decides d'eliminer le joueur :\n");
lire(joueurElimine, 100);
//2.Je parcours le paquet de cartes à partir du début et jusqu'à la fin
for(int i=0; i<nbjoueurs; i++)
{
//3.Pour chaque carte, je vérifie si la carte porte ce nom.
if(strcmp(joueurElimine, joueurs[i].pseudo) == 0)
{
//4.Si oui: je vérifie si la carte indique qu'il est déjà éliminé.
if(!joueurs[i].ingame)
{
//(i.)Si oui, je me plains d'une erreur, j'arrête de parcourir le paquet et je vais en 7.
printf("Erreur : Le joueur a deja ete elimine.\n");
break;
}
//(ii.)Sinon, j'ai terminé, j'arrête de parcourir le paquet et je vais en 7.
else
{
j=i;
joueurs[i].ingame = false;
return j;
}
}
//5.Sinon je continue à parcourir le paquet
}//6.Si j'arrive au bout du paquet et qu'aucune carte ne porte ce nom, je me plains d'une erreur et je boucle en 1.
printf("Erreur : Le joueur designe est introuvable.\n");
saisie_joueur_a_eliminer(joueurs, nbjoueurs);
return j;
}
*/
int saisie_joueur_a_eliminer(struct Joueurs *joueurs, int nbjoueurs)
{//Correction de Dlks
int j = -1;
char joueurElimine[256];
printf("Il est maintenant temps d'eliminer le joueur qui vous parait suspect\n");
printf("Apres concertation saisissez son pseudo parmi les joueurs encore en jeu : \n");
for (int i = 0; i < nbjoueurs; i++)
if (joueurs[i].ingame)
printf("%s\n", joueurs[i].pseudo);
while (1)
{//1.
printf("\nQuel est le pseudo du joueur que vous eliminez :\n");
lire(joueurElimine, 100);
//2.
int i;
for (i = 0; i < nbjoueurs; i++)
{
if (strcmp(joueurElimine, joueurs[i].pseudo) == 0)
{
if (!joueurs[i].ingame)
{//(i)
printf("Erreur : Le joueur a deja ete elimine.\n");
break;
}
//(ii)
else
{
j = i;
break;
}
}//5.
}//6.
if (j == -1 && i == nbjoueurs)
printf("Le joueur est introuvable.\n");
else if (j != -1)
break;
}//7.
return j;
}
void melange_ordre_passage(double *nbjoueurs, struct Joueurs *joueurs)
{
int i = 1;
for(int j = *nbjoueurs-1; j >= 1; j--)
{
i = (rand()%(int)*nbjoueurs);
struct Joueurs temp = joueurs[i];
joueurs[i] = joueurs[j];
joueurs[j] = temp;
//On impose que Mr.White ne puisse commencer la partie donc on remélange s'il est en position 0
if (joueurs[0].role == MR_WHITE)
{
while (joueurs[i].role == MR_WHITE)
i++;
struct Joueurs temp = joueurs[0];
joueurs[0] = joueurs[i];
joueurs[i] = temp;
}
}
}
int main (void)
{//Definition des participants
srand(time(NULL));
double nbjoueurs, nbcivils, nbundercover, nbmrwhite;
nombre_joueurs(&nbjoueurs, &nbcivils, &nbundercover, &nbmrwhite, joueurs);
printf("Joueurs : %0.lf\n_____________\nCivils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", nbjoueurs, nbcivils, nbundercover, nbmrwhite);
//Ajout, Supression de joueurs
modif_joueurs(&nbcivils, &nbundercover, &nbmrwhite);
printf("Joueurs : %0.lf\n_____________\nCivils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", nbjoueurs, nbcivils, nbundercover, nbmrwhite);
//Attribution des pseudos
/* edgardjacobs propose une autre solution
for(int i=0; i<nbjoueurs; i++)
for(unsigned long long int j=0; j<sizeof(joueurs[i].pseudo[100]);j++)
{
printf("Donnez le nom du joueur %d\n",i+1);
lire(&joueurs[i].pseudo[j], 100);
for(int k=nbjoueurs-1; k>0; k--)
{
if(strcmp(&joueurs[i].pseudo[j], &joueurs[i-k].pseudo[j]) == 0)
{
i--;
printf("Vous ne pouvez donner 2 noms de joueurs identique.\n");
}
}
}
*/
//Ici sa proposition
proposition_joueur(joueurs, &nbjoueurs);
//Attribution des rôles exhaustivement
int j = 0;
for (int i = 0; i < nbcivils; i++)
joueurs[j++].role = CIVIL;
for (int i = 0; i < nbundercover; i++)
joueurs[j++].role = UNDERCOVER;
for (int i = 0; i < nbmrwhite; i++)
joueurs[j++].role = MR_WHITE;
//Mélange des rôles https://fr.wikipedia.org/wiki/M%C3%A9lange_de_Fisher-Yates
for (int i = nbjoueurs - 1; i >= 1; i--)
{
int j = rand() % (int)nbjoueurs;
enum roles temp = joueurs[i].role;
joueurs[i].role = joueurs[j].role;
joueurs[j].role = temp;
}
//Affichage des pseudos & rôles (à cacher lorsqu'on jouera)
affichage_pseudo_roles(&nbjoueurs, joueurs);
//Ecriture des mots principaux/secondaires dans le fichier .txt
FILE* fichier = NULL;
fichier = fopen("undercover.txt", "w+");
if (fichier != NULL)
{
int nombreDeLignes = 3;
char motPrincipal1[] = "Chat", motSecondaire1[] = "Chien", motPrincipal2[] = "Fast_&_Furious", motSecondaire2[] = "Need_for_speed", motPrincipal3[] = "Faucon", motSecondaire3[] = "Aigle";
size_t taillemotPrincipal1 = sizeof(motPrincipal1), taillemotSecondaire1 = sizeof(motSecondaire1), taillemotPrincipal2 = sizeof(motPrincipal2), taillemotSecondaire2 = sizeof(motSecondaire2), taillemotPrincipal3 = sizeof(motPrincipal3), taillemotSecondaire3 = sizeof(motSecondaire3);
fprintf(fichier,"%s %s\n", motPrincipal1, motSecondaire1);
fprintf(fichier,"%s %s\n", motPrincipal2, motSecondaire2);
fprintf(fichier,"%s %s\n", motPrincipal3, motSecondaire3);
char lireMotPrincipal1[taillemotPrincipal1], lireMotSecondaire1[taillemotSecondaire1], lireMotPrincipal2[taillemotPrincipal2], lireMotSecondaire2[taillemotSecondaire2], lireMotPrincipal3[taillemotPrincipal3], lireMotSecondaire3[taillemotSecondaire3];
rewind(fichier);
fscanf(fichier, "%s %s", lireMotPrincipal1, lireMotSecondaire1);
fscanf(fichier, "%s %s", lireMotPrincipal2, lireMotSecondaire2);
fscanf(fichier, "%s %s", lireMotPrincipal3, lireMotSecondaire3);
//Attribution des mots de manière aléatoire en gardant la logique de répartition (Civil = motprincipal, Undercover = motsecondaire, Mr.White = pas de mots)
int random = (rand() % nombreDeLignes)+1;
if(random == 1)
{
for (int i = 0; i <nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal1);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire1);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else if(random == 2)
{
for (int i = 0; i <nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal2);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire2);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else if(random == 3)
{
for (int i = 0; i <nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal3);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire3);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else
{
printf("Hors random");
}
//Mélange d'ordre de passage des joueurs dans le jeu
melange_ordre_passage(&nbjoueurs, joueurs);
int tour, manche;
char proposition[100];
for(manche=0; manche<nbjoueurs; manche++)
{
int joueursEnJeu = (int)nbjoueurs-manche;
if(joueursEnJeu==1)
{
printf("Mr.White remporte la partie !");
return 0;
}
if(manche>0)
printf("Il reste donc %d joueurs en jeu\n", joueursEnJeu);
for(tour=0; tour<nbjoueurs; tour++)
{
//Tour de jeu : Un joueur propose un mot à l'équipe
if(joueurs[tour].ingame)
{
printf("Le joueur %s propose un mot :\n", joueurs[tour].pseudo);
lire(proposition, 100);
}
}
//Après enquête et concertation l'équipe décide d'éliminer un joueur
j = saisie_joueur_a_eliminer(joueurs, nbjoueurs);
joueurs[j].ingame = false;
//On totalise les joueurs après chaque éliminations.
if(joueurs[j].role == CIVIL)
nbcivils--;
if(joueurs[j].role == UNDERCOVER)
nbundercover--;
if(joueurs[j].role == MR_WHITE)
nbmrwhite--;
//Puis on pose les conditions de jeu
if(nbcivils == 1 && nbundercover>=1 && nbmrwhite>=1)
{
printf("Les undercover gagnent la partie !");
return 0;
}
if(joueurs[j].role == MR_WHITE)
{
printf("Mr.White a ete demasque, il peut encore gagner en devinant le mot principal :\n");
lire(proposition, 100);
if((random == 1 && strcmp(proposition, motPrincipal1) == 0) || (random == 2 && strcmp(proposition, motPrincipal2) == 0) || (random == 3 && strcmp(proposition, motPrincipal3) == 0))
{
printf("Mr.White gagne la partie !!");
return 0;
}
else
{
printf("Les civils gagnent la partie !");
return 0;
}
}
else
{
printf("Next round !!\n");
}
}
fclose(fichier);
}
else
{
printf("Impossible d'ouvrir le fichier undercover.txt");
}
return 0;
}
J'essaie de contracter tout ça mais c'est pas des abdos.
Joke aside je galère pour la fonction afficher_mots, j'ai comme retour d'erreur motPrincipal1, 2, 3 undeclared dans le main (l.458)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <ctype.h>
enum roles { CIVIL, UNDERCOVER, MR_WHITE };
const char * str_role[] = {
[CIVIL] = "Civil",
[UNDERCOVER] = "Undercover",
[MR_WHITE] = "Mr. White"
};
struct Joueurs {
char pseudo[100];
enum roles role;
bool ingame;
} joueurs[20] = { '\0' };
void viderBuffer()
{
int c = 0;
while (c != '\n' && c != EOF)
{
c = getchar();
}
}
int lire(char *chaine, int longueur)
{
// On vide le buffer avant de commencer
//fflush (stdin);
char *positionEntree = NULL;
// On lit le texte saisi au clavier
if (fgets(chaine, longueur, stdin) != NULL) // Pas d'erreur de saisie ?
{
positionEntree = strchr(chaine, '\n'); // On recherche l'"Entrée"
if (positionEntree != NULL) // Si on a trouvé le retour à la ligne
{
*positionEntree = '\0'; // On remplace ce caractère par \0
}
else
{
viderBuffer();
}
return 1; // On renvoie 1 si la fonction s'est déroulée sans erreur
}
else
{
viderBuffer();
return 0; // On renvoie 0 s'il y a eu une erreur
}
}
void modif_joueurs(double *nbcivils, double *nbundercover, double *nbmrwhite)
{
char choix;
printf("Bienvenue dans la modification de l'equipe, ici se fait l'ajout/suppression.\n");
do
{
printf("Supprimer un Undercover[:U]/Mr.White[:M] au profit d'un civil ? Non[:N]\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'U'&& *nbundercover>0 && *nbmrwhite>0)
{
*nbundercover -= 1;
*nbcivils +=1;
}
else if(choix == 'M'&& *nbmrwhite>0 && *nbundercover>0)
{
*nbmrwhite -= 1;
*nbcivils +=1;
}
else
{
printf("Bien, on continue.\n");
}
if(*nbcivils>*nbundercover+*nbmrwhite+1)
{
printf("Civils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", *nbcivils, *nbundercover, *nbmrwhite);
printf("Ajouter un Undercover[:U]/Mr.White[:M] au depend d'un civil ? Non[:N]\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'U')
{
*nbundercover += 1;
*nbcivils -=1;
}
if(choix == 'M')
{
*nbmrwhite += 1;
*nbcivils -=1;
}
else
{
printf("Voulez-vous continuer la modification ? (:Y/:N)\n");
while (getchar() != '\n');
choix = getchar();
choix = toupper(choix);
if(choix == 'Y')
{
printf("On continue la modification.\n");
printf("Civils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", *nbcivils, *nbundercover, *nbmrwhite);
}
else
{
break;
}
}
}
else
{
break;
}
} while(*nbcivils>=*nbundercover+*nbmrwhite && (*nbundercover!=0 && *nbmrwhite!=0));
viderBuffer();
}
void attribution_pseudo(struct Joueurs *joueurs, double *nbjoueurs)
{
int i=0;
do{
printf("Donnez le nom du joueur %d\n", i+1);
lire(joueurs[i].pseudo, 100);
int j;
for(j=i-1; j>=0; j--)
{
if(strcmp(joueurs[i].pseudo, joueurs[j].pseudo)==0)
{
printf("Vous ne pouvez donner 2 noms de joueurs identiques.\n");
break;
}
}
if(j<0)
i++;
} while(i<*nbjoueurs);
}
void affichage_pseudo_roles(double *nbjoueurs, struct Joueurs *joueurs)
{
for (int i = 0; i < *nbjoueurs; i++)
printf("Joueur %s - role %s\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
void initialisation_jeu(double *nbjoueurs, double *nbcivils, double *nbundercover, double *nbmrwhite, struct Joueurs *joueurs)
{
srand(time(NULL));
do
{
printf("Combien de joueurs sont de la partie ? [3 min, 20 max]\n");
scanf("%lf", nbjoueurs);
}
while(*nbjoueurs<3 || *nbjoueurs>20);
*nbcivils=ceil(*nbjoueurs/2);
if(*nbjoueurs<11)
*nbmrwhite=1;
else if(*nbjoueurs>=11 && *nbjoueurs<17)
*nbmrwhite=2;
else
*nbmrwhite=3;
*nbundercover=*nbjoueurs-*nbcivils-*nbmrwhite;
for(int i=0;i<*nbjoueurs; i++)
{
joueurs[i].ingame = true;
}
printf("Joueurs : %0.lf\n_____________\nCivils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", *nbjoueurs, *nbcivils, *nbundercover, *nbmrwhite);
//Ajout, Supression de joueurs
modif_joueurs(nbcivils, nbundercover, nbmrwhite);
printf("Joueurs : %0.lf\n_____________\nCivils : %0.lf\nUndercover : %0.lf\nMr.White : %0.lf\n", *nbjoueurs, *nbcivils, *nbundercover, *nbmrwhite);
//Attribution des pseudos
/* edgardjacobs propose une autre solution
for(int i=0; i<nbjoueurs; i++)
for(unsigned long long int j=0; j<sizeof(joueurs[i].pseudo[100]);j++)
{
printf("Donnez le nom du joueur %d\n",i+1);
lire(&joueurs[i].pseudo[j], 100);
for(int k=nbjoueurs-1; k>0; k--)
{
if(strcmp(&joueurs[i].pseudo[j], &joueurs[i-k].pseudo[j]) == 0)
{
i--;
printf("Vous ne pouvez donner 2 noms de joueurs identique.\n");
}
}
}
*/
//Ici sa proposition
attribution_pseudo(joueurs, nbjoueurs);
//Attribution des rôles exhaustivement
int j = 0;
for (int i = 0; i < *nbcivils; i++)
joueurs[j++].role = CIVIL;
for (int i = 0; i < *nbundercover; i++)
joueurs[j++].role = UNDERCOVER;
for (int i = 0; i < *nbmrwhite; i++)
joueurs[j++].role = MR_WHITE;
//Mélange des rôles https://fr.wikipedia.org/wiki/M%C3%A9lange_de_Fisher-Yates
for (int i = *nbjoueurs - 1; i >= 1; i--)
{
int j = rand() % (int)*nbjoueurs;
enum roles temp = joueurs[i].role;
joueurs[i].role = joueurs[j].role;
joueurs[j].role = temp;
}
//Affichage des pseudos & rôles (à cacher lorsqu'on jouera)
affichage_pseudo_roles(nbjoueurs, joueurs);
}
/*
int saisie_joueur_a_eliminer(struct Joueurs *joueurs, int nbjoueurs)
{
char joueurElimine[100];
int j = -1;
//1.Je demande le nom d'un joueur à éliminer
printf("Il est maintenant temps d'eliminer le joueur qui vous parait suspect\n");
printf("Apres concertation les joueurs ont decides d'eliminer le joueur :\n");
lire(joueurElimine, 100);
//2.Je parcours le paquet de cartes à partir du début et jusqu'à la fin
for(int i=0; i<nbjoueurs; i++)
{
//3.Pour chaque carte, je vérifie si la carte porte ce nom.
if(strcmp(joueurElimine, joueurs[i].pseudo) == 0)
{
//4.Si oui: je vérifie si la carte indique qu'il est déjà éliminé.
if(!joueurs[i].ingame)
{
//(i.)Si oui, je me plains d'une erreur, j'arrête de parcourir le paquet et je vais en 7.
printf("Erreur : Le joueur a deja ete elimine.\n");
break;
}
//(ii.)Sinon, j'ai terminé, j'arrête de parcourir le paquet et je vais en 7.
else
{
j=i;
joueurs[i].ingame = false;
return j;
}
}
//5.Sinon je continue à parcourir le paquet
}//6.Si j'arrive au bout du paquet et qu'aucune carte ne porte ce nom, je me plains d'une erreur et je boucle en 1.
printf("Erreur : Le joueur designe est introuvable.\n");
saisie_joueur_a_eliminer(joueurs, nbjoueurs);
return j;
}
*/
int saisie_joueur_a_eliminer(struct Joueurs *joueurs, int nbjoueurs)
{//Correction de Dlks
int j = -1;
char joueurElimine[256];
printf("Il est maintenant temps d'eliminer le joueur qui vous parait suspect\n");
printf("Apres concertation saisissez son pseudo parmi les joueurs encore en jeu : \n");
for (int i = 0; i < nbjoueurs; i++)
if (joueurs[i].ingame)
printf("%s\n", joueurs[i].pseudo);
while (1)
{//1.
printf("\nQuel est le pseudo du joueur que vous eliminez :\n");
lire(joueurElimine, 100);
//2.
int i;
for (i = 0; i < nbjoueurs; i++)
{
if (strcmp(joueurElimine, joueurs[i].pseudo) == 0)
{
if (!joueurs[i].ingame)
{//(i)
printf("Erreur : Le joueur a deja ete elimine.\n");
break;
}
//(ii)
else
{
j = i;
break;
}
}//5.
}//6.
if (j == -1 && i == nbjoueurs)
printf("Le joueur est introuvable.\n");
else if (j != -1)
break;
}//7.
return j;
}
int afficher_mots(double *nbjoueurs, struct Joueurs *joueurs)
{
FILE* fichier = NULL;
fichier = fopen("undercover.txt", "w+");
int nombreDeLignes = 3;
char motPrincipal1[] = "Chat", motSecondaire1[] = "Chien", motPrincipal2[] = "Fast_&_Furious", motSecondaire2[] = "Need_for_speed", motPrincipal3[] = "Faucon", motSecondaire3[] = "Aigle";
size_t taillemotPrincipal1 = sizeof(motPrincipal1), taillemotSecondaire1 = sizeof(motSecondaire1), taillemotPrincipal2 = sizeof(motPrincipal2), taillemotSecondaire2 = sizeof(motSecondaire2), taillemotPrincipal3 = sizeof(motPrincipal3), taillemotSecondaire3 = sizeof(motSecondaire3);
fprintf(fichier,"%s %s\n", motPrincipal1, motSecondaire1);
fprintf(fichier,"%s %s\n", motPrincipal2, motSecondaire2);
fprintf(fichier,"%s %s\n", motPrincipal3, motSecondaire3);
char lireMotPrincipal1[taillemotPrincipal1], lireMotSecondaire1[taillemotSecondaire1], lireMotPrincipal2[taillemotPrincipal2], lireMotSecondaire2[taillemotSecondaire2], lireMotPrincipal3[taillemotPrincipal3], lireMotSecondaire3[taillemotSecondaire3];
rewind(fichier);
fscanf(fichier, "%s %s", lireMotPrincipal1, lireMotSecondaire1);
fscanf(fichier, "%s %s", lireMotPrincipal2, lireMotSecondaire2);
fscanf(fichier, "%s %s", lireMotPrincipal3, lireMotSecondaire3);
//Attribution des mots de manière aléatoire en gardant la logique de répartition (Civil = motprincipal, Undercover = motsecondaire, Mr.White = pas de mots)
int random = (rand() % nombreDeLignes)+1;
if(random == 1)
{
for (int i = 0; i <*nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal1);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire1);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else if(random == 2)
{
for (int i = 0; i <*nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal2);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire2);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else if(random == 3)
{
for (int i = 0; i <*nbjoueurs; i++)
{
if (joueurs[i].role == CIVIL)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotPrincipal3);
}
if (joueurs[i].role == UNDERCOVER)
{
system("pause");
printf("%s obtient le mot %s\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, lireMotSecondaire3);
}
if (joueurs[i].role == MR_WHITE)
{
system("pause");
printf("%s est %s : Vous n'avez pas de mot !\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", joueurs[i].pseudo, str_role[joueurs[i].role]);
}
}
}
else
{
printf("Hors random");
}
return random;
}
void melange_ordre_passage(double *nbjoueurs, struct Joueurs *joueurs)
{
int i = 1;
for(int j = *nbjoueurs-1; j >= 1; j--)
{
i = (rand()%(int)*nbjoueurs);
struct Joueurs temp = joueurs[i];
joueurs[i] = joueurs[j];
joueurs[j] = temp;
//On impose que Mr.White ne puisse commencer la partie donc on remélange s'il est en position 0
if (joueurs[0].role == MR_WHITE)
{
while (joueurs[i].role == MR_WHITE)
i++;
struct Joueurs temp = joueurs[0];
joueurs[0] = joueurs[i];
joueurs[i] = temp;
}
}
}
int main (void)
{//Definition des participants
double nbjoueurs, nbcivils, nbundercover, nbmrwhite;
initialisation_jeu(&nbjoueurs, &nbcivils, &nbundercover, &nbmrwhite, joueurs);
//Ecriture des mots principaux/secondaires dans le fichier .txt
FILE* fichier = NULL;
fichier = fopen("undercover.txt", "w+");
if (fichier != NULL)
{
int random = afficher_mots(&nbjoueurs, joueurs);
//Mélange d'ordre de passage des joueurs dans le jeu
melange_ordre_passage(&nbjoueurs, joueurs);
int tour, manche;
char proposition[100];
for(manche=0; manche<nbjoueurs; manche++)
{
int joueursEnJeu = (int)nbjoueurs-manche;
if(joueursEnJeu==1)
{
printf("Mr.White remporte la partie !");
return 0;
}
if(manche>0)
printf("Il reste donc %d joueurs en jeu\n", joueursEnJeu);
for(tour=0; tour<nbjoueurs; tour++)
{
//Tour de jeu : Un joueur propose un mot à l'équipe
if(joueurs[tour].ingame)
{
printf("Le joueur %s propose un mot :\n", joueurs[tour].pseudo);
lire(proposition, 100);
}
}
//Après enquête et concertation l'équipe décide d'éliminer un joueur
int j = saisie_joueur_a_eliminer(joueurs, nbjoueurs);
joueurs[j].ingame = false;
//On totalise les joueurs après chaque éliminations.
if(joueurs[j].role == CIVIL)
nbcivils--;
if(joueurs[j].role == UNDERCOVER)
nbundercover--;
if(joueurs[j].role == MR_WHITE)
nbmrwhite--;
//Puis on pose les conditions de jeu
if(nbcivils == 1 && nbundercover>=1 && nbmrwhite>=1)
{
printf("Les undercover gagnent la partie !");
return 0;
}
if(joueurs[j].role == MR_WHITE)
{
printf("Mr.White a ete demasque, il peut encore gagner en devinant le mot principal :\n");
lire(proposition, 100);
if((random == 1 && strcmp(proposition, &motPrincipal1) == 0) || (random == 2 && strcmp(proposition, &motPrincipal2) == 0) || (random == 3 && strcmp(proposition, &motPrincipal3) == 0))
{
printf("Mr.White gagne la partie !!");
return 0;
}
else
{
printf("Les civils gagnent la partie !");
return 0;
}
}
else
{
printf("Next round !!\n");
}
}
fclose(fichier);
}
else
{
printf("Impossible d'ouvrir le fichier undercover.txt");
}
return 0;
}
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent