Partage
  • Partager sur Facebook
  • Partager sur Twitter

[ERREUR] fonctions qui marche mal

Sujet résolu
    16 juin 2018 à 17:58:52

    Bonjour, J'ai un problème dans mon code, en solo le mélange des lettres ne se fait pas bien et des lettres partent, je vous laisse compiler pour voir ou se trouve le problème, merci de votre aide!

    #include <iostream>
    #include <string>
    #include <ctime>
    #include <cstdlib>
    #include <fstream>
    
    using namespace std;
    
    string aleatoireMotMystereMulti (string motMystere)
    {
    	int position;
    	string melange;
    	srand(time(0));
    	while(motMystere.size() != 0)
    	{
    		position = rand() % motMystere.size();
    
    		melange += motMystere[position];
    
    		motMystere.erase(position,1);
    	}
    
    	return melange;
    }
    
    char choixCoups (char choixCoupsMA, int nbreCoups, char choixCoupsA)
    {
    	cout << "Choisissez le nombre de coups en mode manuel = M, en mode automatique = A ou bien aucun coups = C: "; //choix mode auto, manuel
    	cin >> choixCoupsMA;
    	cin.ignore();
    
    	if(choixCoupsMA == 'M')
    	{
    	cout << "Choisissez le nombre de coups maximum : "; //choix nombre de coups max
    	cin >> nbreCoups;
    	cin.ignore();
        }
        else if(choixCoupsMA == 'A')
        {
        	cout << "- Débutant (15 coups) = D" << endl << "- Confirmé (5 coups) = C" << endl << "- Expert (3 coups) = E" << endl << endl;
        	cout << "Choisissez : ";
        	cin >> choixCoupsA;
        	cin.ignore();
    
        	switch (choixCoupsA)
        	{
        		case 'D':
        		nbreCoups = 15;
        		break;
        		case 'C':
        		nbreCoups = 5;
        		break;
        		case 'E':
        		nbreCoups = 3;
        		break;
        	}
        }
    
    	cout << endl << endl << endl << endl << endl << endl << endl << endl << endl << endl << endl << endl << endl << endl << endl << endl << endl << endl<< endl << endl << endl << endl << endl << endl;
    
    	return nbreCoups;
    
    }
    
    string motAleatoireSolo(string motMystere)
    {
    	ifstream dico ("dico/dico.txt");
    	if(dico)
    	{
    		
    		srand (time(0));
    		int nombreDico = 323577, randomNombre;
    
    
    		randomNombre = rand() % nombreDico;
    
    		for(int i ; i<randomNombre ; i++)
    		{
    			getline(dico, motMystere);
    		}
    	}
    	else
    	{
    		cout << "ERREUR : impossible d'ouvrir ce fichier !" << endl;
    	}
    	return motMystere;
    }
    string melangeAleatoireSolo(string motMystere)
    {
    	int position;
    	string melange;
    	do
    	{
    		position = rand() % motMystere.size();
    
    		melange += motMystere[position];
    
    		motMystere.erase(position,1);
    	}while(motMystere.size() != 0);
    	return melange;
    }
    
    int main()
    {
    	srand (time(0));
    
    	string motMystere, motRecherche;
    	char choixFin, regle, choixMultiSolo, choixCoupsMA, choixCoupsA;
    	int nbreCoups;
    
    	do
    	{
    
    	motMystere = " ";
    	motRecherche = " ";
    	choixFin = ' ';
    	regle = ' ';
    	choixMultiSolo = ' '; // remise a 0 des variables
    	choixCoupsMA = ' ';
    	choixCoupsA = ' ';
    	nbreCoups = 0;
    
    	cout << "Bonjour et bienvenue dans le jeu nommé : Le mot mystère, tout d'abord choisissez de lire les règles ou pas (O/N) : "; //choix regle
    	cin >> regle;
    	cin.ignore();
    	cout << endl << endl;
    
    	if(regle == 'O')
    	{
    		cout << "                            --Les règles sont simples--" << endl << endl; // regle
    		cout << "- en mode solo, tu doit trouver un mot qui a était mélangé, mais si par malheur ton nombre de coups que tu avais prédéfinis et tombé a 0, alors tu a perdu!" << endl;
    		cout << "- en mode multijoueur, le joueur 1 choisit un mot et un nombre de coups maximum puis les règles du mode solo s'applique" << endl << endl; 
    	}
    
    	cout << "Choisissez, pour mode solo = S et pour mode multijoueur = M : ";
    	cin >> choixMultiSolo;
    	cin.ignore();
    
    	if(choixMultiSolo == 'S') // jeu solo
    	{
    		motMystere = motAleatoireSolo(motMystere);
    		string motHazard = melangeAleatoireSolo(motMystere);
    		cout << motHazard << endl;
    		cout << motMystere << endl;
    
    		cout << "Bienvenue, le mot mystère à été choisis aléatoirement par l'ordinateur maintenant a vous de le trouver !" << endl << endl;
    
    		nbreCoups = choixCoups(choixCoupsMA, nbreCoups, choixCoupsA);
    
    		if(choixCoupsMA != 'C') // avec les coups
    		{
    		cout << "lettres au hazard : " <<  motHazard << "                             Nombre restant de coups : " << nbreCoups << endl;
    		cout << "Quels est le mot : ";
    		getline(cin, motRecherche);
    		nbreCoups--;
    		cout << endl << endl;
    	
    
    	do//recherche du motMystere
    	{
    		cout << "lettres au hazard : " <<  motHazard << "                             Nombre restant de coups : " << nbreCoups << endl;
    		cout << "Quels est le mot : ";
    		getline(cin, motRecherche);;
    		cout << endl << endl;
    
    		if(motRecherche != motMystere)
    		{
    			nbreCoups--;
    		}
    
    		if(nbreCoups == 0)
    		{
    			cout << "Dommage, vous n'avez plus de coups possibles et le mot était : " << motMystere << endl; // jeu multi perdu
    		}
    	}while(motRecherche != motMystere && nbreCoups != 0);
        }
        else if(choixCoupsMA == 'C') // sans les coups
        {
        	cout << "lettres au hazard : " <<  motHazard << endl;
    		cout << "Quels est le mot : ";
    		getline(cin, motRecherche);
    		nbreCoups--;
    		cout << endl << endl;
    	
    
    	while(motRecherche != motMystere)//recherche du motMystere
    	{
    		cout << "lettres au hazard : " <<  motHazard << endl;
    		cout << "Quels est le mot : ";
    		getline(cin, motRecherche);;
    		cout << endl << endl;
    	}
        }
    	if(motRecherche == motMystere)
    	{
    		cout << "Bravo, tu a trouvé le mot mystère qui était : " << motMystere << ", en " << nbreCoups  << " coups restant!" << endl << endl; //jeu multi gagné
    	}
    
    		cout << "Voulez refaire une partie (O/N) : "; // choix fin
    		cin >> choixFin;
    		cin.ignore();
    		cout << endl << endl;
    	}
    
    	
    
    
    	else if(choixMultiSolo == 'M') // jeu multi
    	{
    	cout << endl << "Bienvenue Joueur 1, choisis un mot mystère que devra trouver joueur 2 : ";//choix motMystere
    
    	getline(cin, motMystere);
    	cout << endl;
    
    	nbreCoups = choixCoups(choixCoupsMA, nbreCoups, choixCoupsA); // choix de tout les coups
    
    	string motHazard = aleatoireMotMystereMulti(motMystere);//mélange du motMystere
    
    
    		if(choixCoupsMA != 'C') // avec les coups
    		{
    		cout << "lettres au hazard : " <<  motHazard << "                             Nombre restant de coups : " << nbreCoups << endl;
    		cout << "Quels est le mot : ";
    		getline(cin, motRecherche);
    		nbreCoups--;
    		cout << endl << endl;
    	
    
    	while(motRecherche != motMystere && nbreCoups != 0)//recherche du motMystere
    	{
    		cout << "lettres au hazard : " <<  motHazard << "                             Nombre restant de coups : " << nbreCoups << endl;
    		cout << "Quels est le mot : ";
    		getline(cin, motRecherche);;
    		cout << endl << endl;
    
    		if(motRecherche != motMystere)
    		{
    			nbreCoups--;
    		}
    
    		if(nbreCoups == 0)
    		{
    			cout << "Dommage, vous n'avez plus de coups possibles et le mot était : " << motMystere << endl; // jeu multi perdu
    		}
    	}
        }
        else if(choixCoupsMA == 'C') // sans les coups
        {
        	cout << "lettres au hazard : " <<  motHazard << endl;
    		cout << "Quels est le mot : ";
    		getline(cin, motRecherche);
    		nbreCoups--;
    		cout << endl << endl;
    	
    
    	while(motRecherche != motMystere)//recherche du motMystere
    	{
    		cout << "lettres au hazard : " <<  motHazard << endl;
    		cout << "Quels est le mot : ";
    		getline(cin, motRecherche);;
    		cout << endl << endl;
    	}
        }
    	if(motRecherche == motMystere)
    	{
    		cout << "Bravo, tu a trouvé le mot mystère qui était : " << motMystere << ", en " << nbreCoups  << " coups" << endl << endl; //jeu multi gagné
    	}
    
    		cout << "Voulez refaire une partie (O/N) : "; // choix fin
    		cin >> choixFin;
    		cin.ignore();
    		cout << endl << endl;
    	}
    	
    	} while(choixFin == 'O');
    
    
    
    }



    -
    Edité par JaqueAube 16 juin 2018 à 18:39:27

    • Partager sur Facebook
    • Partager sur Twitter
      16 juin 2018 à 18:28:37

      Bonjour,

      Le message qui suit est une réponse automatique activée par un membre de l'équipe. Les réponses automatiques leur permettent d'éviter d'avoir à répéter de nombreuses fois la même chose, ce qui leur fait gagner du temps et leur permet de s'occuper des sujets qui méritent plus d'attention.
      Nous sommes néanmoins ouverts et si vous avez une question ou une remarque, n'hésitez pas à contacter la personne en question par Message Privé.

      Pour plus d'informations, nous vous invitons à lire les règles générales du forum

      Manque de Politesse

      Votre message ne comporte pas ou peu de formules de politesse (« Bonjour », « Merci », « Au revoir », etc.). Les règles du site exigent que chaque nouveau message comporte un minimum de politesse. Après tout, les gens qui répondent le font gratuitement, sur leur temps libre. Ils méritent bien un minimum de considération, n'est-ce pas ?

      Mauvais titre

      Le titre est un élément important qui ne doit pas être négligé. N'oubliez pas cette règle simple : le titre idéal résume la question que vous allez poser en une petite phrase. Il doit permettre aux visiteurs de se repérer facilement dans le forum visité et d'identifier le sujet à sa seule lecture.

      Vous pouvez utiliser divers préfixes comme [Erreur], [MySQL], [Compatibilité], etc... Aussi, pensez à consulter les règles propres à chaque forum (visibles dans les topics épinglés en haut des sections).

      De plus, choisir un bon titre permet de rendre plus faciles les recherches des autres membres.

      Les titres de type "besoin d'aide" ou "problème" ne sont pas tolérés.

      Pour modifier votre titre, éditez le premier message de votre sujet.

      (problème code c++)

      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        17 juin 2018 à 1:06:53

        Il faut bien que tu crée le fichier contenant les mots

        Voici un exemple pour le mode solo :

        #include <cstdlib>
        #include <ctime>
        #include <fstream>
        #include <iostream>
        #include <string>
        #include <vector>
        
        using namespace std;
        
        string loadWordList()
        {
            ifstream fileReader = ifstream("wordlist.txt");
            
            if (fileReader)
            {
                string line;
                vector<string> wordList;
                
                while (getline(fileReader, line))
                    wordList.push_back(line);
                
                if (wordList.size() == 0)
                {
                    cout << "ERROR 2 : There are no words in the list" << endl;
                    exit(2);
                }
                
                return wordList[rand() % wordList.size()];
            }
            else
            {
                cout << "ERROR 1 : Unable to read the file !" << endl;
                exit(1);
            }
        }
        
        string transformWord(string word)
        {
            string transformWord;
            
            while (word.size() > 0)
            {
                int i = rand() % word.size();
                transformWord += word[i];
                word.erase(i, 1);
            }
            
            return transformWord;
        }
        
        int main()
        {
            cout << "Hello, welcome to THE MYSTERY WORD !" << endl << endl;
            
            srand((unsigned) time(NULL));
            
            string const word = loadWordList();
            string const transforWord = transformWord(word);
            
            cout << "Max answer : ";
            string maxAnswer_str;
            getline(cin, maxAnswer_str);
            int maxAnswer = atoi(maxAnswer_str.c_str());
            
            if (maxAnswer < 1)
                maxAnswer = 1;
            
            string answer;
            bool won = false;
            
            for (int i = 0; i < maxAnswer && !won; ++i)
            {
                cout << endl
                << maxAnswer - i << " hits remaining ..." << endl
                << "Tranform word : " << transforWord << endl
                << "Word : ";
                getline(cin, answer);
                
                if (answer == word)
                    won = true;
            }
            
            cout << endl;
            
            if (won)
                cout << "Congratulation !";
            else
                cout << "Oh no !";
            
            cout << endl << endl;
            
            return 0;
        }
        



        • Partager sur Facebook
        • Partager sur Twitter
          17 juin 2018 à 5:44:58

          Deux remarques préliminaires:

          La lecture d'un fichier est une opération particulièrement lente. Un accès mémoire se fait en un temps de l'ordre de quelques nanosecondes, un accès fichier dans un temps de l'ordre de quelques millisecondes. L'accès mémoire est environ 1 million de fois plus rapide que l'accès fichier. 

          Un dictionnaire de 32000 mots à raison de 10 lettres par mot en moyenne, va consommer par mot, 16 octets (le multiple de 8 le plus petit qui soit supérieur à 10), plus les données internes pour gérer la mémoire (l'équivalent d'environ 8 pointeurs, soit 64 octets en 64 bits). On arrive a 80 octets par mot. 32000*80 = 2 560 000 octets, c'est à dire pas grand chose sur nos ordinateurs modernes.

          Une petite règle de programmation(le premier principe de survie en fait ;) ): Le principe de responsabilité unique (SRP: Single Responsability Principle dans la littérature), que l'on pourrait traduire par "Je ne sais faire qu'une seule chose, mais je la fais bien". Plus une fonction fait de trucs, plus elle est difficile à coder, à tester et éventuellement à débugger. L'idéal est donc de se débrouiller pour faire des fonctions qui ne font qu'un seul truc, elle sont les plus faciles à coder, comme il n'y a qu'un seul truc à faire, il n'y a qu'un seul truc à tester donc c'est plus facile, et si malgré tout, il y a un bug, la fonction est courte et simple, donc le bug est plus facile à trouver et aussi plus facile à corriger. Conclusion: si on veut survivre dans un gros programme, il est absolument indispensable d'appliquer strictement le SRP. Ici, nous avons une fonction qui fait 2 trucs, elle lit un fichier et renvoie une ligne aléatoire. En vertu du SRP, une tâche = une fontion, donc on devrait avoir 2 fonctions: une fonction lit un dictionnaire situé dans un fichier, et une fonction qui choisit àléatoirement un mot dans un dictionnaire en mémoire. 

          En tenant compte de mes deux remarques préliminaires, on se rend compte qu'aller relire le fichier à chaque tirage est un énorme gaspillage, il est bien plus rentable de lire le fichier une seule fois au début du programme:

          std::vector<std::string> readFile(std::string const & fileName)
          {
              std::vector<std::string> result{};
              std::ifstream file{fileName};
              std::string line{};
              while(std::getline(file,line)){
                 result.push_back(line);
              }
              return result;
          }

          Pour le tirage du mots, on peut envisager deux approches:

          • tirer un nombre entre 0 et la taille du dictionnaire au sort, ce nombre sera la position du mot dans le dictionnaire.
          • mélanger le dictionnaire et prendre les mots l'un après l'autre. 

          Je ne vais pas détailler la première approche, elle est ultra classique. La seconde est plus subtile. Si je mélange le dictionnaire et que je prends les mots dans l'ordre, le mélange du dictionnaire m'assure que les mots appaîtront toujours dans un ordre différent d'une partie à une autre. Le fait de parcourir le dictionnaire va également m'assurer que chaque mot du dictionnaire ne sera proposé qu'une seule fois au cours de la partie.

          std::string selectWord(std::vector<std::string> & list)
          {
             assert(!list.empty() && "Le dictionnaire est vide!");
             std::string result = list.back();
             list.pop_back();
             return result;
          }
          
          void shuffle(std::vector<std::string> & list)
          {
             // initialiser un générateur aléatoire
             std::random_device rd{};
             std::mt19937 gen{rd()};
          
             // mélanger le tableau
             std::shuffle(std::begin(list),std::end(list),gen);
          }
          
          int main()
          {
             auto dico = readFile("dico.txt");
             shuffle(dico);
             while(!dico.empty()){
               auto w = selectWord(dico);
               // ...
             }
             return 0;
          }

          Ce code introduit une petite subtilité supplémentaire, plutôt que de garder en mémoire le nombre de mots présentés, je retire du dictionnaire le mot que je présente. Ainsi, j'évite d'avoir a maintenir le compteur de mots présentés, du fait que je ne le maintiens pas, je ne risque pas de me tromper dans le code qui maintient ce compteur, puisque ce code n'existe pas. Pour choisir mon mot, je sais, qu'il est plus facile de supprimer le dernier élément d'un tableau, qu'un élément situé à une position quelconque, donc je choisis toujours le dernier mot du dictionnaire.

          En exploitant à fond le SRP, j'obtiens un programme ultra modulaire, qui ne contient que des fonctions ultra simple à écrire, ultra simple à tester, ultra simple à debugger. Elle sont toujours ultra courtes(rarement plus d'une dizaine de lignes), n'utilisent que très peu de variables, les boucles sont toujours simple et courtes, les branchements aussi. A l'arrivée je maximise mes chances d'avoir un programme qui marche bien et que je vais facilement pouvoir faire évoluer. 

          -
          Edité par int21h 17 juin 2018 à 6:36:21

          • Partager sur Facebook
          • Partager sur Twitter
          Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
            17 juin 2018 à 10:33:01

            Merci beaucoup a vous deux, je vais pouvoir finir mon programme
            • Partager sur Facebook
            • Partager sur Twitter

            [ERREUR] fonctions qui marche mal

            × 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