Enregistrement d'un jeu en format texte développé en JAVA

Résolu
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014 - 14 janv. 2012 à 10:23
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 - 18 janv. 2012 à 13:45
Bonjour à tous,

Je viens vous solliciter parce que je rencontre un gros soucis. Je vous explique, je dois développer un jeu en JAVA qui est le puissance 4 (ça c'est fait). Par contre, le joueur doit pouvoir s'il le souhaite enregistrer sa partie en cours pour la reprendre plus tard. Cette partie doit être enregistrer en format texte. Etant débutant en java, je ne sais pas du tout comment m'y prendre. J'ai pu voir sur internet qu'il existait les flux ou la sérialisation pour le faire.
Je viens donc ici pour vous demander votre aide et notamment comment je pourrais m'y prendre pour faire cet enregistrement. Bien entendu, je ne demande pas le code, mais une démarche à suivre (faut-il créer d'autres classes, que faut-il utiliser flux ou sérialisation ? etc)

Je vous remercie d'avance.

23 réponses

cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
14 janv. 2012 à 10:52
Bonjour,

Tu as plusieurs facons de procéder. Soit tu enregistres les données à la main, c'est à dire, tu édites un fichier qui contient les emplacements des pions sur le puissance 4 et les données importantes. Par exemple un fichier comme celui ci :

Joueur1:Pseudo1
Joueur2:Pseudo2
VVVVVV
VVVVVV
BNBNBN
NBNBNB

Ici V signifie vide et B et N sont des identifiants pour les couleurs des pions.

Cette solution présente un avantage : tu peux éditer le fichier texte manuellement pour modifier les paramètres de la partie. L'inconvénient est qu'il faut tout écrire : la façon d'éditer le fichier texte et le chargement de la partie.

La deuxième solution est plus simple bien que plus technique : C'est l'utilisation de la sérialisation. Tu créé un objet partie qui contient tous les paramètres de la partie (Ca peut être un JPanel par exemple si tu n'utilises pas de modèle pour ton code). Il te suffit alors de suivre ce tutoriel : http://www.javafr.com/codes/UTILISATION-SERIALISATION_53479.aspx et le tour est joué
3
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
14 janv. 2012 à 10:52
Remarque : la sérialisation créé également un fichier texte mais il n'est pas éditable à la main. Mais son format est bien texte, ce n'est pas un fichier binaire.
0
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014
14 janv. 2012 à 10:57
Merci beaucoup Julien pour ces précisions. Tu me conseillerais d'utiliser quoi entre les deux solutions sachant que ma seul contrainte est vraiment l'enregistrement dans un fichier texte ?
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
14 janv. 2012 à 15:52
Sans aucun doute la sérialisation alors, c'est beaucoup plus simple et rapide
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014
14 janv. 2012 à 18:25
D'accord merci, je vais donc utiliser cette technique.
Et merci beaucoup pour le tuto qui est très bien construit.

PS : je laisse le sujet ouvert au cas où que je rencontre un soucis

En tout cas, encore merci.
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
14 janv. 2012 à 18:54
Ok, normalement c'est assez simple et tu n'as pas grand chose à faire, ca devrait donc bien se passer si tu fais comme dans le tuto
0
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014
14 janv. 2012 à 20:36
J'ai bien fait comme dans le tuto, j'ai bien la création du fichier texte, mais quand je veux lire le fichier, rien ne se passe.

Voici mon code pour la sérialisation

public class Serializer {
    
    private static final Serializer instance = new Serializer();
    
    private final String chemin = "puissance4.txt";
    private Object taux;
    
    private Serializer() {
        super();
    }
    
    public void serialiser(ArrayList ihm){
        FileOutputStream fichier=null;
        ObjectOutputStream objet=null;
        try {
                fichier = new FileOutputStream(chemin);
                objet = new ObjectOutputStream(fichier);
                objet.writeObject(taux);
                objet.flush();
        } 
        catch (FileNotFoundException e) {
                e.printStackTrace();
        } 
        catch (IOException e) {
                e.printStackTrace();
        }
        finally {
                try {
                        if(objet!=null){
                                objet.close();
                        }
                        if(fichier!=null){
                                fichier.close();
                        }
                }
                catch (IOException e) {
                        e.printStackTrace();
                }
        }

    }
    
    public ArrayList deserialiser(){
ArrayList res = null;
try {
FileInputStream fichier = new FileInputStream(chemin);
ObjectInputStream object = new ObjectInputStream(fichier);
res = (ArrayList) object.readObject();
}
catch (java.io.IOException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
return res;
}

    public static Serializer getInstance() {
        return instance;
    }
}


et voici mon code du jeu
    public IHM(String titre,int x, int y, int largeur, int hauteur,Joueur j){
       
        // Titre, position de la fenêtre et taille préférée de la fenêtre
        setTitle(titre);
        setLocation(new Point(x,y));
        setPreferredSize(new Dimension(largeur,hauteur));
        
        // Initialisation de la barre des menus
        menuBar = new JMenuBar();

        // Initialisation du menu
        menu = new JMenu("Jeu");
        couleur = new JMenu("Couleur");

        // Initialisation des items du menu
        commencer = new JMenuItem("Commencer un nouveau jeu");
        enregistrer = new JMenuItem("Enregistrer");
        recharger = new JMenuItem("Recharger une partie");
        quitter = new JMenuItem("Quitter");
        changerCouleur = new JMenuItem("Changer de couleur");

        // Ajout des items
        this.menu.add(commencer);
        this.menu.add(enregistrer);
        this.menu.add(recharger);
        this.menu.add(quitter);
        this.couleur.add(changerCouleur);

        // Permet de quitter l'application
        quitter.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0){
                JOptionPane jop = new JOptionPane();
                int option = jop.showConfirmDialog(null,"Etes-vous sûr de vouloir arrêter ? ", "Arrêt du jeu", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);

                if(option == JOptionPane.YES_OPTION)
                    System.exit(0);

            } // fin actionPerformed
        }); // fin ActionListener

        // Permet de commencer une nouvelle partie
        commencer.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0){
                Joueur j = new Joueur();
                j.Joueur1.setText(joueur.j1);
                j.Joueur2.setText(joueur.j2);
                j.setVisible(true);
                setVisible(false);
            } //  fin actionPerformed
        }); // fin ActionListener

        // Permet d'enregistrer le jeu
        enregistrer.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0){
                JOptionPane jop = new JOptionPane();
                int option = jop.showConfirmDialog(null,"Etes-vous sûr de vouloir sauvegarder ? ", "Sauvegarde du jeu", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);

                 if(option == JOptionPane.YES_OPTION){
                      
                      ArrayList ihm = new ArrayList();
                      Serializer.getInstance().serialiser(ihm);
                      
                        int reponse = JOptionPane.showConfirmDialog(null, "Voulez-vous continuer la partie?", "Mastermind", JOptionPane.YES_NO_OPTION);
                        if(reponse == 1)
                        {
                            Joueur j = new Joueur();
                            j.Joueur1.setText(joueur.j1);
                            j.Joueur2.setText(joueur.j2);
                            j.setVisible(true);
                            setVisible(false);
                        }     
                  }
                    
            } // fin actionPerformed
        }); // fin ActionListener

        // Permet de recharger le jeu
        recharger.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0){
                JOptionPane jop = new JOptionPane();
                int option = jop.showConfirmDialog(null,"Etes-vous sûr de vouloir charger une partie ? ", "Chargement du jeu", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
                
                if(option == JOptionPane.YES_OPTION){
                   ArrayList ihm = Serializer.getInstance().deserialiser();
                }
            } // fin actionPerformed
        }); // fin ActionListener

        // Permet de changer de couleur
        changerCouleur.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0){
                JOptionPane jop = new JOptionPane();
                int option = jop.showConfirmDialog(null,"Etes-vous sûr de vouloir changer de couleur ? ", "Changer de couleur", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);

                if(option == JOptionPane.YES_OPTION){
                    couleur c = new couleur();
                }

            } // fin actionPerformed
        }); // fin ActionListener
                
        // Ajout de la barre des menus
        this.menuBar.add(menu);
        this.menuBar.add(couleur);
        this.setJMenuBar(menuBar);    
        
        this.joueur = j;
        
        // Le joueur courant est tiré aléatoirement
        for (int i = 0; i<2 ; i++)
        {
          joueurEnCours = (int)(Math.random() * 2);
        } // fin for

        //instanciation du JPanel général 
        this.jeu=new JPanel(new GridLayout(1,7));

        //instanciation du tableau de 'colonne'
        this.p=new Plateau[7];

        //pour toutes les colonnes du puissance 4
        for (int i=0;i<7;i++){
                //on crée un nouvel objet colonne
                this.p[i]=new Plateau(this);
                //et on récupère le JPanel correspondant qu'on ajoute dans 'tout'
                (this.jeu).add((this.p[i]).renvoyerPlateau());
        } // fin for

        //Création d'une instance de vérification
        verif=new verification(this.p);

                        
        if(joueurEnCours==0)
            nomJ = new JLabel(tour + joueur.j1);
        else if(joueurEnCours==1)
            nomJ = new JLabel(tour+ joueur.j2);

        JPanel pan=new JPanel();
        pan.add(nomJ);

        getContentPane().add(pan,BorderLayout.SOUTH);

        //ajout dans la JFrame principale
        this.getContentPane().add(this.jeu,BorderLayout.CENTER);

        // Bloquer redimension de l'image
        this.setResizable(false);
                
        pack();
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        
    }
    


Ai-je louper un truc ?
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
14 janv. 2012 à 20:43
Je dirais que la classe IHM est une Jframe, pour les frame, il faut refaire un frame.setVisible(true); pour l'afficher
0
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014
14 janv. 2012 à 20:54
Oui en effet, j'avais oublié ce point.

Faut-il que je le rajoute dans la fonction deserializer() ou un fois que j'ai fais ArrayList ihm = Serializer.getInstance().deserialiser(); ?
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
14 janv. 2012 à 22:23
C'est un peu comme tu veux.

Je pense que tu as des choses qui ne vont pas dans la fonction sérialiser. Tu n'enregistres pas le bon objet, taux est une variable que j'avais introduite dans le tutoriel, elle n'a rien à faire ici.

As tu réellement compris comment fonctionnait la sérialisation. Je te conseil de comprendre d'abord avec l'exemple et de le refaire dans ton cas.
0
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014
14 janv. 2012 à 22:42
Oui c'est de ma faute pour le "taux" j'ai pas copié le bon code.

Donc voici le bon :

public class Serializer {
    
    private static final Serializer instance = new Serializer();
    
    private final String chemin = "puissance4.txt";
    private Object IHM;
    IHM i;
    
    private Serializer() {
        super();
    }
    
    public void serialiser(ArrayList ihm){
        FileOutputStream fichier=null;
        ObjectOutputStream objet=null;
        try {
                fichier = new FileOutputStream(chemin);
                objet = new ObjectOutputStream(fichier);
                objet.writeObject(IHM);
                objet.flush();
        } 
        catch (FileNotFoundException e) {
                e.printStackTrace();
        } 
        catch (IOException e) {
                e.printStackTrace();
        }
        finally {
                try {
                        if(objet!=null){
                                objet.close();
                        }
                        if(fichier!=null){
                                fichier.close();
                        }
                }
                catch (IOException e) {
                        e.printStackTrace();
                }
        }

    }
    
    public ArrayList deserialiser(){
ArrayList res = null;
try {
FileInputStream fichier = new FileInputStream(chemin);
ObjectInputStream object = new ObjectInputStream(fichier);
res = (ArrayList) object.readObject();
}
catch (java.io.IOException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
                i.setVisible(true);
return res;
}

    public static Serializer getInstance() {
        return instance;
    }
}


En faisait le setVisible(), j'ai une erreur qui se produit "Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException"
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
15 janv. 2012 à 12:08
Ha quelle horreur, un catch de ClassNotFoundException, il faut a tout prix enlever ca...

Je ne sais pas ce qui t'as poussé à l'écrire mais la raison est forcément mauvaise. Pour ton NullPointerException, essayes déjà de mettre le setVisible(true) dans le bloc try. Ensuite, je ne sais pas pourquoi mais tu ne dé-sérialise rien du tout, ton fichier est il bien présent ?

private final String chemin = "puissance4.txt";
Cette ligne ne vas pas, tu devrais lui mettre un chemin absolu : "C:\\puissance4.txt" par exemple
0
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014
15 janv. 2012 à 13:47
Pourquoi faut-il enlever le catch de ClassNotFoundException ?
Ensuite pourquoi mettre un chemin absolu ?
Mon fichier est bien présent mais je n'ai que "¬íNUL ENQ p" dedans, je devrais surement avoir plus d'info dedans.
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
16 janv. 2012 à 08:16
Si tu retrouves bien ton fichier, tu n'es pas obligé de passer un chemin absolu ok. L'idéal serait de passer un chemin absolu en utilisant une properties. Mais bon, ce n'est pas ce que tu recherches je pense.

Il ne faut jamais catcher les RuntimeException : NullPointer, ClassNOtFound : ce sont des exceptions liée au développement qui ne doivent jamais être levées. Ici, si tu catches ClassNotFound, ca veut dire que tu tolères que ton programme tourne sans JRE et que tu vas gérer ce cas (ridicule non ?).

Ensuite, je ne sais pas ce qui se passe mal avec la sérialisation, si tu as bien suivi le tutoriel, normalement, tu ne devrais pas avoir de problème. Je te conseille de recommencer en faisant les choses pas à pas. Il me semble que tu as fais un copier coller trop rapidement sans prendre le temps de te poser les bonnes questions et de comprendre le fonctionnement du mécanisme
0
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014
16 janv. 2012 à 19:08
J'ai procédé en faisant ça :

FIle file = new File("puissance4.txt");
 
 try {
       FileWriter writer = new FileWriter(file);
       writer.write(tour);
       writer.write(joueurEnCours);
       writer.write(joueur.j1);
       writer.write(joueur.j2);
       writer.close();
} catch (IOException ex) {Logger.getLogger(Serializer.class.getName()).log(Level.SEVERE, null, ex);
}


ça m'enregistre bien mes chaines de caractères, par contre, comme j'ai besoin d'enregistrer l'état du jeu qui est un tableau d'objet dois-je procéder avec un "ObjectOutputStream" ?
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
17 janv. 2012 à 07:49
Ok, j'ai plusieurs remarques :

- C'est bien d'utiliser un Logger pour le produit en phase d'exploitation. Mais lors du développement, un e.printStackTrace() dans le bloc catch est souvent plus intéressant.

- A ta place, je ferais plusieurs ficheirs pour enregistrer les objets séparément. Au moins au début, ca te permettra de voir ce qui a bien été sérialisé.

Qu'obtiens tu quand tu désérialises ? Quels objets sont bons ?
0
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014
17 janv. 2012 à 08:36
Pour l'instant j'ai pas fais la partie déserialisation pas trop eu le temps de le faire.

Je prends note des tes remarques et je te tiens au courant.
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
17 janv. 2012 à 09:02
Serialiser sans désérialiser, ca ne sert vraiment pas à grand chose. Mais bon, c'est pour toi. Et franchement, je pensais que tu l'aurais fait en 30 minutes maxi...
0
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014
17 janv. 2012 à 09:19
Oui je sais, mais je développe plusieurs appli en parallèle pour mes cours du coup, je fais le plus urgent en priorité sinon oui en effet, je l'aurais fais d'affiler. Je m'en chargerais ce soir, et je te tiens au courant.
0
narizuke Messages postés 38 Date d'inscription mardi 31 mai 2011 Statut Membre Dernière intervention 9 février 2014
17 janv. 2012 à 17:07
Voici mon code modifié par contre le chargement ne fonctionne pas, mais la sauvegarde oui

public void sauvegarder(String s) throws FileNotFoundException, IOException
    {
        try{
            ObjectOutputStream save = new ObjectOutputStream(new FileOutputStream(s));
            save.writeObject(this);
            save.close();
        } catch (IOException e){
            e.printStackTrace();
            System.out.println("Impossible de sauvegarder");
            
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    
    public static IHM charger(String s) throws IOException{
        Object obj = null;
        try{
            ObjectInputStream load = new ObjectInputStream(new FileInputStream(s));
            obj = load.readObject();
            load.close();
            System.out.println(obj);
        }catch(IOException e){
            e.printStackTrace();
            System.out.println("Impossible de charger");
        }
        catch(Exception e){
            e.printStackTrace();
        }
        return (IHM)obj;
        
    }
0
Rejoignez-nous