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

Langage Java Discussion :

Cartes à trier et mélanger qui ne fonctionne pas


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Retraité
    Inscrit en
    Août 2013
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 52
    Par défaut Cartes à trier et mélanger qui ne fonctionne pas
    Salut à tous
    Un petit coup de main serait le bienvenue.

    Dans mon programme, j'ai 52 cartes photos à afficher dans une grille aléatoirement.
    Ce sont toutes des paires (donc 26 X 2) qui ne doivent pas se répéter
    Je dois choisir les photos dans une liste de 100 photos.

    J'ai besoin d'une algorithme qui fonctionne mieux que la mienne (la mienne affiche 3 ou 4 photos pareilles dans les 52.. Affiche 2 photos pareilles dans les 26 premières ou 26 suivantes.) etc.

    La création et l'assignation de la liste se fait très bien. J'affiche 52 photos ... mais pas comme je le désire...

    Je dois choisir aléatoirement 26 photos dans une banque de 100 photos. Ensuite je les double et je dois remélanger les 52 cartes pour les afficher dans la grille.

    J'ai une méthode Initialise qui créé une liste de 100 cartes:

    J'ai une méthode AuHazard(0, max) qui me retourne un nombre aléatoire: Le problème est qu'il arrive qu'il me retourne encore une carte déjà choisie...

    J'ai une méthode qui MélangeLesCartes: Toute croche...

    J'ai une méthode qui les affiche... Affichage OK mais j'ai plus que des paires

    Je suis comme un peu perdu.
    Merci pour le coup de main.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    sans description précise de tes algorithmes ou de code, difficile de t'indiquer les corrections à y faire.

    Quelques pistes toutefois :

    - pour tirer 26 cartes dans une liste de 100, tu pourrais mettre tes 100 cartes dans une liste (java.util.ArrayList), utiliser java.util.Collections.shuffle(List) pour les mélanger, et prendre les 26 premières
    - autre solution, ranger tes 26 cartes tirées aléatoirement dans une Lis (ou un Set)t au fur et à mesure du tirage ; à chaque tirage aléatoire d'une carte, tu recommences le tirage tant que celle-ci est déjà dans cette List (ou Set).

    Maintenant tu as une liste de 26 cartes aléatoires parmi 100, uniques, dans un ordre quelconque. Donc 26 paires, de fait.

    Pour le placement des 26 paires dans ta grille, ta description est moins claire : est ce que tu cherches à faire un jeu du type jeu de mémoire ou le joueur voit des cartes retournées, clique sur une carte, et doit trouver l'autre carte identique pour éliminer la paire de cartes, et ainsi de suite ?
    En gros, comment tes cartes doivent être réparties dans la grille ?
    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.

  3. #3
    Membre averti
    Homme Profil pro
    Retraité
    Inscrit en
    Août 2013
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 52
    Par défaut
    Je ne connais pas encore les ArryList. Je ne suis pas encore rendu là dans Java.
    Oui, j'essai de faire un petit jeu en mettant les photos des employés qui travaillent dans mon centre.
    La grille affiche 52 cartes et ça les retourne si la 2e choisie n'est pas la même. Si elles sont pareilles, elles restent affichées.
    Voici mon code que j'ai fait pour les tris;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	private int auHasardEntre(int minimum, int maximum){
            	double t=Math.random();
            	int resultat = (int) ((maximum-minimum)*t + minimum);
            	return resultat;
    Cela est bien mais affiche régulièrement des doubles malheureusement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        private void initialiseCartes(){
             listeCartes = new Carte [nombreDePhotos];  //Assigne au complet toutes les photos
             // Répéter autant de fois qu'il y a de carte
             for (int i=0; i < nombreDePhotos; i++){
                 listeCartes[i] = new Carte("../Photos/carte"+i+".png", "../Photos/dos.png", i, "Prénom"+i, "Nom"+i, "Département"+i, "Fonction"+i);
             }
              melangerCartes();
        }
    Si je ne fais pas de tris, cela s'affiche très bien de 0 à NombreDePhotos
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        private void melangerCartes(){
            int aleatoire;
            Carte temporaire;
            //Choisis 26 cartes parmis tous les contacts
            for(int i=0; i<nombreDeCartes/2; i++){  
              // Tirer un nombre au hasard entre 0 et le nombre de contacts
                aleatoire = auHasardEntre(0, listeCartes.length);   
                System.out.println(i+" Aléatoire "+aleatoire);
              // Echanger la carte d'indice i avec celle tirée au hasard
              temporaire = listeCartes[i];
              listeCartes[i] = listeCartes[aleatoire];
              listeCartes[aleatoire] = temporaire;
            }
    J'aimerais bien suivre ton cheminement

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Voici l'équivalent en List :

    Au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private Carte[] listeCartes;
    tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private List<Carte> listeCartes;
    puis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    private void initialiseCartes(){
        //Assigne au complet toutes les photos
        listeCartes = new ArrayList<Carte>();
        // Répéter autant de fois qu'il y a de carte
        for (int i=0; i < nombreDePhotos; i++){
            listeCartes.add( new Carte("../Photos/carte"+i+".png", "../Photos/dos.png", i, "Prénom"+i, "Nom"+i, "Département"+i, "Fonction"+i)); 
        }
        melangerCartes();
    }
    puis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    private void melangerCartes(){
        Collections.shuffle(listeCartes);
    }
    Pour prendre les 26 premières :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    isteCartes.subList(0,25);


    Avec un tirage aléatoire par Random, c'est que tu ne peux pas garantir de ne pas tirer 2 fois le même nombre, même dans un tirage limité (chaque valeur tirée n'est pas supprimée tant qu'on a pas tirée toutes les autres, il y a juste garantie d'équiprobabilité)

    Au sujet de ta méthode qui permutes :

    tu fais 26 fois
    - tirer 1 nombre de 0 et 99 (inclus)
    - permuter la carte correspond à l'index courant (un nombre de 0 à 25 inclus donc)
    avec une carte d'index aléatoire entre 0 et 99 (inclus), donc compris entre 0 et 25 (inclus) éventuellement, voire même avec de très faibles probabilités certes, l'index courant

    donc c'est très difficile de garantir un mélange homogène.

    avec la règle d'équiprobabilité tu as juste (un peu près) 3 fois moins de chances de tirer une cartes entre 0 et 25 et entre 26 et 99, mais tu peux en tirer, et même plusieurs fois la même, voire permuter les 2 mêmes 2 fois (genre 1 et 12, puis 12 et 1, ou bien 1 et 7, puis 7 et 12, puis 12 et 1, et du coup c'est pas mélangé) avec une très très (très très) faible probabilité..



    bien sûr avec ma méthode, il y a une probabilité non nulle que la liste ne soit
    pas triée, mais ce serait vraiment pas de bol

    La méthode shuffle fait pas loin de ce que tu fais : elle parcourt les items de la fin au début, et permute l'item courant avec un item aléatoire tiré entre le courant et le premier. un carte déjà sélectionnée donc ne sera pas repermutée.

    tu peux donc modifier ton algo si tu veux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        private void melangerCartes(){
            int aleatoire;
            Carte temporaire;
            //Choisis 26 cartes parmis tous les contacts
            for(int i=0; i<listeCartes.length-1; i++){  
              // Tirer un nombre au hasard entre la suivante et le nombre de cartes
                aleatoire = auHasardEntre(i+1, listeCartes.length);   
                System.out.println(i+" Aléatoire "+aleatoire);
              // Echanger la carte d'indice i avec celle tirée au hasard
              temporaire = listeCartes[i];
              listeCartes[i] = listeCartes[aleatoire];
              listeCartes[aleatoire] = temporaire;
            }
    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.

  5. #5
    Membre averti
    Homme Profil pro
    Retraité
    Inscrit en
    Août 2013
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 52
    Par défaut
    J'ai réécrit scrupuleusement le code et cela fonctionne.
    Il affiche 52 cartes différentes maintenant.

    Dans le reste de mon programme, j'ai du changer les listeCartes[i] par des List.get...
    J'avoue que j'y vais maintenant à l'aveuglette pour comprendre comment fonctionne les pointeurs pour ce ArryList...

    Mais il affiche bien toutes les 52 cartes différentes...
    Il me reste à les mettre en paires mélangées.

    J'ai ajouté un for dans la méthode initialiseCartes() pour voir ce qui est trié.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
              // Mélanger toutes les photos du dossier
              melangerCartes();
              //Devrait garder que les 26 premières déjà mélangées par melangeCartes()...
              listeCartes.subList(0,25);
                for (int i=0; i < nombreDePhotos; i++){
                    System.out.print(i+" "+listeCartes.get(i).getUrlFace()+" ");
                    System.out.print(listeCartes.get(i).getDepartement()+" ");
                    System.out.println(listeCartes.get(i).getFonction()+" ");
                }
    Mais que fait le code listeCartes.subList(0,25); exactement puisque si je met le compteur à nombreDeCartes (52...) bien il m'affiche les 52 cartes triées quand même. J'aurais cru que cette fonction garde les 26 premières cartes et efface les autres dans la liste mais non... Elles sont encore là !!!???

    J'imagine que de cette manière, je dois créer une autre liste, y ajouter 2 fois les 26 cartes et finalement remélanger le tout?

    Merci de ton aide

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Non, en effet,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listeCartes.subList(0,26);
    (j'ai fait une petit erreur, dans mon précédent post, avec l'index de fin qui est exclus alors que j'avais fait comme s'il était inclus )

    ne supprime pas les 74 autres cartes, c'est une méthode qui récupère une sous liste dans la liste d'origine (attention elle reste liée à la liste d'origine) : le résultat de l'appel est cette sous liste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<Carte> sousListe = listeCartes.subList(0,26);
    je ne connaissais pas la structure complète de ton programme et je ne savais pas que tu souhaitais conserver ta liste d'origine comme base pour remplir ta grille (je pensais que tu voulais conserver dans un coin ta liste de 100 photos, pour pouvoir la réutiliser à chaque nouvelle partie.

    si tu veux que ta variable listeCartes deviennent une liste de 26 paires.

    soit tu crées une nouvelle liste avec ces 26 cartes, soit tu enlèves les 74 autres.

    par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listeCartes =  new ArrayList<Carte>(listeCartes.subList(0,26));
    ou pour supprimer les 74 autres

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while( listeCartes.size()>26 ) listeCartes.remove(26);
    soit tant qu'il reste plus de 26 cartes (de 0 à 25 donc), supprimer la carte d'index 26

    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listeCartes.subList(26,100).clear();
    soit enlever de la liste les cartes de 26 à 99... (ou plutôt sémantiquement, créer une sous-liste allant de 26 à 100 exclus, et retirer tous les éléments s'y trouvant)

    ensuite pour obtenir tes 26 paires il suffit d'ajouter à ta liste, les cartes qui s'y trouvent déjà :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listeCartes.addAll(listeCartes);
    puis de la remélanger :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Collections.shuffle(listeCartes);
    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.

  7. #7
    Membre averti
    Homme Profil pro
    Retraité
    Inscrit en
    Août 2013
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 52
    Par défaut
    Merci! Cela simplifie de beaucoup ma programmation.

    J'ai une question existentielle:
    Le constructeur d'une classe s'exécute-t'il à l'exécution de la classe ou après avoir exécuté sa partie main?
    Dans mon programme, c'est le constructeur qui appelle les autres méthodes du programme et ça fonctionne!

    Je ne vois pas la différence entre mettre mon code dans le constructeur ou dans la partie main... C'est assez mélangeant merci.
    Aussi, je ne vois pas trop l'utilité du constructeur à part de ne pas nommer cette méthode InitialisationJeuCEP qui ferait probablement le même travail...

    Dans mon programme actuel, la partie main ne fait qu'un
    public void run() {
    new JeuCEP().setVisible(true);


    et la partie constructeur fait le reste...

    Ma structure est-elle correcte ou bien je devrais obligatoirement appeler mes méthodes à la suite du main?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Code qui ne fonctionne pas sur Mac
    Par malbaladejo dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 14/01/2005, 11h08
  2. [SQL] Requête à jointure qui ne fonctionne pas
    Par Bensor dans le forum Langage SQL
    Réponses: 2
    Dernier message: 09/12/2004, 16h10
  3. Jointure externe qui ne fonctionne pas
    Par Guizz dans le forum Langage SQL
    Réponses: 3
    Dernier message: 05/02/2004, 12h26
  4. CREATEFILEMAPPING qui ne fonctionne pas???
    Par Jasmine dans le forum MFC
    Réponses: 2
    Dernier message: 06/01/2004, 19h33
  5. UNION qui ne fonctionne pas
    Par r-zo dans le forum Langage SQL
    Réponses: 7
    Dernier message: 21/07/2003, 10h04

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