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

 Java Discussion :

Problème de compilation


Sujet :

Java

  1. ###raw>post.musername###
    Membre à l'essai
    Problème de compilation
    Bonjour,

    J'étais très content d'un de mes programmes, mais il n'était pas optimisé. J'ai arrangé ça, mais il y a plusieurs bizarreries. voici le nouveau code.

    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    package vraiGrandMaitrePendu;
     
    import java.util.Random;
    import java.util.Scanner;
     
    class MortPenduLove {
     
    	public static void main(String[] args) {
     
    		Scanner keyboard = new Scanner(System.in);
    		Random myRandom = new Random();
     
    		char Devine;
    		String Solution = "SolutionTemp";
    		String verifie = "MadameChantilly";
    		int RandomNumber = 0;
    		int Gagnerez = 0;
    		int Perdrez = 0;
    		char[] tabCharSolution;
    		char [] tabCharDevine;
    		char [] pr = new char  [8];
    		String [] tabMotSolution = {"vraiment", "affreux", "pareil", "mannequin"}; // c'est un pendu, donc il y avait vraiment beaucoup de possibilités (environ 100), j'ai tout raccourci.
     
    		while(true) {
     
    			RandomNumber = myRandom.nextInt(tabMotSolution.length) - 1;
     
    			Solution = tabMotSolution [RandomNumber];
     
    			tabCharSolution = Solution.toCharArray();
     
    			tabCharDevine = new char [Solution.length()];
     
    			for(int i = 0; i < Solution.length(); i++) {
    				tabCharDevine [i] = '*';
    			}
    			for(int i = 0; i < pr.length; i++) {
    				pr[i] = ' ';
    			}
     
    			System.out.println("Bienvenue au Pendasio, jeu du pendu!");
    			System.out.println("Pensez-y : pour vous aider, tous les mots avec accents");
    			System.out.println("(graves, aigus, circonflexes... cédilles..) ont été supprimés!");
    			System.out.println("Tous les mots à trouver sont exclusivement en minuscule.");
     
    			while(!verifie.equals(Solution) && Perdrez < 8) {
     
    				System.out.println("Choisissez une lettre.");
     
    				Devine = keyboard.findWithinHorizon(".", 0).charAt(0);
     
    				for(int i = 0; i < Solution.length(); i++) {
    					if(Devine == tabCharSolution [i]) {
    						tabCharDevine[i] = Devine;
    						Gagnerez = 1;
    					}
    				}
    				if(Gagnerez == 0) {
    					Perdrez++;
    				}
    				switch(Perdrez){
     
    				case 1:
    					pr[1] = '|';
    					break;
    				case 2:
    					pr[2] = '0';
    					break;
    				case 3:
    					pr[3] = '/';
    					break;
    				case 4:
    					pr[4] = '|';
    					break;
    				case 5:
    					pr[5] = '\\';
    					break;
    				case 6:
    					pr[6] = '|';
    					break;
    				case 7:
    					pr[7] = '/';
    					break;
    				case 8:
    					pr[8] = '\\';
     
    				}
    				System.out.println(" ____________");
    				System.out.println("|           " + pr[1]);
    				System.out.println("|           " + pr[2]);
    				System.out.println("|          " + pr[3] + pr[4] + pr[5]);
    				System.out.println("|           " + pr[6]);
    				System.out.println("|          " + pr[7] +  " " + pr[8]);
    				System.out.println("|");
    				System.out.println("|_______________");
    				System.out.println(tabCharDevine);
     
    				Gagnerez = 0;
    				verifie = new String( tabCharDevine );
    			}
    			System.out.println();
    			if(Perdrez < 8) {
    				System.out.println("Héehéhé le chocolat, c'est bon pour patatra!");
    			} else {
    				System.out.println("Désolé... la réponse était : " + Solution + " Mais on recommence?");
    			}
    			System.out.println();
    			System.out.println();
    			Perdrez = 0;
     
    			for(int i = 0; i < pr.length; i++) {
    				pr[i] = ' ';
    			}
     
    		}
    	}
     
    }


    énumérations des bizarreries.

    - il souligne la déclaration de la classe MortPenduLove en rouge. c'est la première fois que ça m'arrive.

    - quand je force l'execution du code, tout fonctionne jusqu'à que je tape une lettre au clavier.
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 8 out of bounds for length 8
    at vraiGrandMaitrePendu/vraiGrandMaitrePendu.MortPenduLove.main(MortPenduLove.java:95)
    J'ai plusieurs suspects.
    voici la modification que j'ai fait pour optimiser le code :
    avant, pour afficher le nombre d'erreurs qu'a fait l'utilisateur (que j'ai illustré en construisant un bonhomme qui se construit petit à petit :
    |
    0
    /|\
    |
    / \ faites-vous une idée avec l'ancienne version de mon code sous format zip que j'ai joint à ce message.)
    je l'avais fait avec une structure switch qui prenait beaucoup de place. Je l'ai réduit en utilisant les tableaux.
    Entre deux parties je réinitialise les tableaux pr qui permettent de redessiner le bonhomme en fonction des erreurs,
    et j'ai peur qu'il y ait un problème avec la longueur du tableau... (simple supposition insignifiante)
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    for(int i = 0; i < pr.length; i++) {
    				pr[i] = ' ';
    			}


    - comme j'aime pouvoir faire des parties à l'infini sans relancer le programme, j'ai mis une boucle while(true) { ... }
    mais du coup comme j'ai importé un Scanner je ne peux pas le fermer à cause de la boucle infinie non?
    Si je ne ferme pas le Scanner, j'obtiens une notice keyboard is not closed.

    Merci de votre réponse.
      0  0

  2. ###raw>post.musername###
    Modérateur
    Salut,

    Citation Envoyé par Sticonik Voir le message

    faites-vous une idée avec l'ancienne version de mon code sous format zip que j'ai joint à ce message.)
    Sauf qu'il n'y a pas de code dans le zip. Pourquoi ne pas simplement mettre ce code entre balise [CODE] ? Éventuellement dans une balise [SPOILER].

    Citation Envoyé par Sticonik Voir le message

    - quand je force l'execution du code, tout fonctionne jusqu'à que je tape une lettre au clavier.
    Pour faire fonctionner un programme qui présente des erreurs, à la compilation, comme à la exécution, la première chose à faire est de regarder les erreurs. A défaut de savoir comment les corriger toi-même, indiques les dans tes prochaines questions.
    Dans ton cas, tu dois voir que s'affiche dans la console :
    java.lang.ArrayIndexOutOfBoundsException: Index 8 out of bounds for length 8
    Si tu regardes à la ligne de code où cette erreur se produit, tu vas voir :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    System.out.println("|          " + pr[7] +  " " + pr[8]);

    Il y a un accès à pr[8] alors que le tableau est déclaré comme ça char [] pr = new char [8];., donc pr[8] n'existe pas !

    Pour corriger le problème, il y a juste à faire char pr = new char [9];.

    Il y a ça à corriger également :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    RandomNumber = myRandom.nextInt(tabMotSolution.length) - 1;

    nextInt(n) tire un nombre entre 0 inclus et n exclu. Donc nextInt(n) - 1 tire un nombre entre -1 inclus et n-1 exclu.

    Si le nombre tiré est -1, alors Solution = tabMotSolution [RandomNumber]; va planter, avec une java.lang.ArrayIndexOutOfBoundsException, parce qu'un index doit être positif ou nul.
    Le dernier mot du tableau tabMotSolution, d'index 3, ne sera jamais choisi, parce que tabMotSolution.length vaut 4, exclu donc, donc le nombre le plus grand tirable par nextInt est 3, donc le plus grand tirable est 3-1, donc 2.

    Le -1 dans le code est inutile justement parce que nextInt exclut la borne supérieure.


    Citation Envoyé par Sticonik Voir le message


    - comme j'aime pouvoir faire des parties à l'infini sans relancer le programme, j'ai mis une boucle while(true) { ... }
    mais du coup comme j'ai importé un Scanner je ne peux pas le fermer à cause de la boucle infinie non?
    Si je ne ferme pas le Scanner, j'obtiens une notice keyboard is not closed.

    Tu as ce warning parce que Scanner est "Closeable" et que le compilateur ne sait que dire qu'il faut fermer une ressource Closeable qu'on a créée. Sauf qu'ici la ressource est créée à partir d'une autre ressource, System.in, que tu n'as pas créée toi-même, donc dont tu ne dois pas te soucier de la fermeture (le code qui les auras ouvertes le fera). Donc System.in, tu ne dois pas le fermer. Quant à Scanner, si on le ferme pas, au pire on risque d'avoir des caractères saisis au clavier qu'on aura pas traités. Et on s'en fout de ça, puisqu'on a traité tout ce qu'on voulait traiter...

    Tu peux supprimer le warning en ajoutant une annotation :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    @SuppressWarnings("resource")
    Scanner keyboard = new Scanner(System.in);

    Cela signifie que tu sais que ce n'est pas la peine de fermer le Scanner et donc tu indiques au compilateur qu'il ne doit pas s'en soucier.

    A noter que de toute manière la boucle étant infinie, on pourrait mettre un appel à keyboard.close() à la fin, ou utiliser un try-with-ressource, il y aurait peu de chances que la ressource se ferme.
    Ce serait pas mal de demander au joueur s'il a envie de rejouer pour éviter la boucle infinie. Enfin, tu le redemandes par "Mais on recommence?", mais tu ne lis pas de réponse à cette question au clavier...

    Citation Envoyé par Sticonik Voir le message


    je ne peux pas le fermer à cause de la boucle infinie non?

    Dans la boucle non, parce que tu ne pourrais plus lire des lettres tapées au clavier, mais en dehors de la boucle, à la fin, quand tu n'as besoin de lire des trucs au clavier, tu peux la fermer.

    Citation Envoyé par Sticonik Voir le message

    je l'avais fait avec une structure switch qui prenait beaucoup de place. Je l'ai réduit en utilisant les tableaux.
    Entre deux parties je réinitialise les tableaux pr qui permettent de redessiner le bonhomme en fonction des erreurs,
    Tu pourrais encore simplifier en faisant deux tableaux, un pour les caractères, un pour les positions des caractères, et un StringBuilder pour faire l'affichage.

    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
    // le dessin de la potence : il est juste important que les lignes qui affichent le pendu et celles avant soient de même longueur
    // on pourrait faire du code qui s'arrange pour mais ça se fait facilement à la main
    StringBuilder potence = new StringBuilder()
    				.append(" ____________  \n")
    				.append("|           | \n")
    				.append("|           0 \n")
    				.append("|          /|\\\n")
    				.append("|           | \n")
    				.append("|          / \\\n")
    				.append("|\n")
    				.append("|_______________");
     
     
    		// la position des caractères du pendu (ligne/position dans la ligne)
    		// pareil on peut faire un code pour le déterminer automatiquement, mais ça se fait aussi facilement à la main
    		int [][] positions = { {1,13}, {2,13}, {3,12}, {3,13}, {3,14}, {4,13}, {5,12}, {5,14}};
     
    		int maxl = 15; // la largeur de ligne
     
    		// on stocke les caractères du pendu...
    		char pr[] = new char[positions.length];
    		for(int i=0 ; i< positions.length; i++) {
    			pr[i]=potence.charAt( maxl*positions[i][0] + positions[i][1]);
    		}

    Avec les text blocks qui arrivent dans une prochaine version de Java, on pourrait faire encore plus simple pour la potence

    Ensuite, l'initialisation qui efface le pendu (ça remplace ta boucle sur pr pour le remplir d'espaces ):
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // remise à zéro de la potence
    for(int i=0 ; i< positions.length; i++) {
    	potence.setCharAt(maxl*positions[i][0] + positions[i][1], ' ');
    }


    Ensuite, on remplace le switch et les System.out.println qui affiche la potence par :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    potence.setCharAt(maxl*positions[Perdrez][0] + positions[Perdrez][1], pr[Perdrez]); // remplace le switch
    if(Gagnerez == 0) {
    	Perdrez++;
    }
    System.out.println(potence); // remplace tous les System.out.println
      0  0

  3. #3
    Membre à l'essai
    Salut,
    Je n'ai pas eu l'idée de faire de sauvegarde du code avant de le remodifier. Du coup, ce zip c'est tout ce qui me reste. Je te l'ai envoyé car j'ai trouvé mon expliquation un peu brouillon et tu pourrais l'executer pour voir à quoi ressemblait l'ancien pendu quand on y jouait. Tu pourrais alors voir le petit bonhomme qui commence à se construire.

    Merci beaucoup pour tes conseils, je me suis encore fait avoir: j'ai fait comme si la numérotation des tableaux partait de 1. Grave erreur! Ce qui explique ceci :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    char [] pr = new char [8]; 
    //et
    RandomNumber = myRandom.nextInt(tabMotSolution.length) - 1;


    Je vais faire comme tu m'as dit, je vais demander à l'utilisateur pour eelancer la partie. Mais ceci demandera encore une autre version de ce code. Cette fois, je ferai des sauvegardes

    Une autre fois je reprendrai la peine de lire mieux cette histoire de potence pour que ce soit encore plus clair pour moi.

  4. ###raw>post.musername###
    Membre à l'essai
    Salut,

    j'ai tout relu ton message dans les détails et remis tout ça dans un projet java tout neuf, sans risques.
    Il fonctionne très bien sauf à la fin, et à quelques détails près.

      Chaque fois que le programme dit : "Choisissez une lettre" et que j'en propose une, même juste, le bonhomme a un nouveau membre (comme si la lettre était fausse)

      à la fin d'une partie, il dit "Bravo! Super partie.", alors même que j'ai perdu la partie. Je sais alors que la condition
      Code :Sélectionner tout -Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      if(Perdrez < pr.length) {
      System.out.println("Bravo! Super partie.");
      } else {
      System.out.println("Désolé... la réponse était : " + Solution + " Mais on recommence?");
      }
      est true (bizzare)

      J'illustre ceci : avant la condition, on voit que
      pr.lenth = 8
      et que
      Perdrez = 0
      Code :Sélectionner tout -Visualiser dans une fenêtre à part
      1
      2
      System.out.println("La longueur du tableau pr est : " + pr.length);
      System.out.println("Perdrez est égal à : " + Perdrez);
      ... on sais maintenant pourquoi la condition est vraie, mais pourquoi Perdrez = 0?

    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    package mortRessussitePendu;
     
    import java.util.Scanner;
    import java.util.Random;
     
    public class PenduTroisième {
     
    	public static void main(String []args) {
     
    			Scanner keyboard = new Scanner(System.in);
    	        Random myRandom = new Random();
     
    	        char Devine;
    	        String Solution = "SolutionTemp";
    	        String verifie = "MadameChantilly";
    	        int RandomNumber = 0;
    	        int Gagnerez = 0;
    	        int Perdrez = 0;
    	        String repondez = "oui";
    	        int maxl = 15;
    	        char[] tabCharSolution;
    	        char [] tabCharDevine;
    	        String [] tabMotSolution = {"vraiment", "affreux", "pareil", "mannequin", "vaguement"};
    	        int [][] positions = { {1,13}, {2,13}, {3,12}, {3,13}, {3,14}, {4,13}, {5,12}, {5,14}};
     
    	        StringBuilder potence = new StringBuilder()
    	                .append(" ____________  \n")
    	                .append("|           | \n")
    	                .append("|           0 \n")
    	                .append("|          /|\\\n")
    	                .append("|           | \n")
    	                .append("|          / \\\n")
    	                .append("|\n")
    	                .append("|_______________");
     
    	        char pr[] = new char[positions.length];
    	        for(int i = 0 ; i< positions.length; i++) {
    	                pr[i]=potence.charAt( maxl*positions[i][0] + positions[i][1]);
    	        }       
    	        	while(true) {
     
    	        		for(int i = 0 ; i< positions.length; i++) {
    	                	potence.setCharAt(maxl*positions[i][0] + positions[i][1], ' ');
    	                }
     
    	        		RandomNumber = myRandom.nextInt(tabMotSolution.length);
    	        		Solution = tabMotSolution [RandomNumber];
    	        		tabCharSolution = Solution.toCharArray();
    	        		tabCharDevine = new char [Solution.length()];
     
    	        		for(int i = 0; i < Solution.length(); i++) {
    	        			tabCharDevine [i] = '*';
    	       			}
     
    	        		System.out.println("Bienvenue au Pendasio, jeu du pendu!");
    	    			System.out.println("Pensez-y : pour vous aider, tous les mots avec accents");
    	    			System.out.println("(graves, aigus, circonflexes... cédilles..) ont été supprimés!");
    	    			System.out.println("Tous les mots à trouver sont exclusivement en minuscule et au singulier.");
     
    	    			while(!verifie.equals(Solution) && Perdrez < pr.length) {
    	    				System.out.println("Choisissez une lettre.");
     
    	    				Devine = keyboard.findWithinHorizon(".", 0).charAt(0);
     
    	    				for(int i = 0; i < Solution.length(); i++) {
    	    					if(Devine == tabCharSolution [i]) {
    	    						tabCharDevine[i] = Devine;
    	    						Gagnerez = 1;// Est-ce la source du problème?
    	    					}
    	    				}
     
    	    				potence.setCharAt(maxl*positions[Perdrez][0] + positions[Perdrez][1], pr[Perdrez]);
    	    				/*
    	    				 * Je n'ai pas compris ceci dans la ligne précédente(je pense avoir compris le reste): [perdrez][0] et [perdrez][1]
    	    				 * (j'ai compris à quoi sert perdrez, mais je ne comprend pas où interviennent ces "0" et "1") (j'espère avoir été clair)
    	    				 */
    	    				if(Gagnerez == 0) {
    	    					Perdrez++;
    	    				}
    	    				System.out.println(potence);
    	    				System.out.println(tabCharDevine);
    	    				Gagnerez = 0;
    	    				verifie = new String( tabCharDevine );
    	    			}
    //	    			grave problème. l'utilisateur a toujours gagné, même en perdant! Une erreur avec la variable Perdrez ? ligne 69
     
    	    			Perdrez = 0;
    	    			System.out.println();
    	    			System.out.println("La longueur du tableau pr est : " + pr.length);
    	    			System.out.println("Perdrez est égal à : " + Perdrez);
    	    			if(Perdrez < pr.length) {
    	    				System.out.println("Bravo! Super partie.");
    	    			} else {
    	    				System.out.println("Désolé... la réponse était : " + Solution + " Mais on recommence?");
    	    			}
    	    			keyboard.nextLine();
    	    			System.out.println("pour recommencer, appuiyer sur enter. pour quitter, appuiyer sur la touche N (majuscule/minuscule)");
     
    	    			repondez = keyboard.nextLine();
     
    	    			if(repondez.equals("n") || repondez.equals("N")) {
    	    				break;
    	    			}
    	    			System.out.println();
    	        	}
     
    	        	System.out.println("Merci d'avoir joué au pendu!");
    	        	keyboard.close();
     
    	    }
    }
      0  0

  5. #5
    Modérateur

    Salut,


    Citation Envoyé par Sticonik Voir le message
    [...], mais pourquoi Perdrez = 0?
    Parce qu'au début de cette séquence, qui s'exécute juste après qu'on sorte du while, on affecte 0 à Perdrez, qui vaut donc 0 :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Perdrez = 0;
    System.out.println();
    System.out.println("La longueur du tableau pr est : " + pr.length);
    System.out.println("Perdrez est égal à : " + Perdrez);


    Tu dois effectivement réinitialiser Perdrez lorsqu'on recommence un "jeu", mais c'est après avoir traité tout le jeu d'avant qu'il faut le faire, donc après en avoir afficher les résultats... surtout que la valeur Perdrez est utilisée dans cet affichage de résultat :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if([highlight]Perdrez[/highlight] < pr.length) {
    	System.out.println("Bravo! Super partie.");
    } else {
    	System.out.println("Désolé... la réponse était : " + Solution + " Mais on recommence?");
    }

    Puisque perdrez vaut toujours 0 avant ce test, et que pr.length>0, on affiche toujours "Bravo! Super partie.", même quand on a perdu.

    Citation Envoyé par Sticonik Voir le message

    Chaque fois que le programme dit : "Choisissez une lettre" et que j'en propose une, même juste, le bonhomme a un nouveau membre (comme si la lettre était fausse)
    Déjà, si tu commençais par utiliser des booléens plutôt que des int de valeur 0 ou 1 pour signifier false ou true, l'algorithme/programme serait plus lisible/compréhensible.

    Dans cette boucle
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for(int i = 0; i < Solution.length(); i++) {
        if(Devine == tabCharSolution [i]) {
            tabCharDevine[i] = Devine;
            Gagnerez = true; // true au lieu de 1, pour vrai, 
        }
    }

    on parcourt les lettres du mot à chercher, et si on trouve qu'un lettre de tabDolution est égale à la lettre saisie alors on dit que Gagnerez est vrai.

    Au passage, pourquoi Solution.length() et tabCharSolution[i] ? Sois cohérent ! Si tu parcours tabCharSoluton, utilise tabCharSolution.length comme borne, même si en l'occurrence tabSolution a été construit à partir de Solution, et que ça fonctionne donc effectivement. La cohérence participe également à la lisibilité, à moins se prendre la tête pour comprendre ce que fait le programme.

    Puis tu fais :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    potence.setCharAt(maxl*positions[Perdrez][0] + positions[Perdrez][1], pr[Perdrez]);
    if(!Gagnerez) { // enfin, tu faisais Gagnerez==0, que j'ai remplacé par un test de booléen, "si pas gagné", alors "perdu", donc
        Perdrez++; // on avance vers la pendaison complète
    }

    Au passage, je réponds à ta question en commentaire dans ce bout de code...


    Je n'ai pas compris ceci dans la ligne précédente(je pense avoir compris le reste): [perdrez][0] et [perdrez][1]
    (j'ai compris à quoi sert perdrez, mais je ne comprend pas où interviennent ces "0" et "1") (j'espère avoir été clair)
    int [][] positions est un tableau de positions. Chaque position est représentée par un tableau de deux int : le premier est un numéro de ligne et le second une position de caractère dans la ligne.
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    int [][] positions = { {1,13}, {2,13}, {3,12}, {3,13}, {3,14}, {4,13}, {5,12}, {5,14}};

    On déclare ici la liste de toutes les positions des "segments" du pendu dans l'ordre d'affichage : 1,13 : le premier segment (la corde au dessus de la tête) est en ligne 1, 13ème caractère. positions est un tableau à 2 dimensions de int.
    Un tableau à deux dimensions, c'est un tableau de tableaux.

    La variable potence est un StringBuilder, une sorte de chaîne dynamique (on peut ajouter, supprimer, et modifier des caractères, ce qu'on ne peut pas faire avec String).

    Dans la ligne :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    potence.setCharAt(maxl*positions[Perdrez][0] + positions[Perdrez][1], pr[Perdrez]);


    On modifie le caractère de potence situé à une position qu'on calcule avec la formule : maxl*positions[Perdrez][0] + positions[Perdrez][1].
    maxl est la taille d'une ligne (on s'est arrangé pour que toutes les lignes contenant des caractères du pendu soient de même longueur, maxl donc),
    Perdrez est le numéro d'étape vers la pendaison complète
    positions est donc la suite des différentes positions du pendu, dans un ordre correspondant à Perdrez qui s'incrémente à chaque étape (positions[0] c'est la position pour la première étape, positions[1] c'est la position pour la deuxième étape, positions[Perdrez] la position pour l'étape correspondant à Perdrez.
    pr[Perdrez] c'est le caractère à mettre à la position correspondant à l'étape.

    Rappel : une position pour un étape, c'est un tableau de 2 int, un premier pour la ligne, un second pour le caractère dans la ligne. Donc positions[Perdrez][0], c'est la cellule 0 dans le tableau positions[Perdrez], donc la première, soit le numéro de ligne, et positions[Perdrez][1] c'est la cellule 1 dans le tableau positions[Perdrez], donc la seconde, soit la position du caractère dans la ligne.
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    int [][] positions = { {1,13}, {2,13}, {3,12}, {3,13}, {3,14}, {4,13}, {5,12}, {5,14}};

    Quand Perdrez vaut 0, positions[Perdrez][0] c'est 1 et positions[Perdrez][1] c'est 13.
    Quand Perdrez vaut 1, positions[Perdrez][0] c'est 2 et positions[Perdrez][1] c'est 13.
    Quand Perdrez vaut 2, positions[Perdrez][0] c'est 3 et positions[Perdrez][1] c'est 12.
    Etc.
    On retrouve la position dans potence par la formule longueur de ligne multipliée par numéro de ligne plus numéro de caractère dans la ligne.
    La fameuse formule : maxl*positions[Perdrez][0] + positions[Perdrez][1]


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    potence.setCharAt(maxl*positions[Perdrez][0] + positions[Perdrez][1], pr[Perdrez]);

    Code que tu exécutes à chaque tour de boucle qu'on gagne ou qu'on perde... d'où la progression du pendu d'une étape au moins si on a perdu le coup précédent...

    Puisqu'on perd quand on ne gagne pas et qu'on progresse vers la pendaison seulement si on perd, il faut faire :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if(!Gagnerez) { // si pas gagné, alors on progresse vers la pendaison complète
        potence.setCharAt(maxl*positions[Perdrez][0] + positions[Perdrez][1], pr[Perdrez]);
        Perdrez++;
    }


    Ensuite la boucle de jeu est :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    while(!verifie.equals(Solution) && Perdrez < pr.length) { 
    }

    En clair : tant que ( le mot trouvé n'est pas égal à la solution et qu'on a pas atteint l'étape ultime de la pendaison complète, on continue de jouer.
    Il serait plus logique de faire un do/while plutôt qu'un while, puisqu'on joue d'abord puis on teste si on a gagné ou pas... mais bon ça fonctionne avec un while, puisque tu t'arranges pour que verifie soit initialisée (avec une valeur à la c... mais avec une valeur forcément différente d'un mot qu'on peut trouver) avant. Avec un do/while, tu n'aurais même pas besoin de l'initialiser, donc pas de valeur bidon à la "MadameChantilly" !!!

    Autre chose :
    Voici le code qui te sert à afficher si on a perdu ou gagné...
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if(Perdrez < pr.length) {
        System.out.println("Bravo! Super partie.");
    } else {
        System.out.println("Désolé... la réponse était : " + Solution + " Mais on recommence?");
    }

    Si, au lieu de chercher à déduire de la progression vers la pendaison complète si on a gagné ou pas, tu testais la condition logique qui détermine qu'on a gagné, tu aurais plus de chances d'avoir un résultat juste :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if( verifie.equals(Solution) ) { // le mot trouvé est égal au mot à chercher
        System.out.println("Bravo! Super partie.");
    } else {
        System.out.println("Désolé... la réponse était : " + Solution + " Mais on recommence?");
    }

    Ceci fait que le message de succès/échec ne dépend pas de la progression de la pendaison mais uniquement du fait qu'on ait ou pas trouvé la solution.

    De manière générale, on évite tout solution contournée, alambiquée, indirecte, pour ne pas dire tordue pour évaluer une condition, pour éviter de se faire de nœuds au cerveau pour comprendre pourquoi ça ne fonctionne pas. Après au besoin, pour des raisons d'optimisations, on peut chercher des moyens plus efficaces, mais ici ça ne sert à rien du tout.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Membre à l'essai
    Salut,

    mon programme est terminé. voici les deux seuls problèmes empêchant l'execution (que tu as déjà indiqué).
      changer ceci (ancien à nouveau code)
      Code :Sélectionner tout -Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      //ancien
      potence.setCharAt(maxl*positions[Perdrez][0] + positions[Perdrez][1], pr[Perdrez]);
       
      //nouveau
      if(Gagnerez == false) {
      potence.setCharAt(maxl*positions[Perdrez][0] + positions[Perdrez][1], pr[Perdrez]);
      Perdrez++;
      }


      réinitialiser perdrez après l'annonce victoire / défaite dépendant de perdrez

    Merci beaucoup!

  7. #7
    Modérateur

    Salut,
    Citation Envoyé par Sticonik Voir le message

    mon programme est terminé. voici les deux seuls problèmes empêchant l'execution (que tu as déjà indiqué).
    Je ne comprends pas. Tu as encore des problèmes ?

    Citation Envoyé par Sticonik Voir le message

    changer ceci (ancien à nouveau code)
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //ancien
    potence.setCharAt(maxl*positions[Perdrez][0] + positions[Perdrez][1], pr[Perdrez]);
     
    //nouveau
    if(Gagnerez == false) {
    potence.setCharAt(maxl*positions[Perdrez][0] + positions[Perdrez][1], pr[Perdrez]);
    Perdrez++;
    }

    C'est ça le problème ? Tu as bien supprimé le code "//ancien", je veux dire la ligne de code juste après ce commentaire, évidemment ?

    Citation Envoyé par Sticonik Voir le message

    réinitialiser perdrez après l'annonce victoire / défaite dépendant de perdrez
    Oui...

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if(Perdrez < pr.length) {
    	System.out.println("Bravo! Super partie.");
    } else {
    	System.out.println("Désolé... la réponse était : " + Solution + " Mais on recommence?");
    }
    Perdrez = 0;

    On remet Perdrez à 0 après qu'on ait traité (testé) cette variable.

    Ou
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Perdrez = 0;
    if(verifie.equals(Solution)) {
    	System.out.println("Bravo! Super partie.");
    } else {
    	System.out.println("Désolé... la réponse était : " + Solution + " Mais on recommence?");
    }

    On peut le faire avant ou après, on s'en fout, puisqu'on ne l'utilise pas dans le test.
    Ah, aussi, il faudrait réinitialiser verifie aussi (après le if/else du coup) : sinon, si par malchance on retire le même mot à trouver, verifie sera déjà la bonne solution, et on entrera pas dans le while. En réalité, pour éviter d'avoir à se compliquer la vie avec ça, si verifie était définie et donc initialisée dans le scope utile, il n'y aurait pas besoin de le réinitialiser avant de reboucle. Je veux dire définir cette variable dans le while(true). De manière générale, il est toujours préférable de définir toute variable au plus près de son scope d'usage. Définir toutes les variables au début est une salle habitude issue de vieux langages qui n'a pas de raison d'être appliquée en Java, bien au contraire.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.