[C] Problèmes avec une structure

Résolu/Fermé
Douly - 5 janv. 2010 à 19:27
mamiemando Messages postés 33535 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 12 février 2025 - 6 janv. 2010 à 20:07
Bonjour,
Je suis actuellement en train de réaliser un mastermind en langage C pour un cours et je rencontre actuellement un problème.

Voici mon code :
[CODE]
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>

void AfficherMenu();
void regles();

void jeu();
void initialisation(char *nomJoueur1,unsigned short int *cptnombreJoueur);
void GenererCombiAleatoire(char * solution);
void ProposerCombi(char * proposition);
void VerifierCombi(char * solution, char *proposition, char *test);
void AfficherJeu(unsigned short int *essai,char * proposition,char * test);

void AfficherResultat(char *proposition1,char *resultat,unsigned short int *essai,char *nomJoueur1);

/*---------------------------------------------------------------------------------------
Fonction main, programme principal*/
int main()
{
char choix[2];//Déclaration et initialisation de la variable choix
srand(time(NULL));
AfficherMenu();

do {
fflush(stdin);//Permet de ne pas avoir 2 fois le contenu du printf quand l'utilisateur entre une lettre ou un chiffre non-contenu dans le while.
printf("Que voulez-vous faire ?");
scanf("%s",choix);//On demande à l'utilisateur de rentrer un choix.
choix[0]=toupper(choix[0]);//Mise en majuscule de la chaîne 'choix'.
if(choix[0]!='J'&&choix[0]!='R'&&choix[0]!='Q'||strlen(choix)!=1)
printf("\nVeuillez entrer la lettre 'J' pour jouer, 'R' pour voir les r%cgles ou 'Q' pour quitter.\a\n\n",138);
}
while(choix[0]!='J'&&choix[0]!='R'&&choix[0]!='Q'||strlen(choix)!=1);//Tant que l'utilisateur ne rentre pas une de ces trois lettres ou qu'il rentre plus d'une lettre, on lui demande de rentrer un choix.


switch(choix[0]){
case 'J' : jeu();//Si le choix entré est J on appelle la fonction jeu.
break;
case 'R' : regles();//Si le choix entré est R on appelle la fonction règle.
break;
case 'Q' : printf("\nVeuillez appuyer sur une touche pour quitter.\n");//Si le choix entré est Q on affiche cette phrase et on quitte le programme.
exit;
}
return 0;

}

/*---------------------------------------------------------------------------------------
Fin fonction main*/


/*---------------------------------------------------------------------------------------
Fonction qui affiche le menu et l'en-tête du programme.*/
void AfficherMenu()
{
printf("\t\t===================================================\n");
printf("\t\t|Programme r%calis%c par l'%ctudiant : Legrain Thomas|\n",130,130,130);
printf("\t\t|Section : 1ere IRT Groupe : 4 |\n");
printf("\t\t|Ann%ce acad%cmique : 2009/2010 |\n",130,130);
printf("\t\t|Nom de l'enseignant : De Bodt |\n");
printf("\t\t|Projet : Jeu de Mastermind |\n");
printf("\t\t===================================================\n");

printf("\n\n");
printf("\t\t\t\t========MENU========\n",138);
printf("\t\t\t\t|(J)ouer |\n");
printf("\t\t\t\t|(R)%cgles du jeu |\n");
printf("\t\t\t\t|(Q)uitter |\n");
printf("\t\t\t\t====================\n\n\n");
}

/*---------------------------------------------------------------------------------------
Fin fonction.*/


/*---------------------------------------------------------------------------------------
Fonction qui affiche les règles du jeu et renvoie l'utilisateur au programme principal.*/
void regles()
{
printf("\nVous avez choisi d'afficher les r%cgles du jeu.",138);
printf("\n\n============REGLES============\n");
printf("\nLe programme choisit une combinaison de 4 pions de couleurs au hasard");
printf("\nparmi 6 couleurs disponibles.Cette combinaison de pions peut contenir");
printf("\nplusieurs fois la m%cme couleur.Vous devez essayer de la deviner en",136);
printf("\nproposant au maximum dix combinaisons.Pour chaque tentative le programme");
printf("\nindique les couleurs bien plac%ces (via la lettre 'N')et les couleurs mal",130);
printf("\nplac%ces (via la lettre 'B').Si le nombre maximal d'essais est atteint,",130);
printf("\nle programme indique au joueur qu'il a perdu et donne la combinaison.");

main();//Retour à la fonction principale pour redemander un choix.
}
/*---------------------------------------------------------------------------------------
Fin fonction*/

/*---------------------------------------------------------------------------------------
Fonction jeu, elle appelle kes fonctions initialisation,GenererCombiAleatoire,VerifierCombi,AfficherResultat*/
void jeu()
{
char solution[5],proposition[5],test[5],nomJoueur1[20];
unsigned short int essai=0,nombreJoueur=0,cptnombreJoueur=0;
printf("A combien voulez vous jouer ? ");
scanf("%u",&nombreJoueur);//Demande du nombre de joueurs
do
{
initialisation(nomJoueur1,&cptnombreJoueur);//On va dans la fonction initialisation
GenererCombiAleatoire(solution);//On va dans la fonction GenererCombiAleatoire
while(essai<=9&&strcmp(proposition,solution)!=0)//TANT QUE le nombre d'essais est inferieur à 9 ET QUE la proposition donnée est différente de la solution
{
printf("\n\nJoueur %u \nProposition %u :",cptnombreJoueur+1,essai+1);//On écrit le numéro du joueur et de la proposition
VerifierCombi(solution,proposition,test);//On va dans la fonction VerifierCombi
AfficherJeu(&essai,proposition,test);
essai++;}
AfficherResultat(proposition,solution,&essai,nomJoueur1);
essai=0;
cptnombreJoueur++;
}
while(cptnombreJoueur<nombreJoueur);
}
/*---------------------------------------------------------------------------------------
Fin fonction*/


/*--------------------------------------------
Fonction qui donne les couleurs disponibles et qui demande le nom du joueur.*/
void initialisation(char *nomJoueur1,unsigned short int *cptnombreJoueur)
{

printf("Entrez le nom du joueur %d: ",*cptnombreJoueur+1);
scanf("%s",nomJoueur1);//On entre le nom du joueur
printf("\n\n\n =================================================================\n");
printf(" |# # ## #### ##### ###### ##### # # # # # ##### | \n");
printf(" |## ## # # # # # # # ## ## # ## # # #| \n");
printf(" |# ## # # # #### # ##### # # # ## # # # # # # #| \n");
printf(" |# # ###### # # # ##### # # # # # # # #| \n");
printf(" |# # # # # # # # # # # # # # ## # #| \n");
printf(" |# # # # #### # ###### # # # # # # # ##### | \n");
printf(" =================================================================\n");

printf(" ========================================================================");
printf("\n |Couleurs disponibles : (R)ouge,(V)ert,(B)leu,(J)aune,(O)range,(M)arron|\n");//Affichage des couleurs disponibles
printf(" ========================================================================");


}
/*--------------------------------------------
Fin fonction,retour dans jeu*/

/*--------------------------------------------
Création de la fonction qui génère la combinaison aléatoire et qui la renvoye dans jeu*/

void GenererCombiAleatoire(char * solution)
{
char lettres[7]="RVBJOM";//Initialisation de la chaîne lettres
unsigned short int cptLettresSol=0;
for(cptLettresSol=0;cptLettresSol<=3;cptLettresSol++)
solution[cptLettresSol]=lettres[rand()%6];//On mets 4 fois dans solution une lettre placée entre la position 1 et la position 6 dans la chaîne lettres.
solution[4] = '\0';//On termine la chaîne par le caractère d'échappement
}

/*---------------------------------------------
Fin de la fonction qui génère la combinaison aléatoire*/

/*---------------------------------------------
Début de la fonction qui demande à l'utilisateur de rentrer une proposition*/
void ProposerCombi(char * proposition)
{
unsigned short int cptLettresProp=0;

do
{
scanf("%s",proposition);
printf("\n");
for(cptLettresProp=0;cptLettresProp<=3;cptLettresProp++)
proposition[cptLettresProp]=toupper(proposition[cptLettresProp]);
if(strlen(proposition)!=4||proposition[0]!='R'&&proposition[0]!='V'&&proposition[0]!='B'&&proposition[0]!='J'&&proposition[0]!='O'&&proposition[0]!='M'||proposition[1]!='R'&&proposition[1]!='V'&&proposition[1]!='B'&&proposition[1]!='J'&&proposition[1]!='O'&&proposition[1]!='M'||proposition[2]!='R'&&proposition[2]!='V'&&proposition[2]!='B'&&proposition[2]!='J'&&proposition[2]!='O'&&proposition[2]!='M'||proposition[3]!='R'&&proposition[3]!='V'&&proposition[3]!='B'&&proposition[3]!='J'&&proposition[3]!='O'&&proposition[3]!='M')
printf("Combinaison impossible. Recommencez!\n\a");
}
while(strlen(proposition)!=4||proposition[0]!='R'&&proposition[0]!='V'&&proposition[0]!='B'&&proposition[0]!='J'&&proposition[0]!='O'&&proposition[0]!='M'||proposition[1]!='R'&&proposition[1]!='V'&&proposition[1]!='B'&&proposition[1]!='J'&&proposition[1]!='O'&&proposition[1]!='M'||proposition[2]!='R'&&proposition[2]!='V'&&proposition[2]!='B'&&proposition[2]!='J'&&proposition[2]!='O'&&proposition[2]!='M'||proposition[3]!='R'&&proposition[3]!='V'&&proposition[3]!='B'&&proposition[3]!='J'&&proposition[3]!='O'&&proposition[3]!='M');
proposition[4] = '\0';
}
/*---------------------------------------------
Fin de la fonction*/

/*---------------------------------------------
Cette fonction compare la chaine entrée par l'utilisateur à celle générée par l'ordinateur*/
void VerifierCombi(char * solution, char *proposition, char *test)
{
unsigned short int cptLettres=0;
ProposerCombi(proposition);
for(cptLettres=0;cptLettres<=3;cptLettres++)
{
if(proposition[cptLettres]==solution[cptLettres])//Quand la lettre est au bon endroit dans la combinaison
test[cptLettres]='N';
else if (proposition[cptLettres]!=solution[0]&&proposition[cptLettres]!=solution[1]&&proposition[cptLettres]!=solution[2]&&proposition[cptLettres]!=solution[3])//Quand la lettre n'est pas présente dans la combinaison
test[cptLettres]='.';
else test[cptLettres]='B';//Quand la lettre est présente mais pas à la bonne place
}
test[4] = '\0' ;



}
/*---------------------------------------------
Fin de la fonction*/

/*---------------------------------------------
Cette fonction Affiche le jeu*/
void AfficherJeu(unsigned short int *essai,char * proposition, char * test)
{
unsigned short int nbreLignes=10,cptLettresAff=0,i;

struct Ligne
{
char proposition1[5];
char test1[5];
};
struct Ligne tab_ligne[10];

strcpy(tab_ligne[*essai].proposition1,proposition);
strcpy(tab_ligne[*essai].test1,test);

printf("\t\t============================================");
for(nbreLignes=10;nbreLignes>=*essai+2;nbreLignes--)
printf("\n\t\t[%2d]-[ (*) (*) (*) (*) ] [ [.] [.] [.] [.] ]",nbreLignes);
printf("\n");
printf("\t\t[%2d]-",*essai+1);
printf("[ ");
for(cptLettresAff=0;cptLettresAff<=3;cptLettresAff++)
printf("(%c) ",tab_ligne[*essai].proposition1[cptLettresAff]);
printf("] [ ");
for(cptLettresAff=0;cptLettresAff<=3;cptLettresAff++)
printf("[%c] ",tab_ligne[*essai].test1[cptLettresAff]);
printf("]");

}
/*------------------------------------------------
Fin de la fonction*/

/*Fonction qui affiche le résultat*/
void AfficherResultat(char *proposition,char *solution,unsigned short int *essai,char *nomJoueur1)
{

if(strcmp(proposition,solution)==0)
printf("\n\nBravo %s vous avez r%cussi %c trouv%c la solution qui %ctait %s en %d coup(s)!\n",nomJoueur1,130,133,130,130,solution,*essai);
else printf("\n\nDommage %s! Vous n'avez pas trouv%c la solution qui %ctait %s.",nomJoueur1,130,130,solution);

}

[/CODE]

Le programme fonctionne très bien je n'ai pas de soucis avec seulement je dois améliorer un point. Dans la fonction AfficherJeu, j'affiche au début (quand l'utilisateur rentre sa première proposition) quelque chose comme ça:

[quote][10]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 9]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 8]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 7]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 6]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 5]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 4]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 3]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 2]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 1]-[(R) (V) (B) (J) ] [ [N] [B] [.] [.] ][/quote]

R V B J ce sont les 4 couleurs rentrées par l'utilisateur.
A coté le N signifie que la lettre (R) est à la bonne place, que la lettre (V) est dans le code mais pas à cette place et que les deux autres (B et J) ne sont pas dans le code.

L'utilisateur va rentrer plusieurs combinaisons et il va donc 'remonter' dans le tableau :

[quote][10]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 9]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 8]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 7]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 6]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 5]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 4]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 3]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 2]-[(O) (O) (O) (O) ] [ [.] [.] [.] [.] ][/quote]

Tout est ok mais en fait j'aimerai bien garder les propositions d'avant et les afficher aussi dans le tableau et avoir quelque chose comme ça:


[quote][10]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 9]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 8]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 7]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 6]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 5]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 4]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 3]-[(*) (*) (*) (*)] [ [.] [.] [.] [.] ]
[ 2]-[(O) (O) (O) (O) ] [ [.] [.] [.] [.] ]
[ 1]-[(R) (V) (B) (J) ] [ [N] [B] [.] [.] ][/quote]

Mais là j'avoue je vois pas du tout comment faire, on m'a aiguillé sur un tableau de structure mais j'ai beaucoup de mal.

Merci d'avance à ceux qui se pencheront sur mon problème.

Merci d'avance.;)
A voir également:

2 réponses

mamiemando Messages postés 33535 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 12 février 2025 7 828
5 janv. 2010 à 21:56
Je ne suis pas sûre d'avoir tout compris mais le caractère \r permet de replacer le curseur en début de ligne. Si tu écris les propositions de bas en haut avec le "prompt" en bas, ça pourrait faire l'affaire.

Si tu as besoin de réellement positionner certains caractères, il est peut être plus sage/adéquat de se tourner vers des librairies comme la libncurses. Ca t'éviterait de devoir mémoriser les saisies antérieures.

Si tu veux stocker toutes les saisies (sous entendu, effacer et réécrire tous le tableau de jeu), il va falloir stocker les saisies dans un tableau pour conserver cette information. Dans ce cas je ferais un truc dans ce genre :

#include <stdlib.h>

typedef enum _couleur_t{VIDE,BLEU,ROUGE,JAUNE} couleur_t;

void liberer_tableau(couleur_t **tableau,unsigned nb_lig){
  unsigned i;
  if(tableau){
    for(i=0;i<nb_lig;++i) if(tableau[i]) free(tableau[i]);
    free(tableau);
  }
}

couleur_t **creer_tableau(unsigned nb_col,unsigned nb_lig){
  couleur_t **tableau;
  unsigned i;
  tableau = (couleur_t **) malloc(sizeof(couleur_t *)*nb_lig);
  if(!tableau) return NULL;
  for(i=0;i<nb_lig;++i){
    tableau[i] = (couleur_t *) calloc(sizeof(couleur_t),nb_col);
    if(!tableau[i]){
      liberer_tableau(tableau);
      return NULL;
    }
  }
  return tableau;
}

void afficher_tableau(couleur_t **tableau,unsigned nb_lig,unsigned nb_col){
  unsigned i,j;
  for(i=0;i<nb_lig;++i){
    printf("Tour %2d:",i);

    // Afficher le résultat de la combinaison jouée
    // (comparer chaque tableau[i][j] avec code[j])
    // ...

    // Ecrire la combinaison jouée (tableau[i])
    for(j=0;j<nb_col;++j){
      switch(tableau[i][j]){
        case VIDE:  printf("-"); break;
        case BLEU:  printf("B"); break;
        case JAUNE: printf("J"); break;
        // etc...
        default: fprintf(stderr,"afficher_tableau: couleur incohérente !\n");
      }
      printf(" ");
    }
    printf("\n");
  }
}


Bonne chance
1
Ah oui par tableau, je vais tester ça, merci pour ton aide.
0
mamiemando Messages postés 33535 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 12 février 2025 7 828
6 janv. 2010 à 20:07
De rien bonne continuation !
0