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

Python Discussion :

Rendre un objet indépendant dans une liste d'objets


Sujet :

Python

  1. #1
    Membre du Club
    Homme Profil pro
    Amateur vb.net
    Inscrit en
    Avril 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Amateur vb.net
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 99
    Points : 60
    Points
    60
    Par défaut Rendre un objet indépendant dans une liste d'objets
    Bonjour, avant de vous expliquer mon problème, je vous présente mes codes:
    Voici comment je déclare ma classe Region:
    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
    # -*-coding:Latin-1 -*
    class Region:
     
        def __init__(self):
            self.nom = ""
            self.description = ""
            self.id = ""
            self.regionParent = self.id
            self.motsCles = []
            self.facteurDep = 1
            self.creaturesRencontrables= []
            self.conditionsEntrer = []
            self.conditionsSortir = []
            self.effets = []
            self.objets = []
            self.creatures = []
            self.portails = []
            self.directionUtil = 11111111
    Ici je définis différents types de régions:
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    plaine_du_ninejaddai = Region()
    plaine_du_ninejaddai.id = 'plaine_du_ninejaddai'
    plaine_du_ninejaddai.nom = 'Plaine du Ninejaddai'
    plaine_du_ninejaddai.motsCles = ['#plaine','#ninejaddai']
    plaine_du_ninejaddai.creatures = [[bouc1,[1,1]],[bouc2,[1,1]],[bouc3,[0,1]]]
    plaine_du_ninejaddai.creaturesRencontrables = [bouc,orque_miteux,troll_geant_maladroit,rat_pesteux]
    plaine_du_ninejaddai.description = "Une plaine sauvage malgré les nombreux pâturages de boucs."
     
    foret_de_schlipak = Region()
    foret_de_schlipak.id = 'foret_de_schlipak'
    foret_de_schlipak.nom = 'Forêt de Schlipak'
    foret_de_schlipak.motsCles = ['#foret']
    foret_de_schlipak.creaturesRencontrables = [orque_miteux,troll_geant_maladroit]
    foret_de_schlipak.description = "Une grande forêt peuplée de divers peuples et diverses créatures."
     
    plaine_du_ninejaddai_lisiere_schlipak = Region()
    plaine_du_ninejaddai_lisiere_schlipak.id = 'plaine_du_ninejaddai_lisiere_schlipak'
    plaine_du_ninejaddai_lisiere_schlipak.nom = 'Plaine du Ninejaddai - Lisière de la forêt de Schlipak'
    plaine_du_ninejaddai_lisiere_schlipak.regionParent = 'plaine_du_ninejaddai'
    plaine_du_ninejaddai_lisiere_schlipak.motsCles = ['#plaine','#ninejaddai', '#lisiere','foret']
    plaine_du_ninejaddai_lisiere_schlipak.creatures = [[bouc1,[1,1]],[bouc2,[1,1]],[bouc3,[0,1]]]
    plaine_du_ninejaddai_lisiere_schlipak.creaturesRencontrables = [bouc,orque_miteux,troll_geant_maladroit,rat_pesteux]
    plaine_du_ninejaddai_lisiere_schlipak.description = "La lisière de la forêt de Schlipak avec la plaine du Ninejaddai."
     
    plaine_du_ninejaddai_route = Region()
    plaine_du_ninejaddai_route.id = 'plaine_du_ninejaddai_route'
    plaine_du_ninejaddai_route.nom = 'Plaine du Ninejaddai - Route de Zoyek'
    plaine_du_ninejaddai_route.regionParent = 'plaine_du_ninejaddai'
    plaine_du_ninejaddai_route.motsCles = ['#plaine','#ninejaddai','#route']
    plaine_du_ninejaddai_route.creatures = [[bouc1,[1,2]],[bouc2,[1,2]],[bouc3,[0,2]]]
    plaine_du_ninejaddai_route.creaturesRencontrables = [bouc,rat_pesteux]
    plaine_du_ninejaddai_route.description = "La route traversant la plaine du Ninejaddai et reliant Zoyek au lac de Zblouf."
     
    bordure_fleuve_elibed = Region()
    bordure_fleuve_elibed.id = 'bordure_fleuve_elibed'
    bordure_fleuve_elibed.nom = 'Bordures du fleuve Elibed'
    bordure_fleuve_elibed.motsCles = ['#fleuve','#ninejaddai','#plaine']
    bordure_fleuve_elibed.creatures = [[bouc1,[1,1]],[bouc2,[1,1]],[bouc3,[0,1]]]
    bordure_fleuve_elibed.creaturesRencontrables = [bouc,orque_miteux,troll_geant_maladroit,rat_pesteux]
    bordure_fleuve_elibed.description = "Les bordures du fleuves Elibed qui sépare la plaine du Ninejaddai des terres sauvages de Kwzprtt."
    Alors ici je définis la map de mon jeu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    univers.map = [[plaine_du_ninejaddai_route,plaine_du_ninejaddai,plaine_du_ninejaddai_lisiere_schlipak,foret_de_schlipak,foret_de_schlipak,foret_de_schlipak],
                   [plaine_du_ninejaddai_route,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai_lisiere_schlipak,foret_de_schlipak,foret_de_schlipak],
                   [plaine_du_ninejaddai,plaine_du_ninejaddai_route,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai_lisiere_schlipak,foret_de_schlipak],
                   [plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai_route,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai_lisiere_schlipak],
                   [plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai_route,plaine_du_ninejaddai_route,plaine_du_ninejaddai],
                   [plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai_route],
                   [plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai],
                   [bordure_fleuve_elibed,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai],
                   [plaine_du_ninejaddai,bordure_fleuve_elibed,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai,plaine_du_ninejaddai]
                   ]
    Le fonctionnement est assez simple: Cette liste définit en fait la map de mon jeu, chaque emplacement contient une région (un objet).
    Ainsi on peu accéder à la région d'un emplacement précis en faisant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    region = univers.map[X][Y]
    Voici la représentation de la map. Les carrés verts foncés représentent foret_de_schlipak, les verts clairs plaine_du_ninejaddai_lisiere_schlipak, les beiges plaine_du_ninejaddai, les marrons/gris plaine_du_ninejaddai_route et les bleus bordure_fleuve_elibed.
    Le point (x=0,y=0) se trouve en bas à gauche.
    Nom : terressauvages-carte2_rogné.jpg
Affichages : 225
Taille : 10,3 Ko

    Lorsque le joueur rencontre une créature, la créature est piochée au hasard et elle est ajoutée à la liste des créatures de la région dans laquelle se trouve le joueur dans univers.map (donc elle est ajoutée à univers.map[personnage.positionX][personnage.positionY].creatures).
    Mais c'est là que le problème se manifeste puisqu'elle s'ajoute également à toutes les régions du même type dans univers.map. Ce qui est assez logique.
    Pour résoudre ce problème j'ai fait cette fonction que j'applique à univers.map comme ceci:
    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
    29
    30
    31
    32
    33
    34
    35
    def ModifierMap(map = []):
        i = 0
        while i < len(map):
            a = 0       
            while a < len(map[i]):
                obj = map[i][a]
                newObj = Region()
                newObj.conditionsEntrer = obj.conditionsEntrer
                newObj.conditionsSortir = obj.conditionsSortir
                newObj.creatures = obj.creatures
                newObj.creaturesRencontrables = obj.creaturesRencontrables
                newObj.description = obj.description
                newObj.directionUtil = obj.directionUtil
                newObj.effets = obj.effets
                newObj.facteurDep = obj.facteurDep
                newObj.id = obj.id
                newObj.motsCles = obj.motsCles
                newObj.nom = obj.nom
                newObj.objets = obj.objets
                newObj.portails = obj.portails
                newObj.regionParent = obj.regionParent
                map[i][a] = newObj
                a += 1
            i += 1
        return map
     
    univers.map = ModifierMap(univers.map)
    map = univers.map
    i=0
    while i < len(map):
            a = 0       
            while a < len(map[i]):
                print(id(map[i][a]))
                a+=1
            i+=1
    La dernière boucle affiche les ids de tous les éléments de univers.map. Je confirme que tous les objets ont bien des ids différents.
    Malheureusement le problème n'est pas résolu: les créatures sont toujours ajoutée à toutes les régions du même type que celle dans laquelle ont veut en ajouter. Mais si les ids pythons des objets sont différents, les objets devraient être indépendants non ?

    Je précise que je suis ici entrain de tester si les mécanismes du jeu fonctionnent bien. Dans la version finale, l'utilisateur pourra personnaliser entièrement l'univers du jeu, donc entre autres, les types de régions mais également leur répartition sur la map.

  2. #2
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2010
    Messages : 553
    Points : 2 740
    Points
    2 740
    Par défaut
    Salut,

    tout d'abord, je précise que j'ai pas cherché à comprendre ce que fait ta fonction qui était censée régler ton problème.

    mais vu ton problème, et intuitivement, je me dis que j'aurais probablement fait une sous classe de Region pour chaque type de région. un truc du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class SchlipakForest(Region):
    ...
    class NinejaddaiPlain(Region):
    ...
    ...
    tu pourrais ainsi mettre les caractéristiques communes au type de région dans des attributs de classe et les caractéristique propre à chaque case dans des attributs d'instance.
    Ensuite, au lieu de stocker la même instance pour chacune de tes cases du même type, tu aurais une instance par case et ton problème n'existerait plus.

    après, comme je l'ai dit, c'est ce que je ferai intuitivement, mais étant donné que chaque case serait une instance à part entière, ça peut faire fortement décoller la conso mémoire si tu fais une grosse map... du coup faut voir, t'auras peut être de meilleures propositions.

    HS: tu nous fait un jeu d'aventure sur Naheulbeuk?

  3. #3
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par herroP Voir le message
    les créatures sont toujours ajoutée à toutes les régions du même type que celle dans laquelle ont veut en ajouter. Mais si les ids pythons des objets sont différents, les objets devraient être indépendants non ?
    Bonjour,
    Je n'ai peut-être pas tout compris, mais:
    Quels sont les ids différents?
    "foret_de_schlipak" est une variable possédant un contenu.

    Toutes les cases "foret_de_schlipak" sont associées à la même variable… Modifier une liste de cette variable est donc visible dans toutes les autres cases (associées à cette même variable)!!!

    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
    >>> class Region:
    	def __init__(self):
    		self.lst = []
     
     
    >>> reg = Region()
    >>> tout = [reg, reg, reg]
    >>> tout[0].lst.append(1)
    >>> print(tout)
    [<__main__.Region object at 0x7fabcaa33eb8>, <__main__.Region object at 0x7fabcaa33eb8>, <__main__.Region object at 0x7fabcaa33eb8>]
    >>> print(tout[0].lst)
    [1]
    >>> print(tout[1].lst)
    [1]
    >>> print(tout[2].lst)
    [1]
    >>>
    Clodion

    PS: je n'ai pas non plus essayé de comprendre la fonction!!!

  4. #4
    Membre du Club
    Homme Profil pro
    Amateur vb.net
    Inscrit en
    Avril 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Amateur vb.net
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 99
    Points : 60
    Points
    60
    Par défaut
    Citation Envoyé par Tryph Voir le message
    mais vu ton problème, et intuitivement, je me dis que j'aurais probablement fait une sous classe de Region pour chaque type de région. un truc du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class SchlipakForest(Region):
    ...
    class NinejaddaiPlain(Region):
    ...
    ...
    En fait comme l'ai dit, dans la version finale toutes les régions (ainsi que la composition de la map) seront personnalisables. Donc il est impossible de prévoir les différents types de régions qui composeront le jeu. Je déclare ici des régions pour tester le jeu.

    Citation Envoyé par Tryph Voir le message
    après, comme je l'ai dit, c'est ce que je ferai intuitivement, mais étant donné que chaque case serait une instance à part entière, ça peut faire fortement décoller la conso mémoire si tu fais une grosse map... du coup faut voir, t'auras peut être de meilleures propositions.
    Effectivement c'est un risque mais c'est la solution qui me parait la plus adaptée pour le jeu que je veux faire.

    Citation Envoyé par Tryph Voir le message
    HS: tu nous fait un jeu d'aventure sur Naheulbeuk?
    Le principe du jeu est de se rapprocher le plus possible des jeux de rôles sur table mais en solo. Après tout l'univers est personnalisable, ainsi on peut recréer le jdr qu'on veut. J'ai effectivement pris le jdr naheulbeuk pour faire mes tests .

    Quels sont les ids différents?
    Effectivement j'ai oublié de préciser: je parle ici des ids pythons des objets (qu'on obtient avec id(objet)).

    Ma fonction remplace chaque objet de la map par un nouvelle objet qui prend tous les caractéristiques du précédent objet.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par herroP Voir le message
    Ma fonction remplace chaque objet de la map par un nouvelle objet qui prend tous les caractéristiques du précédent objet.
    Bonsoir,
    Oui, mais…
    Comme écrit précédemment, les mêmes objets sont attribués!
    En particulier les listes: ce sont les références aux listes qui sont copiées. Donc modifier celle de l'une des cases, sera répercuté sur l'ensemble des cases de la même région.
    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
    29
    30
    31
    >>> class Region:
    	def __init__(self):
    		self.lst = []
     
     
    >>> reg1 = Region()
    >>> reg1.lst.append(123)
    >>> reg1.lst
    [123]
    >>> reg2 = Region()
    >>> reg2.lst = reg1.lst
    >>> reg2.lst
    [123]
    >>> id(reg1)
    140647925837216
    >>> id(reg2)
    140647908681992
    >>> id(reg1.lst)
    140647942521928
    >>> id(reg2.lst)
    140647942521928
    >>> reg1.lst.append(456)
    >>> reg1.lst
    [123, 456]
    >>> reg2.lst
    [123, 456]
    >>> id(reg1.lst)
    140647942521928
    >>> id(reg2.lst)
    140647942521928
    >>>
    Désolé je ne sait qu'écrire pour être plus explicite!

    Clodion

  6. #6
    Membre du Club
    Homme Profil pro
    Amateur vb.net
    Inscrit en
    Avril 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Amateur vb.net
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 99
    Points : 60
    Points
    60
    Par défaut
    Ok, j'ai saisi l'idée.
    En cherchant un peu, j'ai trouvé la fonction deepcopy(). Du coup j'ai un peu modifier ma fonction et je sais pas trop pourquoi mais ça fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def ModifierMap(map = None):
        if map == None: map = []
        i = 0
        while i < len(map):
            a = 0        
            while a < len(map[i]):
                map[i][a] = copy.deepcopy(map[i][a])
                a += 1
            i += 1
        return map
    J'imagine que cette fonction rend indépendant l'objet copié mais également toutes ses propriétés.
    En tout cas merci beaucoup pour votre aide .

  7. #7
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par herroP Voir le message
    Ok, j'ai saisi l'idée.
    En cherchant un peu, j'ai trouvé la fonction deepcopy().
    J'imagine que cette fonction rend indépendant l'objet copié mais également toutes ses propriétés.
    Bonsoir,
    Oui, c'est l'une des solutions. Une autre, en se basant sur le travail initial se fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> class Region:
    	def __init__(self):
    		self.lst = []
     
     
    >>> reg1 = Region()
    >>> reg2 = Region()
    >>> reg1.lst.append(12)
    >>> reg2.lst = reg1.lst[:]
    >>> print(reg1.lst, reg2.lst)
    [12] [12]
    >>> print(id(reg1.lst), id(reg2.lst))
    140647908696456 140647908662600
    >>>
    Ici, la ligne "reg2.lst = reg1.lst[:]" créé une copie de la liste.

    Résumé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> lst1 = []
    >>> lst2 = lst1
    >>> lst3 = lst1[:]
    >>> print(id(lst1), id(lst2), id(lst3))
    140647908697224 140647908697224 140647908635464
    >>>
    Clodion

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

Discussions similaires

  1. recherche par attribut dans une liste d'objet
    Par Jacobian dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 28/05/2008, 21h11
  2. Stocker une liste d'objets personnalisés dans les settings
    Par laville dans le forum Général Dotnet
    Réponses: 12
    Dernier message: 13/12/2007, 11h14
  3. Réponses: 2
    Dernier message: 21/05/2007, 20h43
  4. Réponses: 1
    Dernier message: 13/09/2006, 11h50
  5. Créer une liste d'objets statiques dans une classe
    Par crossbowman dans le forum C++
    Réponses: 3
    Dernier message: 13/03/2006, 09h11

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