Java: Question array list et instance de classe

Discutez d'informatique ici !
Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

Java: Question array list et instance de classe

par Rockleader » 07 Mai 2015, 17:29

Bonjour,

Je n'arrive pas à comprendre le comportement suivant


Code: Tout sélectionner
public void playNAleat(int n,Partie p){
      int r1=1;
      int c1=1;
      Position p1=new Position(r1,c1);
      ArrayList part=new ArrayList();
      for(int k=0;k<n;k++){
         part.add(p);
      }
      for(int k=0;k<n;k++){
         Partie temp=part.get(k);
         ArbreGo tree=new ArbreGo(p1,temp.g);
         System.out.println(tree.endGameAleat(temp));
      }
   }



Je commence par stocker n partie dans une array list.
Dans un second temps, je fais jouer ces partie de façon aléatoire

Sauf que voilà, il semblerait que j'ai les même tirage à chaque fois.

Par exemple pour n=2

1 2 3 4 5 6 7 8 9
1 . O O O X X X X X
2 X X X O X X X X X
3 X X . O X X X X X
4 X . X X X X X X X
5 X X X X X X X X X
6 . X X X X X X X X
7 X X X X X X X X X
8 X X X X X X X X X
9 X X X X X X X X X

1
1 2 3 4 5 6 7 8 9
1 . O O O X X X X X
2 X X X O X X X X X
3 X X O O X X X X X
4 X . X X X X X X X
5 X X X X X X X X X
6 . X X X X X X X X
7 X X X X X X X X X
8 X X X X X X X X X
9 X X X X X X X X X

1


On remarquera qu'une seule intersection vide se remplit.

En réalité je me dis...la première partie aléatoire se joue comme il faut...mais ensuite, comme les références de bases sont sur la même partie, il ne reprends pas du début mais comme le partie précédente a été laissé.


J'ai pu confirmer ce problème en spécifiant bien une nouvelle instance de classe partie et là ça marche comme il faut...sauf que si je fais ça je ne pourrais m'en servir que pour le premier coup...le but est de pouvoir dérouler plusieurs partie aléatoire à partir d'une même partie...



C'est un vrai casse tête ahah


En gros il semblerait que

si je fais

Partie p1=new Partie(9);
Partie p2=p1;

Toute opération sur p1 modifiera p2 aussi; et je voudrais éviter ça...mais je ne sais vraiment pas comment faire x) :mur:
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !



Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 08:03

par ampholyte » 07 Mai 2015, 18:13

Bonjour,

Regarde par ici, il y a une explication et une solution pour cloner des objets :

http://stackoverflow.com/questions/869033/how-do-i-copy-an-object-in-java

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 07 Mai 2015, 18:25

ampholyte a écrit:Bonjour,

Regarde par ici, il y a une explication et une solution pour cloner des objets :

http://stackoverflow.com/questions/869033/how-do-i-copy-an-object-in-java



J'avais tenté le coup du constructeur comme ça, mais sans succès, peut être m'y étais je mal pris. Je vais tenter à nouveau.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 07 Mai 2015, 18:37

J'ai donc mon constructeur de base

Code: Tout sélectionner
public Partie(int size){
      this.g=new Goban(size);
      this.j1=new JoueurNoir("Joueur 1");
      this.j2=new JoueurBlanc("Joueur 2");
   }


Le second constructeur qui devrait faire la copie

Code: Tout sélectionner
public Partie(Partie p){
      this.g=p.g;
      this.j1=p.j1;
      this.j2=p.j2;
   }




Et donc la fonction

Code: Tout sélectionner
public void playNAleat(int n,Partie p){
      int r1=1;
      int c1=1;
      Position p1=new Position(r1,c1);
      ArrayList part=new ArrayList();
      for(int k=0;k<n;k++){
         Partie test=new Partie(p);
         part.add(test);
      }
      for(int k=0;k<n;k++){
         Partie temp=part.get(k);
         ArbreGo tree=new ArbreGo(p1,temp.g);
         System.out.println(tree.endGameAleat(temp));
      }
   }

Là en théorie je clone dans test et je stocke les clones dans l'array list

Donc, dans la seconde boucle je travaille sur les clones en théorie. Pourtant je continue à tirer la même série aléatoire...





EDIT:


C'est quand même étrange, sur le principe ça a l'air de fonctionner
Code: Tout sélectionner
public class Test {
   public int nb;
   
   
   public Test(int n){
      this.nb=n;
   }
   
   public Test(Test t){
      this.nb=t.nb;
   }
   
   public static void main(String[] args) {
      Test t1=new Test(5);
      Test t2=new Test(t1);
      t2.nb++;
      System.out.println(t1.nb +" "+ t2.nb);
   }
}


Ici j'obtiens bien 5 et 6.

Bon...je dois avoir fait un truc de travers j'imagine...
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 07 Mai 2015, 19:27

le truc c'est que 5 et 6 c'est des int donc des types primitifs qui sont forcément copiés.

toi quand t'écris Partie a = b,
tu fais référence à b, comme si a pointait vers b...

pour ca, le mieux c'est que tu implémentes une méthode clone sur ta Partie, et du coup tu écris
Partie a = b.clone();

puis dans clone tu t'assures évidemment de cloner tous tes objets
edit vraisemblablement clone existe déjà, ya surement un peu d'effort à fournir, mais tu devrais utiliser les mecanismes java
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 07 Mai 2015, 19:59

J'ai donc implémenter l'interface dans partie en redéfinissant Clone en public.

Code: Tout sélectionner
public Object clone() {
      Object o = null;
      try {
         // On récupère l'instance à renvoyer par l'appel de la
         // méthode super.clone()
         o = super.clone();
      } catch(CloneNotSupportedException cnse) {
         // Ne devrait jamais arriver car nous implémentons
         // l'interface Cloneable
         cnse.printStackTrace(System.err);
      }
      // on renvoie le clone
      return o;
   }


Mais je continue à reprendre le dernier état de la partie entre les clones...
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 14:25

par Cliffe » 07 Mai 2015, 21:16

Code: Tout sélectionner
ArrayList part = new ArrayList();
for(int k = 0; k < n; ++k)
    part.add(new Partie(p));

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 07 Mai 2015, 21:34

Cliffe a écrit:
Code: Tout sélectionner
ArrayList part = new ArrayList();
for(int k = 0; k < n; ++k)
    part.add(new Partie(p));



Partie test=new Partie(p);
part.add(test);

C'est la même chose non ? ou alors je saisis pas la différence...
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 14:25

par Cliffe » 07 Mai 2015, 22:03

Tout est "pointeur" en java si tu veux.

Ce n'est pas pareil qu'en C++, attention.

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 07 Mai 2015, 23:24

ben déjà depuis le temps ca serait bien que tu fournisses un moyen pour reproduire au lieu de balancer une fonction de nul part.

ensuite,
on sait même pas ou tu la redéfinis, ni pourquoi.

et enfin, si les membre de ta classe ne définissent pas clonable, sont-ils clonés?
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 08 Mai 2015, 00:49

Bon, si j'ai bien compris:

Si la classe que je veux cloner contient des types non primitif; pour que la copie s'effectue alors

Je dois implémenter clone dans chacune de ses classes.

Et je dois faire la même chose jusqu'à tomber sur une classe ne contenant plus que des primitif.


Si j'ai

public class Partie{
Goban g
int nb
}


public class Goban{
ArrayList liste
ArrayList chain
int taille
}


public class Intersection{
int nb
}

public class Chaine{
int nb
}


Les attributs ne sont en rien représentatifs de ce que j'ai, c'est simplement pour comprendre le problème.


Si je veux cloner une partie; je vais devoir implémenter clone dans chacune des classes mentionnées ci dessus ? J'ai du mal avec ces histoires...

PS: désolé fatal, je suis sûrement pas très clair dans mes dires, j'essaie simplement de rester d'un point de vue général pour que l'on ne se perde pas dans toutes les lignes de codes obscures que j'ai pondu..je suis parfaitement conscient que j'ai du code assez sale pour le moment avec surement un tas de lignes inutiles ou en tout cas difficile à comprendre...


Pour le moment j'essaye de faire quelque chose qui marche, je ne cherche pas la performance. Je veux surtout essayer de comprendre, et je crois me rappeler de ce que tu me disais ces dernières années; le détail du code on s'en fout un peu, il faut juste représenter le problème de façon simplifié.
C'est ce que j'ai essayé de faire...peut être maladroitement mais ça n'en reste pas moins mon intention.


Encore une fois, merci pour votre patience.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 08:03

par ampholyte » 08 Mai 2015, 08:56

Rockleader a écrit:Si la classe que je veux cloner contient des types non primitif; pour que la copie s'effectue alors

Je dois implémenter clone dans chacune de ses classes.

Et je dois faire la même chose jusqu'à tomber sur une classe ne contenant plus que des primitif.


Oui tu as bien compris. Lorsque tu as une classe non primitive, il faut implémenter clone dans celle-ci; et cela pour chaque classe non primitive que tu utilises dans ta classe principale

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 08 Mai 2015, 09:30

et enfin, si les membre de ta classe ne définissent pas clonable, sont-ils clonés?


http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone%28%29

Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 08 Mai 2015, 13:44

Bon et bien je sais ce qu'il me reste à faire merci à vous tous :we:
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 08 Mai 2015, 18:05

Bon et bien, il semblerait que je n'ai toujours pas le résultat attendu, je continue à retravailler la même partie à chaque fois :mur:

J'ai pourtant bien implémenter clone dans chaque classe où elle devait l'être.





La fonction que j'essaie de faire tourner est donc la suivante

Code: Tout sélectionner
public void playNAleat(int n,Partie p2){
      for(int k=0;k chain=new ArrayList();
   //permet de vérifier l'appartenance d'une intersection à un territoire
   //ne doit pas être utilisé pour autre chose
   public ArrayList listeVerif=new ArrayList();


public Goban clone() {
      try {
         // On récupère l'instance à renvoyer par l'appel de la
         // méthode super.clone()
         Goban cloned = (Goban) super.clone();
         
         // Et on clone manuellement tous les types mutables :
         cloned.ko=cloned.ko.clone();
         for(int k=0;k maChaine = new ArrayList();
   public int nbRock=0;
   public int nbLiberteChaine=0;
   public String symbole;

public Chaine clone() {
         try {
            // On récupère l'instance à renvoyer par l'appel de la
            // méthode super.clone()
            Chaine cloned = (Chaine) super.clone();
            // Et on clone manuellement tous les types mutables :
            for(int k=0;k node=new ArrayList();
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 09 Mai 2015, 21:39

J'ai complètement changé ma structure et ça fonctionne désormais sans problème :)

J'ai moi même construit le chainage, j'ai été obligé d'utiliser des variables globales aux objet de la classe..mais bon pas grave, le principal c'est que ça marche.



Je pense que ma prochaine réflexion ça va être sur le temps...5 secondes pour simuler une partie...c'est beaucoup mais vraiment beaucoup trop long...

A 5 seconde par partie en supposant que je veuille tester 3 partie depuis chaque intersection dès le début, ça fait 15 seconde par intersection...soit 20 minute pour tester l'ensemble des 81 intersections...

Et ça juste pour déterminer le premier coup théorique de l'ia....







EN fait le problème je pense l'avoir identifié..c'est la génération des coups aléatoires..à chaque fois que je vais taper sur une intersection non jouable je vais reboucler, et comme c'est aléatoire, il y a le potentiel de boucler à l'infini...il faudrait que je garde le coté aléatoire tout en pouvant supprimer les coups illégaux de cet aléatoires...
Peut être la solution à faire ce serait de stocker tous les coups potentiellement valide quitte à perdre du temps pour mettre à jour cette liste.
En contrepartie chaque coup aléatoire sera forcement valide.



Bref bref bref vais réfléchir à tout ça^^
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 16:31

par joel76 » 09 Mai 2015, 22:55

Rockleader a écrit:Bref bref bref vais réfléchir à tout ça^^
C'est ça le problème de l'IA, à partir d'un moment, il faut quand même réfléchir ....

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 8 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite