Algorithme "Appels de méthodes"

Fermé
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017 - 13 févr. 2017 à 18:26
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 16 févr. 2017 à 07:02
Bonjour, voilà j'ai fait un petit programme qui propose 10 exercices de multiplications , la première étant une multiplication "Difficile" si l'utilisateur répond bien il a 2 point sinon le programme lui proposera de faire un exercice simple si l'utilisateur répond bien il obtiendra 1 point dans le cas contraire il en perds 2 à la fin du programme le score total que l'utilisateur a eu est affiché :

Voici mon code:
 
import java.util.Scanner;
public class MultiDificil{
  public static Scanner scanner = new Scanner(System.in);
  public static void main(String[]args){
   String multipli = ""; 
   int score = 0; 
   int point = 0;
  for(int i = 1; i <= 10; i++){
    System.out.println("Multiplication Difficile ");   
     int premierNombre , secondNombre, reponseCorrecte, reponseEleve;
     premierNombre =  unEntierAuHasardEntre(5,10);
     secondNombre =  unEntierAuHasardEntre(11,19);
     System.out.println("Calculer : " + premierNombre + " x " + secondNombre + " = " );
     reponseCorrecte = premierNombre * secondNombre;  
     reponseEleve = scanner.nextInt();
     
       if(reponseEleve == reponseCorrecte){
          multipli = "Difficile";
          point = score(premierNombre,secondNombre,reponseCorrecte,reponseEleve , multipli);
          score = score + point;
          System.out.println("Très bien vous gagnez : " + point + " point");
       }
       else{
        multipli = "Facile";
        System.out.println("Non C'etait : " + reponseCorrecte + " Voici une Multiplication facile");
         premierNombre = unEntierAuHasardEntre(1,6);
         secondNombre = unEntierAuHasardEntre(3,10);
         reponseCorrecte = premierNombre * secondNombre;
         System.out.println("Calculer : " + premierNombre + " x " + secondNombre + " = " );
         reponseEleve = scanner.nextInt();
         if(reponseEleve == reponseCorrecte){        
           point = score(premierNombre,secondNombre,reponseCorrecte,reponseEleve , multipli);
           score = score + point;
           System.out.println("Bien vous gagnez : " + point + " point");
         }
         else{
           point = score(premierNombre,secondNombre,reponseCorrecte,reponseEleve , multipli);
           score = score + point;
           System.out.println("Non C'était : " + reponseCorrecte + " Vous perdez : " + point + " points");
         }
       }
     } 
     System.out.println("Voici votre score : " + score);
    } 
  
 
 
 public static int score(int premierNombre , int secondNombre , int reponseCorrecte , int reponseEleve , String multipli){
  
   if(reponseCorrecte == reponseEleve && multipli == "Difficile" ){
     return 2;  
  }
  
  else{
     if(reponseCorrecte == reponseEleve && multipli == "Facile"){
       return 1;
     }
     
     return -2;
   }
 }

 public static int unEntierAuHasardEntre (int valeurMinimale, int valeurMaximale){
		double nombreReel;
		int resultat;

		nombreReel = Math.random();
		resultat = (int) (nombreReel * (valeurMaximale - valeurMinimale + 1))
								+ valeurMinimale;
		return resultat;
  }
 }


Cependant je ne suis pas du tout satisfait de mon code , je l'ai fait de façon à évité de mauvaises habitudes que j'ai tels que mélangés (les scanner.next et les System) dans une méthode ... Je voudrais donc savoirs qlqn peut m'aider a amélioré mon code de façon à ce qu'il soit plus lisible et concis Merci d'avance :)

1 réponse

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
13 févr. 2017 à 20:19
Bonjour,

Pour que ton code soit plus lisible il faut sortir toutes les "valeurs magiques" qui sont liées à tes niveaux (5, 10, 11, 19, +2, +1, -2...)

Je pense que la bonne idée est d'utiliser un enum où chaque valeur représente un niveau. Pour l'instant il n'y a que FACILE et DIFFICILE, mais si tu veux rajouter 1, 2 ou 15 niveaux intermédiaires avec ton code c'est impossible alors qu'avec un enum il suffirait de rajouter une valeur.

import java.util.Random;
import java.util.Scanner;

public class MultiDificil {

    private static final Random random = new Random();
    private static final Scanner scanner = new Scanner(System.in);

    public static int unEntierAuHasardEntre(int valeurMinimale, int valeurMaximale) {
        return random.nextInt(valeurMaximale - valeurMinimale + 1) + valeurMinimale;
    }

    public enum Niveau {
        FACILE(1, 6, 3, 10, 1, 2), DIFFICILE(5, 10, 11, 19, 2, 2);

        private final int minA, maxA, minB, maxB, scoreOk, scoreKo;

        Niveau(int minA, int maxA, int minB, int maxB, int scoreOk, int scoreKo) {
            this.minA = minA;
            this.maxA = maxA;
            this.minB = minB;
            this.maxB = maxB;
            this.scoreOk = scoreOk;
            this.scoreKo = scoreKo;
        }

        public int getPremierNombreAuHasard() {
            return unEntierAuHasardEntre(minA, maxA);
        }

        public int getSecondNombreAuHasard() {
            return unEntierAuHasardEntre(minB, maxB);
        }

        public int getNbPointsSucces() {
            return scoreOk;
        }

        public int getNbPointsEchec() {
            return scoreKo;
        }

        public Niveau suivant(int delta) {
            int pos = ordinal() + delta;
            if (pos < 0) {
                pos = 0;
            } else {
                int len = Niveau.values().length;
                if (pos >= len)
                    pos = len - 1;
            }
            return Niveau.values()[pos];
        }
    }

    public static int saisirResultat(Niveau niveau, int premierNombre, int secondNombre) {
        System.out.println("MULTIPLICATION " + niveau);
        System.out.print(premierNombre + " x " + secondNombre + " = ");
        return scanner.nextInt();
    }

    public static void afficherScore(boolean succes, int reponse, int point, int score) {
        if (succes) {
            System.out.print("Très bien. Vous gagnez ");
        } else {
            System.out.print("Non, c'était " + reponse + ". Vous perdez ");
        }
        System.out.println(point + " points. Votre score est de " + score + ".");
    }

    public static void main(String[] args) {
        Niveau niveau = Niveau.DIFFICILE;
        int score = 0;

        for (int i = 1; i <= 10; i++) {
            int premierNombre = niveau.getPremierNombreAuHasard();
            int secondNombre = niveau.getSecondNombreAuHasard();
            int reponseEleve = saisirResultat(niveau, premierNombre, secondNombre);
            int reponseCorrecte = premierNombre * secondNombre;
            boolean succes = reponseEleve == reponseCorrecte;

            int point;
            if (succes) {
                point = niveau.getNbPointsSucces();
                score += point;
                niveau = niveau.suivant(+1);
            } else {
                point = niveau.getNbPointsEchec();
                score -= point;
                niveau = niveau.suivant(-1);
            }

            afficherScore(succes, reponseCorrecte, point, score);
        }
    }
}

Je t'invites à ajouter des niveaux intermédiaires, avec par exemple :

public enum Niveau {
    FACILE(1, 6, 3, 10, 1, 2),
    NORMALE(3, 5, 2, 8, 1, 2),
    DIFFICILE(5, 10, 11, 19, 2, 2);
0
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017
14 févr. 2017 à 02:41
Merci !! Oui je n'avait pas connaissance du Enum , j'vois à peut a quoi sa sert mais sa reste tout de même encore un peut flou , Est ce que Donc dans ce cas là on peut en conclure que "Niveau" est un Objet ? qui peut prendre plusieurs valeurs (FACILE, NORMAL , DIFFICLE) Qui sont des sous Objets ? Et Par contre je ne comprends pas du tout l'algorithme qui vous permet de passé d'un niveaux a un autre je ne vois pas l’intérêt en fait je pensais le faire autrement mais je ne sais si c'est bon :/


 public Niveau suivant(int delta) {
            int pos = ordinal() + delta;
            if (pos < 0) {
                pos = 0;
            } else {
                int len = Niveau.values().length;
                if (pos >= len)
                    pos = len - 1;
            }
            return Niveau.values()[pos];
        }


je veut dire puisque on sait que l'utilisateur commencera un exercice "Difficile" dans le cas où il échoue pourquoi ne pas Mettre Niveau.DIFFICLE à Niveau.FACILE , En gros Changer La valeur de L'objet Niveau ?

if (succes) {
                point = niveau.getNbPointsSucces();
                score += point;
                niveau = niveau.suivant(+1);
            } else {
                 Niveau niveau = Niveau.FACILE;
                point = niveau.getNbPointsEchec();
                score -= point;
                niveau = niveau.suivant(-1);
            }
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
14 févr. 2017 à 19:38
"on peut en conclure que "Niveau" est un Objet ? qui peut prendre plusieurs valeurs (FACILE, NORMAL , DIFFICLE) Qui sont des sous Objets ?"
Niveau n'est pas un objet, mais une classe, qui étends java.lang.Enum
FACILE, NORMAL et DIFFICILE sont des objets de la classe Niveau, et particularité de l'enum, ce sont les seuls objets qui puisse exister.

"dans le cas où il échoue pourquoi ne pas Mettre Niveau.DIFFICLE à Niveau.FACILE"
Ça fonctionnerait si on se limitait à FACILE et DIFFICILE, mais avec NORMAL entre les deux ça ne fonctionne plus.

Lorsque l'on déclare un enum, l'ordre a un sens. La méthode Niveau.values() renvoie un tableau Niveau[] avec chaque niveau dans l'ordre où il a été déclaré.
C'est à dire que Niveau.values() vaut { FACILE, NORMAL, DIFFICILE };
On a donc FACILE.ordinal() == 0, NORMAL.ordinal() == 1, DIFFICILE.ordinal() == 2.

La méthode suivant(delta) permet de passer d'un niveau à un autre (avec +1 ou -1) de sorte que NORMAL.suivant(+1) == DIFFICILE et NORMAL.suivant(-1) == FACILE.
Ce qui marche aussi quand tu n'as que FACILE et DIFFICILE.

Si on détaille :

public Niveau suivant(int delta) {
    Niveau[] tab = Niveau.values(); // la liste des niveaux
    int ord = this.ordinal(); // la position dans le tableau du niveau actuel
    int pos = ord + delta; // la position dans le tableau du niveau suivant

    // gestion des cas particuliers où pos<0 ou pos>=tab.length

    return tab[pos]; // le niveau suivant
}

Dans les cas particuliers on gère les cas FACILE.suivant(-1) == FACILE et DIFFICILE.suivant(+1) == DIFFICILE, sinon on dépasserait la taille du tableau.
0
Jiko-java Messages postés 186 Date d'inscription dimanche 25 septembre 2016 Statut Membre Dernière intervention 22 juillet 2017
16 févr. 2017 à 06:00
Ahh d'accord je vois un peut plus clair merci mais quelque chose m'intrigue d'avantage comment sa se fait que vous avez pas créée de tableaux a la base mais que vous avez quand mémé réussi a appelé length

 
int len = Niveau.values().length;


Est ce que La Classe enum posède dejà un tableaux ou quelque chose de ce genre ?
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
16 févr. 2017 à 07:02
En effet, c'est ce que j'ai indiqué précédemment, la particularité de l'enum, c'est que les seuls objets qui puissent exister sont ceux que l'on déclare dans le code, que l'ordre de cette déclaration a un sens et que la méthode values() renvoie un tableau avec chaque valeur de l'enum dans l'ordre où il a été déclaré.
0