Partage
  • Partager sur Facebook
  • Partager sur Twitter

Faire un Menu de selection en mode Console C

    22 novembre 2017 à 11:33:22

    Bien le bonjours tout le monde.

    Comme dit dans le titre, j'aimerais savoir faire un menu de Sélection où grâce a ce petit caractère ">" qui nous servira de curseur, permettre aux utilisateur de choisir leur choix. Je m'explique;

    A l'heure actuel bien que je débute, j'ai pour projets de faire un petit jeux en mode Console. Ce petit jeux consistera à faire une histoire avec avec l'utilisateur. Bien entendu, le scénario et l'histoire global est déjà écrites.
    Mais étant donnée qu'il y aura que du texte, je veux faire interagir l'utilisateur au maximum, c'est-à-dire qu'il y aura beaucoup de choix possible et selon c'est réponses il sera diriger vers d'autre scénario.

    Je peux également faire en sorte de demander à l'utilisateur de taper sur les touche 1, 2, 3, 4... Pour choisir le choix qu'il décidera, mais ça ne m'intéresse pas vraiment, je veux vraiment quelque chose un peu plus poussé.
    J'avais pour idée aussi de faire un menu déroulant pour donner un peu plus de couleurs que le blanc et noir, mais au bon du coup, c'est vraiment mais vraiment pas terrible.

    Je vous donne un exemple concret.

    Personnage = Hey est-ce que tu m'entends ?
    Utilisateur = Oui, je ne suis pas sourd
    Personnage = Hé hé oui, désolé. J'espère que je ne te dérange pas.

    Choix utilisateur
    1 = Non pas du tout
    2 = Je suis occuper là...
    3 = Ça dépends c'est pourquoi ?

    Si réponse 1 | Personnage = Tu n'aurais pas vu une jeune femme par hasard ?
    Si réponse 2 | Personnage = Excusez-moi... Pourrais-tu m'accorder quelque secondes ?
    Si réponse 3 | Personnage = Pour savoir si tu aurais pas croisé une jeune femme...
    Etc... Etc... Etc...

    Au bout du coup, il y aura une ou plusieurs histoires de cette façon, avec un scénario écrit au préalable.

    Du coup, je vous envoie le code que j'ai pu faire;

    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
     
    void Locate(SHORT x,SHORT y)
    {
        HANDLE hmenu=GetStdHandle(STD_OUTPUT_HANDLE);
        COORD Pos;
        Pos.X = x;
        Pos.Y = y;
        SetConsoleCursorPosition(hmenu,Pos);
    }
     
    void Afficher(int curs)
    {
        Locate(3,0);
        printf("%c Jouer\n\n",(curs==0)?'>':' ');
        Locate(3,2);
        printf("%c Quitter\n\n",(curs==1)?'>':' ');
        Locate(3,4);
    }
     
     
     
    int Choisir()
    {
        int curs = 0;
        int touche;
        do
        {
            Afficher(curs);
            touche = _getch();
            if (touche==0xE0) // fleche : le code fleche renvoie 2 caracteres.
            {
                touche = _getch();
                if (touche==0x50 && curs==0)  // fleche bas
                    curs = 1;
                else if (touche==0x48 && curs==1)  // fleche bas
                    curs = 0;
            }
        } while (touche!=0x0D);  // enter
        return curs;
    }
     
    int main()
    {
        int choix;
        choix = Choisir();
        Locate(0,7);
        printf("Vous avez choisi : %s\n\n\n",(choix==0)?"Jouer":"Quitter");
        return 0;
    }

    Le code fonctionne c'est pas le soucis, mais ça va me posé d'énorme problèmes à la longue.
    Je vais devoir faire énormément de variables, de void.

    Du coup, est-ce que vous avez une technique pour faire un menu déroulant dans un void (Que je placerais dans un Fichier.h) qui me permettra simplement de placer dans une boucle quand il y aura un choix. Mais j'aimerais si possible que sa soit simplement le curseur qui se déplace sans avoir à écrire comme dans mon code plusieurs fois les mêmes phrases.

    Maintenant regarder se code "C'est presque le même avec quelque trucs rajoutés.

    void Locate(SHORT x,SHORT y)
    {
        HANDLE hmenu=GetStdHandle(STD_OUTPUT_HANDLE);
        COORD Pos;
        Pos.X = x;
        Pos.Y = y;
        SetConsoleCursorPosition(hmenu,Pos);
    }
     
    void Afficher(int curs)
    {
        Locate(3,0);
        printf("%c Jouer\n\n",(curs==0)?'>':' ');
        Locate(3,2);
        printf("%c Réglement\n\n",(curs==1)?'>':' ');
        Locate(3,4);
        printf("%c Quitter\n\n",(curs==2)?'>':' ');
    }
     
     
     
    int Choisir()
    {
        int curs = 0;
        int touche;
        do
        {
            Afficher(curs);
            touche = _getch();
            if (touche==0xE0) // fleche : le code fleche renvoie 2 caracteres.
            {
                touche = _getch();
                if (touche==0x50 && curs==0)  // fleche bas
                    curs = 1;
                else if (touche==0x50 && curs==1)  // fleche bas
                    curs = 2;
                else if (touche==0x48 && curs==2)  // fleche haut
                    curs = 1;
                else if (touche==0x48 && curs==1)  // fleche haut
                    curs = 0;
            }
        } while (touche!=0x0D);  // enter
        return curs;
    }
     
    int main()
    {
        int choix;
        choix = Choisir();
        Locate(0,7);
        printf("Vous avez choisi : %s\n\n\n",(choix==0)?"Jouer":"Réglement":"Quitter");
        return 0;
    }

    Donc, j'ai changer un peu mon code, j'ai rajouter un Menu Réglement; Si vous regarder bien le dernier printf 

    printf("Vous avez choisi : %s\n\n\n",(choix==0)?"Jouer":"Réglement":"Quitter");

    Qui se trouve tout en bas de page. Il ne fonctionne pas. Ça me dis une erreur; Error: expected ')' before ':' token

    Puis avouez quand même qu'un jeux comme j'aimerais faire, avec un code comme ça pour chaque choix, je vais jamais en voir le bout et je prendrais le chemin super long. Je suis sur que vous arriverez à me donner un raccourcis.

    J'espère que j'ai pas étais trop flou, ni trop vague et que vous allez comprendre mon problème. Si vous avez des questions, n'hésitez pas.
    Je vous dis un grand merci et à bientôt !



    • Partager sur Facebook
    • Partager sur Twitter
      22 novembre 2017 à 11:59:44

      Salut, essaie ça :

      void Locate(SHORT x, SHORT y)
      {
      	HANDLE hmenu = GetStdHandle(STD_OUTPUT_HANDLE);
      	COORD Pos;
      	Pos.X = x;
      	Pos.Y = y;
      	SetConsoleCursorPosition(hmenu, Pos);
      }
      
      int Choix(const char* ch[],int taille,int y)
      {
      	int i,curs = 0;
      	Locate(0, y);
      	for (i = 0; i < taille; i++)
      		printf("  %s\n", ch[i]);
      	Locate(0, y);
      	printf(">");
      	while (1)
      	{
      		int touche = _getch();
      		if (touche == 0x50 && curs < taille-1)
      			curs++;
      		if (touche == 0x48 && curs > 0)
      			curs--;
      		if (touche == 0x0D)
      			return curs + 1;
      		Locate(0, y);
      		for (i = 0; i < taille; i++)
      			printf("%c\n", (i == curs) ? '>':' ');
      	}
      	return 0;
      }
      
      
      int main()
      {
      	const char* tab[] = { "Non pas du tout","Je suis occupé là","Ça dépend c'est pourquoi ?" };
      	int c = Choix(tab,3,0);
      ...

      Ainsi, tu n'as qu'une fonction : tu lui passes tous tes choix, la taille (3) et la position y de ton menu, ici 0

      • Partager sur Facebook
      • Partager sur Twitter

      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

        22 novembre 2017 à 12:28:19

        Et à chaque fois, quand il y aura un choix à faire je devrais écrire tout simplement

        const char* tab[] = { "Non pas du tout","Je suis occupé là","Ça dépend c'est pourquoi ?" };
            int c = Choix(tab,3,0);

        Remplacer le texte par les choix que je proposes, remplace le chiffre 3 par le nombre des choix proposés et changer le 0 si je voudrais changer les coordonner des choix non ??

        J'ai l'impression que ton code à l'air d'être parfait ! Je te remercie énormément en espérant que j'ai vu juste. Parce que si je dois écrire tout se code à chaque fois, ça sera super long. Bien-sur le tout, je peu le couplet avec des swith case?? 




        • Partager sur Facebook
        • Partager sur Twitter
          22 novembre 2017 à 14:01:14

          Salut,

          En effet, la fonction est écrite une fois pour toutes !

          Tu  n'auras pas à la réécrire. Tu pourrais l'appeler autant de fois que tu veux avec d'autres valeurs si tu veux, elle marchera. Tu n'auras pas à la réécrire. Essaie !

          Voici un exemple pour faire 3 choix de suite, sans réécrire la fonction :

          const char* tab1[] = {"truc","machin","chose"};
          const char* tab2[] = {"bidule","truc"};
          const char* tab3[] = {"plouf","paf","pif","pouf"};
          
          int c1 = Choix(tab1,3,0);
          int c2 = Choix(tab2,2,5);
          int c3 = Choix(tab3,4,10);



          -
          Edité par Fvirtman 22 novembre 2017 à 14:04:13

          • Partager sur Facebook
          • Partager sur Twitter

          Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

            22 novembre 2017 à 15:30:05

            Oh magnifique, ça ressemble fortement à se que je voulais depuis le début ! Franchement tes trop fort *-*

            En tout cas je pense garder cette méthode là, et je vais l'apprendre par coeur, comprendre l'intégralités du petit code pour m'en inspiré et le refaire à ma sauce :)

            Je te dis un grand merci :)

            J'ai rajouter un int x

            int Choix(const char* ch[],int taille,int y, int x)

            J'ai modifier le programme pour qu'il fonctionne et que le x soit pris en compte;

            int Choix(const char* ch[],int taille,int y, int x)
            {
                int i,curs = 0;
                Locate(x, y);
                for (i = 0; i < taille; i++)
                    printf("  %s\n", ch[i]);
                Locate(x, y);
            
                while (1)
                {
                    int touche = _getch();
                    if (touche == 0x50 && curs < taille-1)
                        curs++;
                    if (touche == 0x48 && curs > 0)
                        curs--;
                    if (touche == 0x0D)
                        return curs + 1;
                    Locate(x, y);
                    for (i = 0; i < taille; i++)
                        printf("%c\n\n", (i == curs) ? '>':' ');
                }

            Et donc ici quand je met les coordonnée de mon choix exemple 15*15 pour qu'il soit à l'endroit souhaiter

                int c = Choix(tab,3,0,15);

            Il y a que le premier choix qui se déplace. Les autres choix se déplace mais que dans les coordonnés Y, Il reste à 0 dans les coordonnées X

            Les accent non plus ne fonctionne pas dans le menu des choix. Ils fonctionne très bien quand j'utilise un simple printf. Mais il ne fonctionne pas dans la fonction 

            char* tab[] = {"Jouer\n","R%cglement\n","Quitter\n",130};

            Peu importe se que je fais il y a soit une erreur, soit ça ne change rien. Je ne sais plus quoi faire pour pouvoir choisir les coordonnée en X et pouvoir afficher les accents. Mais je trouve ça étrange qu'il y a que le premier mot/phrase de la fonction

            const char* tab3[] = {"1 mot/phrase","etc..","etc..."};

            Qui se déplace ! Par contre, en Y "de haut en bas", j'ai aucune soucis.


            -
            Edité par Zanaki 22 novembre 2017 à 21:18:35

            • Partager sur Facebook
            • Partager sur Twitter
              25 juillet 2018 à 10:58:21

              Salut a vous, 

              cette facon de coder m'interesse vraiment... je serais curieux de savoir comment est ce que tu as couplé cela avec des Switch case...

              merci 

              • Partager sur Facebook
              • Partager sur Twitter
                25 juillet 2018 à 14:10:55

                Salut, juste un petit truc, tu peux aussi voir du coté de la ncurse ;) il y à pas mal de choses là dedans pouvant être très utile
                • Partager sur Facebook
                • Partager sur Twitter
                Toujours plus
                  25 juillet 2018 à 14:42:23

                  voila un code fonctionnel sous linux, je serai curieux de savoir pour Windows :

                  #include <stdio.h>
                  #include <stdarg.h>
                  #include <termios.h>
                  #include <stdlib.h>
                  #include <string.h>
                  #include <unistd.h>
                  
                  int menu ( int argc, ... )
                  {
                  	static struct termios oldMask, newMask;
                  	va_list list;
                  	char **table  = NULL;
                  
                  	int i = 0;
                  	int choix = -1;
                  	int position = 0;
                  
                  	tcgetattr ( STDIN_FILENO, &oldMask );
                  	newMask = oldMask;
                  	newMask.c_lflag &= ~(ICANON); // avoid <enter>
                  	newMask.c_lflag &= ~(ECHO); // hide text typed
                  
                  	tcsetattr( STDIN_FILENO, TCSANOW, &newMask );
                  
                  	table = malloc ( sizeof ( char * ) * argc );
                  
                  	va_start ( list, argc );
                  	for ( i = 0; i < argc; i++ )
                  	{
                  		table[ i ] = va_arg ( list, char* );
                  	}
                  	va_end ( list );
                  
                  	do
                  	{
                  		for ( i = 0; i < argc; i++ )
                  		{
                  			printf ( " %c %s\n", ( position == i )?'>':' ', table[ i ] );
                  		}
                  		
                  		switch ( i = getchar ( ) )
                  		{
                  			case 0x41:
                  			{ // up key is : 0x1b5b41
                  				position = ( position - 1 + argc ) % argc;
                  				break;
                  			}
                  			case 0x42:
                  			{ // down key is : 0x1b5b42
                  				position = ( position + 1 ) % argc;
                  				break;
                  			}
                  			case '\n':
                  			{
                  				choix = position;
                  				break;
                  			}
                  		}
                  		if ( choix < 0 )
                  		{
                  			printf ( "\e[%dA", argc );
                  		}
                  	}
                  	while ( choix < 0 );
                  
                  	free ( table );
                  
                  	tcsetattr( STDIN_FILENO, TCSANOW, &oldMask );
                  
                  	return ( choix );
                  }
                  
                  int main ( void )
                  {
                  	printf ( "choice : %d\n", menu ( 3, "A--", "B--", "C--" ) );
                  	return ( 0 );
                  }
                  
                  



                  -
                  Edité par ox223252 25 juillet 2018 à 14:51:48

                  • Partager sur Facebook
                  • Partager sur Twitter

                  la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

                  Mon GitHub

                  Faire un Menu de selection en mode Console C

                  × 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.
                  • Editeur
                  • Markdown