Etudes/Premiere annee/golfPourEtudiants/golf.c

840 lines
19 KiB
C

/***************************************************************************
golf.c
***************************************************************************/
#include "golf.h"
/*
* paramètre d'entrées : le nombre actuel d'element(s) du tableau
*
* en entrées :
*
* paramètre de sortie
*
* paramètre d'E/S un tableau de pointeur(s) sur parcours
*
* en sortie :
* valeur retournée : le nouveau nombre de parcours present dans le tableau
*
* DESCRIPTION : creation dynamique d'un parcours, initialisation
* et ajout de ce dernier dans le tableau des parcours
*
*/
int creerParcours( typeParcours *tab[], int nbParcours )
{
int i;
// creation du parcours a l'indice nbParcours
tab[nbParcours] = ( typeParcours* ) malloc( sizeof( typeParcours ) );
printf( "\nnom du parcours " );
scanf( "%s", tab[nbParcours]->nom );
printf( "nombre de trous " );
scanf( "%d", &tab[nbParcours]->nbTrou );
// initialisation des trous
for ( i = 0;i < tab[nbParcours]->nbTrou;i++ )
{
printf( "numero du trou : %d\n", i + 1 );
tab[nbParcours]->listeTrous[i].numero = i + 1;
printf( "distance (en metre) : " );
scanf( "%f", &tab[nbParcours]->listeTrous[i].distance );
printf( "valeur du par : " );
scanf( "%d", &tab[nbParcours]->listeTrous[i].par );
printf( "nombre maximum de coups pour ce trou : " );
scanf( "%d", &tab[nbParcours]->listeTrous[i].nbMaxCoups );
}
return nbParcours + 1;
}
/*
* paramètre d'entrées : un tableau de pointeur(s) sur parcours
le numero d'index du parcours a afficher
*
* en entrées :
*
* paramètre de sortie
*
* paramètre d'E/S
*
* en sortie : affichage de info à l'ecran
* valeur retournée :
*
* DESCRIPTION : afficher les informations d'un parcours particulier
*
*/
void afficherUnParcours( typeParcours *tab[], int nro )
{
int i;
printf( "\nnom du parcours %s\n", tab[nro]->nom );
printf( "nombre de trous %d\n", tab[nro]->nbTrou );
// afficher le detail de chaque trou du parcours
for ( i = 0;i < tab[nro]->nbTrou;i++ )
{
afficherInfoTrou( tab[nro]->listeTrous[i] );
}
}
/*
* paramètre d'entrées : un tableau de pointeur(s) sur parcours
le nombre actuel d'element(s) du tableau
*
* en entrées :
*
* paramètre de sortie
*
* paramètre d'E/S
*
* en sortie : fichier contenant l'ensemble des parcours
* valeur retournée :
*
* DESCRIPTION : sauvegarder les donnees des parcours dans un fichier
*
*/
void sauvegarderParcours( typeParcours *tab[], int nbParcours )
{
FILE *fd;
int i;
int nbEnregistrement;
int retourFclose;
// ouverture du fichier des parcours en ecriture
fd = fopen( FICHIER_PARCOURS, "w+" );
if ( fd == NULL )
{
printf( "%s\n", strerror( errno ) );
exit( errno );
}
//ecriture de chacun des parcours
for ( i = 0; i < nbParcours; i++ )
{
nbEnregistrement=fwrite( tab[i], sizeof( typeParcours ), 1, fd );
if (nbEnregistrement!=1)
{
printf( " pb sauvegarde parcours%s\n", strerror( errno ) );
exit( errno );
}
}
retourFclose=fclose( fd );
if(retourFclose==EOF)
{
printf( " pb fermeture sauvegarde parcours%s\n", strerror( errno ) );
exit( errno );
}
}
/*
* paramètre d'entrées :
*
* en entrées : fichier contenant l'ensemble des parcours
*
* paramètre de sortie : un tableau de pointeur(s) sur parcours
*
* paramètre d'E/S
*
* en sortie :
* valeur retournée : le nombre actuel d'element(s) du tableau des parcours
*
* DESCRIPTION : initialiser le tableau des parcours
* à partir d'un fichier
*
*/
int chargerParcours( typeParcours *tab[] )
{
FILE *fd;
int nbEnregistrement;
int i = 0;
int retourFclose;
// ouverture du fichier des parcours en lecture
fd = fopen( FICHIER_PARCOURS, "r" );
if ( fd == NULL )
{
printf( "%s\n", strerror( errno ) );
exit( errno );
}
// lecture et stockage de tous les parcours
while ( !feof( fd ) )
{
// reservation memoire pour stokcer un parcours
tab[i] = ( typeParcours* ) malloc( sizeof( typeParcours ) );
//lecture d'un parcours
nbEnregistrement=fread( tab[i], sizeof( typeParcours ), 1, fd );
if (nbEnregistrement!=1) // pb de lecture
{
if (!feof(fd))
{
printf( " pb lecture charger parcours%s\n", strerror( errno ) );
exit( errno );
}
else
{
// c'est la fin de fichier
// on a donc réserve une case en trop pour les parcours
// il faut la supprimer
free( tab[i] );
}
}
else
{
// augmentation du nombre de parcours lu
i++;
}
}
retourFclose=fclose( fd );
if(retourFclose==EOF)
{
printf( " pb fermeture charger parcours%s\n", strerror( errno ) );
exit( errno );
}
// je retourne le nombre de parcours maintenant present dans mon tableau
return i;
}
/*
* retourne une valeur entiere E[0..maxAlea[
*/
float aleatoire( float maxAlea )
{
/* struct timeb {
time_t time;
unsigned short millitm;
short timezone;
short dstflag;
};*/
struct timeb t;
//long t;
float a, b ;
unsigned int nbmilli;
ftime( &t );
nbmilli = t.time * 1000 + t.millitm;
srand( nbmilli );
a = rand();
b = ( maxAlea * a ) / RAND_MAX;
return ( b );
}
/*
* retourne un entier entre min et max
*/
float lancement( float min, float max )
{
float lancee;
lancee = min + aleatoire( max - min );
return ( lancee );
}
/*
* paramètre d'entrées : un trou
* la difficulte sur le green
*
*
* en entrées : le choix du club utilise
*
* paramètre de sortie :
*
* paramètre d'E/S
*
* en sortie : affichage de la distance restante
* et du nombre de points
* valeur retournée : le nombre de coups effectue pour arriver au trou
*
* DESCRIPTION : jouer un trou ->
* demander autant de fois que necessaire
* le type de club a utilise
* jusqu'à arriver au trou.
* ->la difficulte est de determiner à partir de
* combien de metres du trou
* une balle est consideree dans le trou.
*
*/
int jouerTrou( typeTrou t, float difficulte )
{
int fin = 1; // la balle n'est pas dans le trou
float dist = t.distance;
int nbCoups = 1;
char choix;
do
{
printf( "=============== coups nro %d\n", nbCoups );
printf( "choix du club : \n[D]river\n[B]ois\n[F]er\n[P]utter\n" );
scanf( " %c", &choix );
choix = toupper( choix );
// en fonction du choix de club, je reduis la distance avec le trou
switch ( choix )
{
case 'D':
dist -= lancement( DRIVER_MIN, DRIVER_MAX );
break;
case 'B':
dist -= lancement( BOIS_MIN, BOIS_MAX );
break;
case 'F':
dist -= lancement( FER_MIN, FER_MAX );
break;
case 'P':
dist -= lancement( PUTTER_MIN, PUTTER_MAX );
break;
}
if ( dist <= 0.0 )
{// si je depasse le trou je remets une distance positive
dist = -dist;
if ( dist > difficulte )
printf( "%svous avez depasse le trou%s\n", RED, GREY );
}
if ( dist <= difficulte && dist >= 0.0 )
{// la balle est dans le trou
fin = 0;
}
if ( nbCoups == t.nbMaxCoups )
{// j'ai atteint le nombre maxi de coups pour le trou
if ( fin != 0 )
{// et en plus la balle n'est toujours pas dans le trou
printf( "%sNombre de coups maxi atteint!! abandon de ce trou%s\n", RED, GREY );
}
fin = 0;
}
if ( fin != 0 )
{// je dois rejouer, j'affiche la distance restante
nbCoups++;
printf( "=================================================\n" );
printf( "il vous reste %.1f metres avant le trou\n", dist );
printf( "=================================================\n" );
}
}
while ( fin != 0 );
printf( "\n\n\n" );
// suivant le nombre de coups joue par rapport au "par" du trou
// j'affiche la designation correspondante
switch ( nbCoups - t.par )
{
case CONDOR:
printf( "%s CONDOR !!!! %d\n%s", YELLOW, CONDOR, GREY );
break;
case ALBATROS:
printf( "%s ALBATROS!!! %d\n%s", YELLOW, ALBATROS, GREY );
break;
case EAGLE:
printf( "%sEAGLE!! %d%s\n", YELLOW, EAGLE, GREY );
break;
case BIRDIE:
printf( "%sBIRDIE! %d%s\n", YELLOW, BIRDIE, GREY );
break;
case PAR:
printf( "PAR %d\n", PAR );
break;
case BOGEY:
printf( "%sBOGEY +%d%s\n", RED, BOGEY, GREY );
break;
case DOUBLE_BOGEY:
printf( "%sDOUBLE_BOGEY +%d%s\n", RED, DOUBLE_BOGEY, GREY );
break;
case TRIPLE_BOGEY:
printf( "%sTRIPLE_BOGEY +%d%s\n", RED, TRIPLE_BOGEY, GREY );
break;
default:
printf( "%s+%d%s\n", RED, nbCoups - t.par, GREY );
}
printf( "\n\n\n" );
// retourne le nombre de coups joue pour ce trou
return ( nbCoups );
}
/*
* paramètre d'entrées : un pointeur sur un score
*
* en entrées :
*
* paramètre de sortie :
*
* paramètre d'E/S
*
* en sortie : affichage du score d'un joueur pour un parcours
* valeur retournée :
*
* DESCRIPTION : affichage du score d'un joueur pour un parcours
*
*/
void afficherScore( typeScore *s )
{
int i, total = 0;
printf( "score de%s %s:%s\n", CYAN, s->nomJoueur, GREY );
printf( "parcours : %s difficulte : ", s->parcoursJoue.nom );
// suivant la valeur de la difficulte, afficher la difficulte en toute lettre
switch ( s->difficulte )
{
case 0:
printf( "infernale\n" );
case 1:
printf( "tres difficile\n" );
case 2:
printf( "difficile\n" );
case 3:
printf( "normale\n" );
case 4:
printf( "facile\n" );
case 5:
printf( "tres facile\n" );
}
// affichage de la grille avec le numero des trous, les valeurs des "par" et le score du joueur
printf( "--------------" );
for ( i = 0;i < s->parcoursJoue.nbTrou + 1;i++ )
{
printf( "----" );
}
printf( "\n" );
//affichage des numeros de trou
printf( "nro Trou " );
for ( i = 0;i < s->parcoursJoue.nbTrou;i++ )
{
if ( i < 10 )
{
printf( "| %.1d ", i + 1 );
}
else
{
printf( "| %.2d", i + 1 );
}
}
printf( "|TOT" );
printf( "\n" );
printf( "--------------" );
for ( i = 0;i < s->parcoursJoue.nbTrou + 1;i++ )
{
printf( "----" );
}
printf( "\n" );
//affichage des valeurs de "par" pour chaque trou
printf( "valeur du par " );
for ( i = 0;i < s->parcoursJoue.nbTrou;i++ )
{
printf( "| %.1d ", s->parcoursJoue.listeTrous[i].par );
total += s->parcoursJoue.listeTrous[i].par;
}
printf( "| %.2d", total );
printf( "\n" );
total = 0;
printf( "--------------" );
for ( i = 0;i < s->parcoursJoue.nbTrou + 1;i++ )
{
printf( "----" );
}
printf( "\n" );
//affichage du score du joueur
printf( "score " );
for ( i = 0;i < s->parcoursJoue.nbTrou;i++ )
{
printf( "| " );
if ( s->points[i] > ( s->parcoursJoue.listeTrous[i].par ) )
printf( "%s", RED );
if ( s->points[i] < ( s->parcoursJoue.listeTrous[i].par ) )
printf( "%s", YELLOW );
printf( "%.1d %s", s->points[i], GREY );
total += s->points[i];
}
printf( "| %.2d", total );
printf( "\n" );
printf( "--------------" );
for ( i = 0;i < s->parcoursJoue.nbTrou + 1;i++ )
{
printf( "----" );
}
printf( "\n" );
}
/*
* paramètre d'entrées : le nombre de scores present dans le tableau des scores
*
* en entrées :
*
* paramètre de sortie :
*
* paramètre d'E/S tableau de pointeurs sur des scores
*
* en sortie : le tableau des scores trie
* selon la somme des coups par ordre croissant
* valeur retournée :
*
* DESCRIPTION : trier les scores du meilleur au plus mauvais
*
*/
void classement( typeScore *tab[], int nbScore )
{
int i, j, k;
typeScore *tmp;
int sommei = 0, sommej = 0;
for ( i = 0;i < nbScore;i++ )
{
sommei = 0;
// calcul de la somme des points au rang i
for ( k = 0;k < tab[i]->parcoursJoue.nbTrou;k++ )
sommei += tab[i]->points[k];
for ( j = i;j < nbScore;j++ )
{
sommej = 0;
// calcul de la somme des points au rang j
for ( k = 0;k < tab[j]->parcoursJoue.nbTrou;k++ )
sommej += tab[j]->points[k];
// si le score au rang j est plus petit qu'au rang i swapper les pointeurs
if ( sommej < sommei )
{
tmp = tab[i];
tab[i] = tab[j];
tab[j] = tmp;
}
}
}
}
/****************************************************************************************************
****************************************************************************************************
****************************************************************************************************
fonctions a coder/completer
****************************************************************************************************
****************************************************************************************************
****************************************************************************************************/
void afficherMenu(int nbParcours, int nbScores)
{
if(nbParcours > 0)
{
printf("[J] Jouer un parcours\n");
printf("[D] Jouer un parcours avec 2 joueurs\n");
printf("[V] Afficher un parcours\n");
}
if(nbScores > 0)
{
printf("[Z] Classement\n");
}
printf("[C] Creer un parcours\n");
printf("[Q] Quitter\n");
printf("Votre choix :");
}
/*
* paramètre d'entrées : un trou
*
* en entrées :
*
*
* paramètre de sortie :
*
* paramètre d'E/S
*
* en sortie : Affichage des champs du trou
* valeur retournée :
*
* DESCRIPTION : Affichage des caracteristiques d'un trou
*
*
*/
void afficherInfoTrou( typeTrou unTrou)
{
printf("[Trou numero %d |", unTrou.numero);
printf(" Distance %.2f metres |", unTrou.distance);
printf(" Par %d |", unTrou.par);
printf(" %d coups maximum]\n", unTrou.nbMaxCoups);
}
/*
* paramètre d'entrées : tableau de pointeur sur des parcours
nombre de parcours actuellement dans le tableau
*
* en entrées :
*
*
* paramètre de sortie :
*
* paramètre d'E/S
*
* en sortie : affichage de l'index(numero d'indice) de chaque parcours suivi de son nom
* valeur retournée :
*
* DESCRIPTION : Affichage des différents parcours disponibles
*
*
*/
void afficherLesParcours( typeParcours *tab[], int nbParcours )
{
int i;
for(i = 0; i <
nbParcours; i++)
{
printf("%d - %s\n", i, tab[i]->nom);
}
}
/*
* paramètre d'entrées : un pointeur sur le parcours a jouer
*
* en entrées : nom du joueur
* difficulte de la partie
*
* paramètre de sortie :
*
* paramètre d'E/S
*
* en sortie : affichage des differents coups joues
affichage du score
mise à jour du fichier des scores
* valeur retournée : un pointeur sur le score du joueur
*
* DESCRIPTION : creation d'un joueur avec son score,
* joue chaque trou du parcours.
*
*/
typeScore *jouerParcours( typeParcours *p )
{
typeScore *sc;
int i;
float niveau;
// creation d'un nouveau score
sc = ( typeScore* ) malloc( sizeof( typeScore ) );
printf( "votre nom :" );
scanf( "%s", sc->nomJoueur );
printf( "difficulte [0-infernale .. 5-tres facile]" );
scanf( "%d", &sc->difficulte );
niveau = 1.0 + 3.0 * ( float ) sc->difficulte;
// recopie des donnees du parcours fait par le joueur
memcpy( &sc->parcoursJoue, p, sizeof( typeParcours ) );
printf( "parcour %s\n", p->nom );
/*****************************************************************************************/
// pour chaque trou du parcours
// afficher les informations concernant le trou
// jouer le trou et sauvegarder le nombre de coups joue dans le tableau
// des points du joueur
for ( i = 0;i < p->nbTrou;i++ )
{
afficherInfoTrou( p->listeTrous[i] );
sc->points[i] = jouerTrou( p->listeTrous[i], niveau );
}
// afficher le score du joueur pour ce parcours
afficherScore( sc );
// sauvegarder ce score
sauvegarderScore(sc);
/*****************************************************************************************/
return sc;
}
void sauvegarderScore( typeScore *sc )
{
FILE *fd;
int erreurEcriture;
int erreurFClose;
fd = fopen( FICHIER_SCORE, "w+");
erreurEcriture = fwrite(sc, sizeof(typeScore), 1, fd);
if(erreurEcriture != 1)
{
printf("Probleme sauvegarde scores%s\n", strerror(errno));
exit(errno);
}
erreurFClose = fclose(fd);
if(erreurFClose == EOF)
{
printf("Probleme fermeture sauvegarde scores%s\n", strerror(errno));
exit(errno);
}
}
int chargerLesScores( typeScore *tab[] )
{
FILE *fd;
int i = 0;
int erreurLecture;
int erreurFClose;
fd = fopen(FICHIER_SCORE, "r");
if(fd == NULL)
{
printf("%s\n", strerror(errno));
exit(errno);
}
while(!feof(fd))
{
tab[i] = (typeScore*) malloc(sizeof(typeScore));
erreurLecture = fread(tab[i], sizeof(typeScore), 1, fd);
if(erreurLecture != 1)
{
if(!feof(fd))
{
printf("Probleme lecture chargement scores%s\n", strerror(errno));
exit(errno);
}
else
{
free(tab[i]);
}
}
else
{
i++;
}
}
erreurFClose = fclose(fd);
if(erreurFClose == EOF)
{
printf("Probleme fermeture chargement scores%s\n", strerror(errno));
exit(errno);
}
return i;
}
void jouerParcoursADeux( typeParcours *p )
{
typeScore *scP1;
typeScore *scP2;
int i;
float niveauP1;
float niveauP2;
// creation d'un nouveau score
scP1 = ( typeScore* ) malloc( sizeof( typeScore ) );
scP2 = ( typeScore* ) malloc( sizeof( typeScore ) );
printf( "Nom player 1 :" );
scanf( "%s", scP1->nomJoueur );
printf( "difficulte player 1 [0-infernale .. 5-tres facile]" );
scanf( "%d", &scP1->difficulte );
printf( "Nom player 2 :" );
scanf( "%s", scP2->nomJoueur );
printf( "difficulte player 2 [0-infernale .. 5-tres facile]" );
scanf( "%d", &scP2->difficulte );
niveauP1 = 1.0 + 3.0 * ( float ) scP1->difficulte;
niveauP2 = 1.0 + 3.0 * ( float ) scP2->difficulte;
// recopie des donnees du parcours fait par le joueur
memcpy( &scP1->parcoursJoue, p, sizeof( typeParcours ) );
memcpy( &scP2->parcoursJoue, p, sizeof( typeParcours ) );
printf( "parcour %s\n", p->nom );
// pour chaque trou du parcours
// afficher les informations concernant le trou
// jouer le trou et sauvegarder le nombre de coups joue dans le tableau
// des points du joueur
for ( i = 0;i < p->nbTrou;i++ )
{
afficherInfoTrou( p->listeTrous[i] );
printf("%s", scP1->nomJoueur);
scP1->points[i] = jouerTrou( p->listeTrous[i], niveauP1 );
printf("%s", scP2->nomJoueur);
scP2->points[i] = jouerTrou( p->listeTrous[i], niveauP2 );
}
afficherScore( scP1 );
afficherScore( scP2 );
}