Retour à l'accueil
Accueil Aide Rechercher Calendrier Identifiez-vous Inscrivez-vous
Bienvenue, Invité. Veuillez vous connecter ou vous inscrire.
Avez-vous perdu votre courriel d'activation?
25 Septembre 2017 à 22:22

Connexion avec identifiant, mot de passe et durée de la session
Règlement | Grades du forum | L'équipe de modération | Album photo | Chat
Rechercher:     avancée
Forums Zelda Solarus  |  Jeux amateurs  |  Programmation  |  Sujet: [GM8.1 / GML] Tri de plusieurs listes en fonction d'une autre 0 Membres et 1 Invité sur ce sujet.
Pages: [1] Imprimer
Auteur Sujet: [GM8.1 / GML] Tri de plusieurs listes en fonction d'une autre  (Lu 15550 fois)
iArcadia
Sheikah
*
Hors ligne Hors ligne

Messages: 4 782



WWW
« le: 16 Juin 2014 à 22:30 »

Bonsoir chers solarussiens.

Me voilà en présence d'un problème qui est relativement embêtant. Ce n'est pas faute d'avoir essayé plusieurs méthodes, il m'est arrivé de penser avoir trouver la bonne, mais il s'avère un peu plus tard que ce n'est pas le cas quand j'ajoute du contenu.

Voici concrètement ce que je voudrais réaliser : une sorte de "Pokédex" pour ranger les différents dragons disponibles du jeu facebook Dragon City. Seulement voilà, impossible d'associer les informations affichées à l'écran avec le dragon concerné.

Pour être un peu plus précis, je copie la liste contenant le nom des dragons (global.dragonName) dans une liste temporaire (tempList), puis je trie global.dragonName dans l'ordre alphabétique grâce à une fonction de base (ds_list_sort), et j'essaye de trier toutes les autres en récupérant le nouvel index de la liste triée... Enfin en gros, un p'tit bordel.

Je vous passe la fonction que j'ai créé au cas où, vu comment j'explique super bien.

Code:
var tempList, i, tempValue, tempIndex; // déclaration de variables

// copie de la liste contenant le nom des dragons dans une liste temporaire
tempList = ds_list_create();
ds_list_copy(tempList,global.dragonName);

// tri de la liste d'origine dans l'ordre alphabetique
ds_list_sort(global.dragonName,argument0);

// parcourt de toutes les autres listes
for (i = 0 ; i <= (ds_list_size(tempList)-1) ; i += 1) // tant que i est inférieur à la taille de la liste (= du nombre total de dragons)
{    
    // récupère le nouvel index grâce à la valeur de la liste temporaire
    tempValue = ds_list_find_value(tempList,i);
    tempIndex = ds_list_find_index(global.dragonName,tempValue);
    
    // déplace les informations de l'index d'origine vers le nouvel index pour chaque liste
    tempValue = ds_list_find_value(global.dragonPictureName,i);
    ds_list_insert(global.dragonPictureName,tempIndex,tempValue);
    if (i < tempIndex) ds_list_delete(global.dragonPictureName,i);
    else ds_list_delete(global.dragonPictureName,i+1);
    
    tempValue = ds_list_find_value(global.dragonDescription,i);
    ds_list_insert(global.dragonDescription,tempIndex,tempValue);
    if (i < tempIndex) ds_list_delete(global.dragonDescription,i);
    else ds_list_delete(global.dragonDescription,i+1);
    
    ... (y'en a plein d'autres !)
    
    tempValue = ds_list_find_value(tempList,i);
    ds_list_insert(tempList,tempIndex,tempValue);
    if (i < tempIndex) ds_list_delete(tempList,i);
    else ds_list_delete(tempList,i+1);
}

Si vous ne comprenez pas le problème, n'hésitez pas à me le dire que j'explique un peu mieux ! sourire
« Dernière édition: 16 Juin 2014 à 22:32 par iArcadia » Journalisée
Neo2
Sheikah
*
Hors ligne Hors ligne

Messages: 4 537



« Répondre #1 le: 16 Juin 2014 à 23:05 »

La solution la plus simple serait de :
- Copier la liste des noms
- La trier dans l'ordre souhaité
- Garder cette copie

Et pour accéder aux informations :
- Récupérer l'index du dragon dans la liste d'origine grâce à son nom
- Récupérer les informations du dragon via cet index

Idéalement, la liste "triée" devrait même contenir directement les index dans la liste d'origine :p
Journalisée
iArcadia
Sheikah
*
Hors ligne Hors ligne

Messages: 4 782



WWW
« Répondre #2 le: 16 Juin 2014 à 23:24 »

Ah tiens tu n'es pas porté disparu toi ? sourire

Merci pour ta réponse, mais ce que tu viens d'expliquer, je crois que ça correspond à ce que je fais en fait :

Citation
- Récupérer l'index du dragon dans la liste d'origine grâce à son nom

Code:
tempValue = ds_list_find_value(tempList,i);
tempIndex = ds_list_find_index(global.dragonName,tempValue);

Ou alors je n'ai pas compris ta solution.
Journalisée
Neo2
Sheikah
*
Hors ligne Hors ligne

Messages: 4 537



« Répondre #3 le: 16 Juin 2014 à 23:26 »

Je parlais plutôt de récupérer l'index à partir du nom lors de l'affichage des informations, et les récupérer a ce moment là, plutôt que de trier toutes les différentes listes ^^
Journalisée
Wouf
Hylien
*
Hors ligne Hors ligne

Messages: 1 116


C'est la faim !


« Répondre #4 le: 17 Juin 2014 à 00:10 »

Ca remonte tout ça ^^'

Bon alors déjà une première chose: il est délicat de modifier une liste pendant qu'on la parcourt (on risque de modifier les infos dont on aura besoin lors d'une itération ultérieure).

Ensuite, c'est plutôt lourd de trier plusieurs listes (perfs), alors qu'une seule suffirait. Si tu tiens absolument à garder plusieurs listes, pourquoi ne pas simplement créer une liste de positions et t'arranger pour maintenant la correspondance élément à élément avec la liste qui te sert d'ordre (alphabêtique en l'occurence). Ce qui te fait deux listes à réorganiser. Ensuite, tu parcours les éléments de la liste à positions et tu les utilises comme position pour récupérer les éléments depuis les autres listes (que tu n'as plus besoin de trier).

EDIT1: c'est la solution postée par Néo2 entre-temps tire la langue
EDIT2: surtout que récupérer un élément par sa valeur est beaucoup plus coûteux que par sa position. (pour ceux qui me gueuleraient dessus, sachez que les listes Gml sont implémentées par des tableaux).

Sinon, je me demande s'il n'y a pas moyen de grouper toutes les infos relatives aux dragons dans un type d'objet et de créer une liste d'instances vers ces objets. Ainsi, tu n'as qu'une seule liste. Mais ça ne t'arrange pas pour le tri vu que tu ne disposes que de deux tris: croissant et décroissant qui se fera sur les id d'instance dans le cas présent :/

La meilleure solution que je vois passerait par une dll faite maison (un langage tel que le C permet de grouper toutes les données des dragons au sein d'une même structure et de trier selon l'une des caractéristiques via callback comparateur).

En fait, tout dépend du nombre d'ordre de tri que tu aimerais. Si tu ne veux qu'un tri alphabêtique en plus de l'ordre par défaut (id spécifique aux dragons commençant à 0 jusque ton nombre de dragons-1), alors je te conseille de passer par un conteneur map (nomDuDragon->idDuDragon). Je m'explique:
A) création des structures de données
  • A1) Tu crées un tableau global pour chaque caractéristique du dragon (sauf le nom), et tu les insères dans l'ordre d'id des dragons. Par exemple
    img[0] = imgBulbizarre, img[1] = imgHerbizarre, ...
    type[0] = plante, type[1] = plante, ...
  • A2) tu crées une liste avec les noms de tes dragons
    ds_list_add(nameList, "bulbizarre"), ds_list_add(nameList, "herbizarre"),  ...
  • A3) tu crées une map avec comme clef le nom du dragon et comme valeur associée l'id du dragon
    ds_map_add(map, "bulbizarre", 0), ds_map_add(map, "herbizarre", 1), ...
B ) Tri par id
  • B1) par ordre croissant, il te suffit de parcourir tous les tableaux d'un coup avec un index allant de 0 jusque nombreDeDragon-1 (une seule boucle for dans laquelle tu accèdes à l'élément i de toutes tes listes)
  • B2) par ordre décroissant, idem, mais de nombreDeDragons-1 à 0.
C) Tri par ordre alphabêtique (croissant comme décroissant)
  • C1) tu tries la liste par ordre alphabêtique (croissant ou décroissant) : ds_list_sort(nameList, true)
  • C2) tu parcours cette liste dans l'ordre et tu récupère le nom : name = ds_list_find_value(nameList, i)
  • C3) tu utilise le nom dans la map pour récupérer l'id : id = ds_map_find_value(map, name)
  • C4) tu utilises l'id dans chacun de tes tableaux pour récupérer l'élément associé : value = img[id], type = img[id], ...

Ca devrait fonctionner à condition que le conteneur map accepte le texte comme clef.
Si tu veux trier par type, ça sert à rien d'utiliser un conteneur map puisque plante correspond à plusieurs Pokémon --> lequel choisir ? En fait, la relation caractéristique <-> id doit être bijective sourire
« Dernière édition: 17 Juin 2014 à 00:24 par Wouf » Journalisée

Marre des pavés ? Marchez dans la boue!
ハハ、あなたは私の罠に落ちた!
Pages: [1] Imprimer 
Forums Zelda Solarus  |  Jeux amateurs  |  Programmation  |  Sujet: [GM8.1 / GML] Tri de plusieurs listes en fonction d'une autre
Aller à:  

Propulsé par MySQL Propulsé par PHP Powered by SMF 1.1.20 | SMF © 2006, Simple Machines XHTML 1.0 Transitionnel valide ! CSS valide !
Zelda Solarus 2009Skin par Eidarloy
www.zelda-solarus.com