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 :

Comment rendre ce bout de script plus joli?


Sujet :

Python

  1. #1
    Invité
    Invité(e)
    Par défaut Comment rendre ce bout de script plus joli?
    Bonjour, c'est mon tout premier post, je suis un développeur du dimanche autant dire que mon niveau est plutôt bas...
    Bref, je programme pour un jeu pas tout récent BF2142 et je voudrais rendre ce bout de script plus digeste, je souhaite au final faire en sorte qu'il ne reste qu'un seul drapeau par équipe et que se soit les 2 plus éloignés (ah oui mon script fonctionne bien...) :
    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
    g_cP = bf2.objectManager.getObjectsOfType('dice.hfe.world.ObjectTemplate.ControlPoint') #Cette ligne permet d'obtenir tout les drapeaux de la carte appartenant à une des deux équipes ou encore neutre...
    	teamPAC = []
    	teamUE = []
    	for flag in g_cP:
    		teamFlag = int(flag.cp_getParam('flag')) #Permet d'obtenir le numéro de l'équipe possédant le drapeau, 0 = neutre, 1 = PAC, 2 = UE
    		if teamFlag == 1:
    			teamPAC.append(flag) #Le 'flag' est un objet contenant qq données tel que ses coordonnées, son appartenance à une équipe...
    		if teamFlag == 2:
    			teamUE.append(flag)
    	if len(teamUE) > 1 or len(teamPAC) > 1: #Sur certaines cartes il n'y a qu'un seul drapeau par équipe au début, donc le pb n'est pas pour ces cartes là.
    		disPosList = []
    		for flag in teamPAC:
    			pos1 = flag.getPosition()
    			for advFlag in teamUE:
    				disPosList.append([flag,advFlag, getVectorDistance(pos1,advFlag.getPosition())]) #Là j'ajoute dans une liste une autre liste comportant 2 drapeaux adverses et la distance qui les séparent. Je fais ça pour tous les drapeaux.			
    		compList = []
    		for comp in disPosList:
    			compList.append(comp[2])	#Là je crée une autre liste qui ne garde que les distances et ensuite je trie de la plus petites à la plus grande.			
    		compList.sort()
     
    		for comp in disPosList:
    			if compList[-1] in comp:
    				saveThisComp = comp     #Je garde seulement la liste contenant les drapeaux adverses les plus éloignés.
     
    		for flag in g_cP:
    			if flag not in saveThisComp:
    				flag.cp_setParam('team', 0)     #Je rends neutre tout les autres drapeaux.
    				flag.cp_setParam('flag', 0)
    Je sens que je n'ai pas été très clair, mais dur de faire quelques choses de concret et explicite... Je pourrais tenter de m'expliquer autrement si vraiment c'est imbuvable...
    Si comme moi ça vous amuse de perfectionner des scripts, j'attends vos réponses avec impatience! ^^
    Dernière modification par Invité ; 11/02/2014 à 21h35.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Bonjour et bienvenue sur le forum.

    Ça peut encore aller, c'est pas imbuvable. La logique est assez facile à suivre.

    Une version plus courte (pas testée bien sûr, donc il y a certainement des fautes):
    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
    g_cP = bf2.objectManager.getObjectsOfType('dice.hfe.world.ObjectTemplate.ControlPoint') # Cette ligne permet d'obtenir tous les drapeaux de la carte appartenant à une des deux équipes ou encore neutres...
     
    # partionner les drapeaux par équipe
    teams = [[],[],[]]
    for flag in g_cP:
        teams[int(flag.cp_getParam('flag'))].append(flag) # teams: 0 = neutre, 1 = PAC, 2 = UE
     
    # déterminer le couple de drapeaux les plus éloignés
    keep = max([(f1, f2) for f1 in teams[1] for f2 in teams[2]],
               key = lambda (f1,f2): getVectorDistance(f1.getPosition(), f2.getPosition()))
     
    #rendre neutre tous les autres drapeaux
    for flag in g_cP:
        if flag not in keep:
            flag.cp_setParam('team', 0)
            flag.cp_setParam('flag', 0)

  3. #3
    Invité
    Invité(e)
    Par défaut
    Wahou!
    J'ai beaucoup de mal à comprendre la fonction max et encore plus à savoir quand utiliser lambda qui est pourtant très utile!
    Malheureusement ça n'a pas l'air de fonctionner, en même temps ce jeu est vieux et la version de python aussi, qui plus est le jeu bloque certains modules par soucis de sécurité j'imagine...
    En tout cas merci beaucoup, je vais bucher la dessus, maitre Yoda!

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Quelle est la version de python ?
    Sinon, tu sais à quel niveau ça bloque ?

    Quelques explications pour max:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [(f1, f2)for f1 in teams[1]for f2 in teams[2]]
    construit une liste des couples de drapeaux possibles; c'est équivalent à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    liste = []
    for f1 in teams[1]:
        for f2 in teams[2]:
            liste.append((f1,f2))
    La fonction max, comme son nom l'indique, retourne le maximum sur le tableau de couples, mais ça n'aurait pas beaucoup de sens de comparer les couples de drapeaux entre eux directement, c'est pourquoi on passe à l'argument key une fonction qui sera appliquée à chaque élément de la liste; le maximum sera évalué sur la valeur de retour de cette fonction.
    La fonction est définie de façon anonyme avec une lambda, qui reçoit comme argument le couple (f1,f2) et retourne la distance entre f1 et f2.
    C'est un syntaxe un peu particulière qui est utilisée pour indiquer que l'argument de la lambda est un couple, si c'est ça qui bloque, tu peux la remplacer par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    lambda flags: getVectorDistance(flags[0].getPosition(), flags[1].getPosition())

  5. #5
    Invité
    Invité(e)
    Par défaut
    La version de python est la version 2.3.4, et il est impossible de la mettre à jour malheureusement...
    J'ai essayé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    keep = max([flags for f1 in teams[1] for f2 in teams[2]],key = lambda flags: getVectorDistance(flags[0].getPosition(), flags[1].getPosition()))
     
    keep = max([(f1, f2) for f1 in teams[1] for f2 in teams[2]],key = lambda flags: getVectorDistance(flags[0].getPosition(), flags[1].getPosition()))
     
    keep = max([[f1, f2] for f1 in teams[1] for f2 in teams[2]],key = lambda flags: getVectorDistance(flags[0].getPosition(), flags[1].getPosition()))
     
    keep = max([(f1) for f1 in teams[1]],key = lambda flags: getVectorDistance(flags[0].getPosition(), flags[1].getPosition()))
    Et malheureusement il n'y a rien dans keep peut importe ce que j'essaye, pourtant si je fais une faute de syntaxe, le script plante bien comme il faut ^^, donc on peut imaginer qu'il reconnait la fonction max, non?
    Si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    keep = max(45,23,89,25)
    Le serveur m'affiche (en écho) : Si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    keep = max(32,12,90,10)
    Le serveur m'affiche (en écho) : J'adore Python sur ce jeu, tout fonctionne très bien sur IDLE par contre rien ne va fonctionner comme il le devrait ingame, ça permet de pousser la réflection encore un peu plus loin au cas ou c'était pas déjà assez complexe ^^.
    En tout cas merci, pour ton aide, si tu abandonnes je ne t'en voudrais pas...

  6. #6
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    L'argument key a été ajouté en python 2.5, ça explique donc le problème.
    Essaie ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    keep = max([(getVectorDistance(f1.getPosition(), f2.getPosition()), f1, f2) for f1 in teams[1] for f2 in teams[2]])[1:]

    C'est le pattern decorate/undecorate: on "décore" les éléments avec la valeur qui sert pour les comparaisons. Comme la comparaison de tuples se fait dans l'ordre lexicographique (le premier élément a le plus de poids, plus le second sert à départager les égalités, etc.) ça donnera le résultat voulu. A la fin on enlève l'élément qu'on a ajouté (ce qui explique le [1:]).

  7. #7
    Invité
    Invité(e)
    Par défaut
    Tu es un dieu , mec! ^^
    Ca marche, impec! Tu programmes en python depuis combien de temps pour information?

    Merci beaucoup! Problème résolu et compris.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Merci pour le compliment

    Je ne saurais pas dire quand j'ai commencé le Python exactement, je me rappelle que c'est du Python 2.3 à l'époque. Et comme mon inscription au forum date de 2007, ça doit faire au moins depuis ce temps-là je pense...

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

Discussions similaires

  1. [WD-2003] Formulaire : comment rendre la mise en page plus souple ?
    Par Lucie_ dans le forum Word
    Réponses: 3
    Dernier message: 16/11/2010, 17h02
  2. Comment rendre Shutdown immediate plus rapide ds Oracle9i
    Par mtaleb dans le forum Administration
    Réponses: 3
    Dernier message: 06/05/2009, 10h30
  3. Modifier l'url d'une page perso pour la rendre plus "jolie" ?
    Par bond70 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 10/02/2009, 13h14
  4. comment rendre compatible ce script avec firefox ?
    Par xav20 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 31/07/2007, 18h35
  5. Comment avoir des interfaces Qt plus jolies ?
    Par Tux1 dans le forum PyQt
    Réponses: 3
    Dernier message: 02/10/2006, 13h39

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