PROFDINFO.COM

Votre enseignant d'informatique en ligne

LE DISTRIBUTEUR DE BOISSONS

Solution

#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>

#define COUT_BOISSON		80
#define NB_BOISSONS			5
#define DELAI_REMISE_PIECE	750
#define DELAI_FABRICATION	1500

using namespace std;

/*
 * Thread qui calcule la monnaie à rendre et affiche les pièces sur la sortie
 * standard.
 */

void* calculer_monnaie( void* argent )
{
	int nb5, nb10, nb25, nb100;	
	int monnaie = ( int )argent;
	
	if( monnaie != 0 )
	{
		nb100 = monnaie / 100;
		monnaie %= 100;
		nb25 = monnaie / 25;
		monnaie %= 25;
		nb10 = monnaie / 10;
		monnaie %= 10;
		nb5 = monnaie / 5;
	}
	
	while( nb100 > 0 )
	{
		delay( DELAI_REMISE_PIECE );
		puts( "$1,00 " );
		fflush( stdout );
		nb100--;
	}

	while( nb25 > 0 )
	{
		delay( DELAI_REMISE_PIECE );
		puts( "$0,25 " );
		fflush( stdout );
		nb25--;
	}	

	while( nb10 > 0 )
	{
		delay( DELAI_REMISE_PIECE );
		puts( "$0,10 " );
		fflush( stdout );
		nb10--;
	}

	while( nb5 > 0 )
	{
		delay( DELAI_REMISE_PIECE );
		puts( "$0,05 " );
		fflush( stdout );
		nb5--;
	}
	
	pthread_exit( NULL );
	return 0; // pour faire plaisir au compilateur
}

/*
 * Thread qui simule la fabrication d'une boisson et affiche un message sur la
 * sortie standard.
 */
void* fabriquer_boisson( void* boisson )
{
	int retour;
	
	delay( DELAI_FABRICATION );
	
	if( ( rand() % 3 ) == 0 )
	{
		puts( "Probleme majeur: veuillez appeler reparateur" );
		retour = 1;
	}
	else
	{
		printf( "Votre %s est servie !\n", ( char* )boisson );
		retour = 0;
	}
	
	pthread_exit( ( void* )retour );
	return 0; // pour faire plaisir au compilateur
}

/*
 * Fonction qui affiche le menu.
 */
void afficher_choix( int argent )
{
	system( "clear" );
	puts( "    Distributrice de boissons" );
	printf( "    Montant entre: %d\n", argent );
	puts( "\n" );
	puts( "(a) Vodka" );
	puts( "(b) Cognac" );
	puts( "(c) Martini" );
	puts( "(d) Quick aux fraises" );
	puts( "(e) Jus de carottes" );
	puts( "\n" );
}

/*
 * Fonction qui lit les entrées de l'utilisateur (pièces de monnaie et
 * commande) et retourne 0 s'il s'agit d'une pièce ou le caractère si c'est un
 * caractère.
 */
char lire_commande( int * argent )
{
	char ligne[ 5 ];
	int nombre;
	int retour;
	
	fgets( ligne, 5, stdin );
	afficher_choix( *argent );
		
	nombre = atoi( ligne );
		
	if( ( nombre ==  5 ) || ( nombre ==  10 ) ||
		( nombre == 25 ) || ( nombre == 100 ) )
	{
		*argent += nombre;
		retour = 0;
	}	
	else // ce n'est pas un nombre
	{
		retour = ligne[ 0 ];
	}
	
	return retour;
}

/*
 * Fonction principale.
 */
int main( int argc, char *argv[] )
{
	int total = 0;
	//char* boissons[ NB_BOISSONS ];
	char chose[ 10 ];
	pthread_t fabriquer;
	pthread_t calculer;
	bool fini = false;
	char commande;
	
	int statut_fabrication = 0;
	srand( time( NULL ) );
	
	strcpy( chose, "boisson" );
	
	while( !fini )
	{
		afficher_choix( total );
		
		commande = lire_commande( &total );

		if( commande != 'z' )
		{
			if( ( commande >= 'a' ) && ( commande <= 'e' ) &&
				( total >= COUT_BOISSON ) )
			{
				pthread_create( &fabriquer, NULL, fabriquer_boisson,
					( void* ) chose );
				pthread_create(	&calculer, NULL, calculer_monnaie,
					( void* )( total - COUT_BOISSON ) );
			
				total = 0;
				afficher_choix( total );
				
				pthread_join( calculer, NULL );
				pthread_join( fabriquer, ( void** )&statut_fabrication );				
				
				if( statut_fabrication )
				{
					fini = true;
				}
				else
				{
					printf( " pour continuer" );
					getc( stdin );
				}
			}
		}
		else
		{
			fini = true;
			puts( "Machine arretee" );
		}

	}
	pthread_exit( 0 );
}