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

Collection et Stream Java Discussion :

Aide pour un sudoku avec ArrayList et sauvegarde des placements


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2010
    Messages : 39
    Par défaut Aide pour un sudoku avec ArrayList et sauvegarde des placements
    Bonjour,

    Petit problème, j'ai besoin d'aide pour un travail dans un cours en Java.
    La partie qui me prose problème est la suivante:

    J'ai un sudoku et toutes les valeur sont dans un int[9][9] (ici c'est fait)
    Je dois faire 10 placement de valeur (pour les case qui ont une valeur de 0) (ici pas fait mais je ne crois pas avoir de difficulté pour le faire, juste à donner une nouvelle valeur à 10 cases de mon int[][])
    Jusqu'ici ça va... cepentant je dois enregistrer une trace de mes placement dans un ArrayList et ensuite effacer les deux dernier placement en me basant sur la ArrayList, puis revenir à ma grille de départ en me basant encore sur la ArrayList. Je ne connais nullement les ArrayList...

    Quelqu'un peut m'aider?

    Merci

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 156
    Par défaut
    Je ne comprends pas tout à ta demande (pourquoi effacer les 2 derniers placements et ensuite remettre tout ça dans une tableau???).

    Algorithmiquement ce qu'on te demande n'a absolument aucun intérêt (le tableau à 2 dimensions me semble la meilleure représentation) mais c'est peut-être pour te faire travailler un point particulier...

    Tu peux considérer qu'une ArrayList est un "super tableau" à une dimension. Son principal avantage par rapport au tableau est que sa taille n'est pas prédéfinie et n'est pas non plus limitée (enfin si par la mémoire au moins).
    Partant de là, si tu dois obligatoirement travailler sur une ArrayList, il faut que tu codes une méthode qui te permette de passer de la représentation [][] à la représentation ArrayList et une autre qui fasse le contraire. La première consiste à passer ton tableau "à plat", cad itérer sur toutes les cases et les mettre dans l'ArrayList. La seconde consiste à le remettre en colonnes, cad incrémenter le compteur de la 2nde dimension jusqu'à la taille d'une ligne (ici 9) et y mettre la valeur à la position courante dans la liste avec un add() puis incrémenter le compteur de la 1ère dimension et recommencer jusqu'à avoir atteint le nombre de colonnes.

    Pour l'effacement il te faudra probablement une méthode qui à partir de la position dans le tableau te calcule la position dans la liste (position dans la liste = y * 9 + x, x étant la position horizontale (2 ème dimension) et y la position verticale (1 ère dimension), x et y commençant à 0 vu que ce sont des tableaux).

  3. #3
    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 : 55
    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,

    Je ne pense qu'il s'agisse de représenter la grille dans une ArrayList. La grille est un tableau à 2 dimensions. Je pense que le but de l'ArrayList est de stocker les emplacements "joués", afin de faire il semble (entre autres) un undo (revenir en arrière sur les chiffres placés dans la grille).
    La question primordiale est de savoir ce qu'on veut mettre dans l'ArrayList : un placement de chiffre dans une grille peut se stocker sous la forme :
    1. d'un couple de coordonnées (une classe qui représente un couple de int)
    2. 2 int (les éléments de position paire seraient les abscisses, et les éléments impaires les ordonnées).
    3. un String avec une syntaxe adéquate (par exemple du genre A3 (genre bataille navale))

    Le cas 2 pourrait expliquer pourquoi on parle de retirer les 2 derniers placements pour revenir en arrière d'un coup (le terme placements n'est pas très juste certe).
    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.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2010
    Messages : 39
    Par défaut
    Merci de vos réponses.

    J'explique un peu mieux, le travail ayant avancé mais me pose toujours problème.

    J'ai un Sudoku, représenté dans un int [9][9]
    Plusieurs case de ce tableau 2d ont déjà des chiffre variant de 1 à 9, puis bien sur il y a les case vide (0).
    J'ai une classe Sudoku, qui contient ce tableau et plusieurs méthode.
    Dans la classe Sudoku j'ai une méthode fairePlacement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ArrayList Placement = new ArrayList();
     
    public void fairePlacement() {
     
    			board[0][0] = 1; // Attribut une valeur à la case (0,0) de mon sudoku
    			Case Place1 = new Case();			
    			Place1.setPlacement(0, 0, 1);
    			verif(); //appel une méthode permettant de verifier si le chiffre placé est valide ou non
    			board[0][1] = 2;
    			Case Place2 = new Case();
    			Place2.setPlacement(0, 1, 2);
    		}
    Je dois faire 10 placements et chacun de ces placements doit être sauvegardé dans un objet nommé Case

    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
    class Case {
    		int Line;
    		int Row;
    		int Value;
     
    		public int getLine() {
    			return Line;
    		}
     
    		public int getRow() {
    			return Row;
    		}
     
    		public int getValue() {
    			return Value;
    		}
     
    		public void setPlacement(int x, int y, int z) {
    			Line = x;
    			Row = y;
    			Value = z;
    		}										
    	}
    Je dois absolument me servir d'une ArrayList pour mon travail et mon ArrayList doit être impliqué dans la procédure d'enregistrement des placement. Ce que je pensais faire est une ArrayList contenant le nom de chaque objet servant à mon placement, c'est-à-dire ajouter une ligne de code après chaque attibution de valeur dans ma méthode faireplacement pour donner quelque chose comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public void fairePlacement() {
     
    			board[0][0] = 1; // Attribut une valeur à la case (0,0) de mon sudoku
    			Case Place1 = new Case();			
    			Place1.setPlacement(0, 0, 1);
                            Placement.add(Place1);
    			verif(); //appel une méthode permettant de verifier si le chiffre placé est valide ou non
    			board[0][1] = 2;
    			Case Place2 = new Case();
    			Place2.setPlacement(0, 1, 2);
                            Placement.add(Place2);
    		}
    Cependant lorsque je System.out.println(Placement) je n'obtien pas les x, y et z que j'ai placé dans mon objet mais une série de chiffre et lettre. Alors je ne sais pas comment l'utiliser pour faire un undo à ma méthode. Car il me faut absolument faire 10 placement (donc je vais créer manuellement Place1, Place2... Place10) puis ensuite je dois annuler les deux dernier placements fait. Je dois donc avoir une méthode pour regarder Placement.size, faire un Placement.remove pour obtenir ce qu'il y a dans ma array list puis d'aller chercher les x et y de mon objet Placex afin de faire board[x][y] = 0.
    Pour mon travail je suis obligé de faire 10 placements,
    Utiliser une ArrayList
    Enregistrer une trace de tous les placements
    Canceller les 2 derniers placements

    Des idées?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2010
    Messages : 39
    Par défaut
    Pour terminer je dois aussi canceller tous les placements effectué pour revenir à ma grille de départ, en suivant mon historique de sauvegarde, et non en appelant les valeur de ma grille original.

  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 : 55
    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
    Citation Envoyé par Rashlack Voir le message
    Cependant lorsque je System.out.println(Placement) je n'obtien pas les x, y et z que j'ai placé dans mon objet mais une série de chiffre et lettre.
    C'est parce que tu n'as pas implémenté la méthode toString() de Case. Java ne devine pas comment tu veux afficher tes objets.

    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
    class Case {
    		int Line;
    		int Row;
    		int Value;
     
    		public int getLine() {
    			return Line;
    		}
     
    		public int getRow() {
    			return Row;
    		}
     
    		public int getValue() {
    			return Value;
    		}
     
    		public void setPlacement(int x, int y, int z) {
    			Line = x;
    			Row = y;
    			Value = z;
    		}							
     
                    public String toString() {
                           return "["+Line+","+Row+","+Value+"]"; // par exemple...
                    }
     
    	}
    Citation Envoyé par Rashlack Voir le message
    Alors je ne sais pas comment l'utiliser pour faire un undo à ma méthode.
    Ceci n'a rien à voir avec l'affichage. Il faut simplement que tu ailles chercher le dernier placement dans la liste : Case dernierPlacement = Placement.remove(Placement.size()-1); (remove pour le retirer de la liste (en fait, une Deque serait probablement plus adaptée qu'une List, mais je suppose qu'on ne t'a pas encore parlé de cette interface)).
    Ensuite, tu peux utiliser les attributs de l'objet pour annuler (ou autre) le placement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     int x=dernierPlacement.getLine();
    /*...*/
    En revanche, l'intérêt de stocker une valeur dans Case, c'est de pouvoir revenir à la valeur avant placement, donc de stocker la valeur avant placement, pas placée.

    Au passage, il y a des conventions de nommage en Java. Et ces conventions indiquent que les noms de variables commencent par une minuscule...
    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
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2010
    Messages : 39
    Par défaut
    Bonsoir et merci

    J'ai fait la de petits changement pour m'orienté dans la direction que tu m'as proposé:
    Alors voici une partie de ma class Sudoku dans laquelle il y a mes deux méthode pour faire et annuler un placement

    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
    static int[][] board = new int[9][9];
    	   ArrayList placement = new ArrayList();
     
              public void fairePlacement() {
    			board[0][0] = 1;
    			Case place1 = new Case();			
    			place1.setPlacement(0, 0, 1);
    			placement.add(place1);
    			verif();
    			board[0][1] = 2;
    			Case place2 = new Case();
    			place2.setPlacement(0, 1, 2);
    			placement.add(place2);
    		}
     
    		public void annulerPlacement()  {
    			Case dernierPlacement = (Case) placement.remove(placement.size()-1);
    			int x = dernierPlacement.getLine();
    			int y = dernierPlacement.getRow();
    			board[x][y] = 0;
    		}
    Puis ici nous avons ma class Case:

    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
     
    	class Case {
    		int Line;
    		int Row;
    		int Value;
     
    		public int getLine() {
    			return Line;
    		}
     
    		public int getRow() {
    			return Row;
    		}
     
    		public int getValue() {
    			return Value;
    		}
     
    		public void setPlacement(int x, int y, int z) {
    			this.Line = x;
    			this.Row = y;
    			this.Value = z;
    		}										
    	}
    Le tout fonctionne assez bien, cependant il me reste des petites question.
    Dans la solution proposé vous m'avez dit d'inclure le code suivant à ma class Case et je ne sais pas trop pourquoi et comment l'utiliser... :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                    public String toString() {
                           return "["+Line+","+Row+","+Value+"]"; // par exemple...
                    }
    Aussi le correcteur automatique de Eclipse m'a fait ajouter " (case) " à la formule que vous m'aviez proposé de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Case dernierPlacement = (Case) placement.remove(placement.size()-1);
    Si je n'ajoute pas ce " (Case) " ça ne fonctionne pas, et je ne sais pas pourquoi non plus. Oui ça fonctionne pour l'instant mais afin de pouvoir l'utiliser ultérieurement dans d'autre situation, j'aimerais comprendre.

    Puis est-il possible d'exécuter une méthode plusieurs fois dans avoir à dupliquer la ligne l'initiant "x" fois. C'est-à-dire que dans mon main j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    IGrille.fairePlacement();
    		IGrille.Grille();
    		IGrille.verif();
    		IGrille.annulerPlacement();
    		IGrille.annulerPlacement();
    		IGrille.Grille();
    Puis Si je fais 10 placements, j'aurai ensuite à canceller 10 placements pour revenir à l'original. Il faut que appeler la méthode annulerPacement 10 fois?

    Et une petite dernière question, malgré que le tout fonctionne, si je voulais faire 10 placements de façon aléatoire (dans les case qui sont vide seulement ( donc valeur 0 ). Comment devrais-je m'y prendre?

    Encore une fois un gros merci pour votre aide.

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

Discussions similaires

  1. besoin d'aide pour une jointure avec une exclusion
    Par manu_71 dans le forum Requêtes
    Réponses: 2
    Dernier message: 27/02/2007, 11h22
  2. Réponses: 24
    Dernier message: 12/02/2007, 23h56
  3. Réponses: 16
    Dernier message: 01/02/2007, 16h04
  4. Aide pour un warning avec RegSetValueEx
    Par Pierre.g dans le forum Windows
    Réponses: 4
    Dernier message: 24/08/2006, 14h46
  5. [PHP-JS] besoin d'aide pour menu déroulant avec lien
    Par Damarus dans le forum Langage
    Réponses: 3
    Dernier message: 06/10/2005, 18h43

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