IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Jeu du plus ou moins avec une fonction récursive


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 16
    Points : 8
    Points
    8
    Par défaut Jeu du plus ou moins avec une fonction récursive
    Bonjour à tous,

    J'ai comme projet de faire un programme en c qui effectue le célèbre jeux du PLUS OU MOINS. Jusque là tout va bien mais c'est dans la deuxième partis du TD. C'est l'ordinateur qui doit trouver le nombre que vous avez dans votre tête. Il faut juste l'aider en lui disant + ou -
    Il y a une condition il faut utiliser la fonction recursive.

    Je me suis pas mal renseigner la dessus. Je trouve d'ailleurs cette fonction génial mais assez dur pour un novice comme moi à mettre en place. Comme mon père me disait, C'est en programment que l'on devient programmeur !

    Donc voici en gros les règles de l'exercice:
    Choisissez un nombre entre 0 et 100.
    L'ordinateur doit pouvoir trouver votre nombre, pour cela utiliser la touche "1" pour plus petit et "2" pour plus grand et "3" pour c'est gagné !
    Utiliser la recurrence.

    J'ai commencé donc à écrire un programme depuis 2 jours et je vous avouerais que je bloque au niveau des intervalles.
    Prenons par exemple le nombre 22.
    Le programme me demande au début si il est plus petit ou plus grand que 50.
    Je répond plus petit.
    Il me demande ensuite si il est plus petit ou plus grand que 25.
    Je répond plus petit.
    Il me demande ensuite si il est plus petit ou plus grand que 12.
    Je lui répond plus grand.
    LA il me demande si il est plus petit ou plus grand que 6. Je vous avouerais que je bloque. Mon code est surement faux mais je n'arrive pas à trouvé une solution. Si quelqu'un pouvait m'éclairer.

    Pour info: Je développe sur Xcode 6.0.1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
     
    const int MIN = 0;
    const int MAX = 100;
     
     
    void intervalle(int MIN, int MAX)
    {
        int INT_T; // intervalle à l'instant t
        int x;
     
        INT_T = ((MAX-MIN)/2);
     
        printf("Est il plus grand (1) ou plus petit (2) que : %d ? ou est ce %d ? (3) \n", INT_T, INT_T);
        scanf("%d", &x);
     
        if ( x == 1 ) /* nombre mystère > INT_T */
        {
     
            INT_T = (((MAX-MIN)/2) + MIN);
            MIN = INT_T;
            intervalle(MIN, MAX);
        }
        if ( x == 2) /* nombre mystère < INT_T */
        {
            MAX = INT_T;
            intervalle(MIN, MAX);
        }
        if ( x == 3) /* c'est le nombre mystère */
        {
            printf("C'est gagné, le chiffre mystère est %d \n", INT_T);
            exit (0);
        }
    }
     
    int main ()
    {
        intervalle(0,100);
        return 0;
    }


    MERCI A TOUS

  2. #2
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Je pense que tu n'utilise pas la bonne méthode concernant ton algorithme, l'as-tu testé sur une feuille de papier avant de le coder?
    En pseudo code?

    J'aurais bien envie de te donner la solution de suite, mais ça serait trop simple .
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Franchement, pour cet exemple la récursivité me paraît aussi "forcée" que pour le cas d'école de la factorielle. Mais admettons.

    Ton problème, c'est que tu as deux formules différentes pour le calcul de INT_T, et seule l'une d'entre elles est bonne.
    De plus, ta convention de nommage est un peu bizarre et tu devrais séparer l'interrogation dans une autre fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    /*Comme strcmp: Retourne <0 si valeurATester est inférieur au nombre mystère,
    >0 si valeurATester est supérieur au nombre mystère,
    0 si égal.*/
    int ComparerNombre(int valeurATester)
    {
    	int x;
    	int saisieOK = 0;
    	int resultat = 0;
    	/*On saisit en boucle jusqu'à ce qu'on ait une valeur valide.*/
    	do
    	{
    		printf("Est-il plus grand (1), plus petit (2) ou égal (3) à %d?\n", valeurATester);
    		scanf("%d", &x);
    		saisieOK = 1;
    		switch(x)
    		{
    		case 1: 
    			resultat = -1; /*Nombre mystère est plus grand -> valeurATester est plus petit*/
    			break; 
    		case 2:
    			resultat = 1; /*Nombre mystère est plus petit -> valeurATester est plus grand*/
    			break;
    		case 3:
    			resultat = 0; /*Nombre mysère est égal*/
    			break;
    		default:
    			saisieOK = 0; /*Valeur inconnue*/
    			getchar(); /*Pour éviter de reboucler si l'utilisateur a tapé une lettre*/
    			break;
    		}
    	}
    	while(!saisieOK);
    	return resultat;
    }
     
    int TrouverDansIntervalle(int valeurMin, int valeurMax)
    {
    	int milieu = (valeurMax-valeurMin)/2 + valeurMin;
    	int resCmp;
    	if(milieu == valeurMin) /*peut arriver si valeurMax == valeurMin+1*/
    		milieu = valeurMin+1; /*Pour éviter une recherche infinie*/
     
    	printf("[Debug: Recherche dans [%d, %d], milieu est %d.]\n", valeurMin, valeurMax, milieu);
     
    	resCmp = ComparerNombre(milieu);
    	if(resCmp == 0)
    		return milieu;
    	else if(resCmp < 0) /*milieu est inférieur au nombre mystère, il faut donc rechercher dans la moitié supérieure*/
    		return TrouverDansIntervalle(milieu, valeurMax);
    	else /*milieu est supérieur au nombre mystère, il faut donc rechercher dans la moitié inférieure*/
    		return TrouverDansIntervalle(valeurMin, milieu);
    }
     
    int main()
    {
    	int valeurTrouvee = TrouverDansIntervalle(0, 100);
    	printf("C'est gagné, le chiffre mystère est %d \n", valeurTrouvee);
    }
    Avec ça, on obtient des fonctions plus petites, les entrées/sorties sont séparées des calculs, et normalement le code reste facile à comprendre.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 16
    Points : 8
    Points
    8
    Par défaut
    Wahh !!

    C'est clair comme de l'eau de roche avec votre code.
    Il fallait que je fasse deux fonctions distinctes.
    Je vous remercie énormément, cela va vraiment m'aider à comprendre.

  5. #5
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Puisqu'on est au stade de donner les réponse ...... Voici une meilleur méthode:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    int chercherValeur(int min, int max)
    {
    	// Nombre courant
    	int courant = ((max - min) / 2) + min;
    	char reponse = '\0';
    	int continuer = 1;
     
    	// Tant qu'on a pas une réponse compréhensible
    	while (continuer)
    	{
    		printf("Est il plus grand (1) ou plus petit (2) que : %d ? ou est ce %d ? (3) \n", courant, courant);
    		// Si erreur de lecture
    		if ((reponse = getchar()) > 0)
    		{
    			printf("Erreur de lecture");
    			continuer = 0;
    		}
    		else
    		{
    			switch (reponse)
    			{
    			case '1':
    				// Le nombre est plus grand donc on referme notre recherche sur [courant-max]
    				return (chercherValeur(courant, max));
    			case '2':
    				// Le nombre est plus petit donc on referme notre recherche sur [min-courant]
    				return (chercherValeur(min, courant));
    			case '3':
    				// Le nombre est trouvé donc on remonte toute la pile d'appel
    				return (courant);
    			}
    		}
    	}
     
    	return (-1);
    }
     
    int main(int argc, char* argv[])
    {
    	int valeur = chercherValeur(0,100);
    	if (valeur >= 0)
    		printf("La valeur est = %d\n", valeur);
    	system("PAUSE");
    	return 0;
    }
    Plus simple, plus rapide, moins de blabla.
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 16
    Points : 8
    Points
    8
    Par défaut
    Du coup j'ai réussi à faire avec la récursivité mais en repartant d'une feuille blanche et en m'aidant de vos codes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    int x;
    int valeur;
    int compteur;
     
    int main ()
    {
        int min = 0;
        int max = 100;
     
        printf("rentre un nombre\n");
        scanf("%d", &x);
     
        compteur = 1;
        while (cherche(min, max, 1));
        printf("valeur : %d en %d fois \n",valeur, compteur);
     
    }
     
     
     
     
     
     
    int cherche ( int min, int max)
    {
        int newmin;
        int newmax;
     
        if ((((max-min)/2)+min) !=x)
        {
            if ((((max-min)/2)+min) > x){
                newmax = ((max-min)/2)+min;
                compteur++;
                cherche(min, newmax);
            } else {
                newmin = ((max-min)/2)+min;
                compteur++;
                cherche(newmin,max);
            }
        } else {
            valeur = (((max-min)/2)+min);
        }
        return 0;
    }
    Le code marche bien, en plus de ça j'ai rajouté un petit compteur. Le seul HIC c'est qu'il perd la tête quand notre chiffre est 100 (la limite de l'intervalle).

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Tu devrais essayer d'obtenir une version sans variable globale.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/08/2014, 07h28
  2. Jeu de plus ou moins avec images
    Par CloudyClad dans le forum Général JavaScript
    Réponses: 18
    Dernier message: 18/07/2013, 20h08
  3. Réponses: 7
    Dernier message: 15/07/2011, 15h22
  4. Réponses: 3
    Dernier message: 03/03/2010, 19h05
  5. Permutation avec une fonction récursive
    Par nypahe dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 29/04/2009, 07h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo