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 :

Algorithme A* - Pathfinding - Aide requise /!\


Sujet :

Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Mars 2016
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mars 2016
    Messages : 18
    Points : 10
    Points
    10
    Par défaut Algorithme A* - Pathfinding - Aide requise /!\
    Bonjour à toutes et à tous !


    Je travaille actuellement sur un projet de jeu vidéo, un petit chose assez simple, mais plutôt ambitieux pour mon niveau: Je ne code en python que depuis 6 mois, et dans le cadre d'un cours ne représentant que très peu d'heures sur mon emploi du temps chargé de S.

    L'idée serait de créer un jeu d'infiltration en vue de dessus.
    Je vous passe tous les détails, pour en venir directement au fait:
    J'ai énormément de mal avec l'algorithme A*. Je planche dessus depuis maintenant plusieurs semaines, et je ne parviens pas à débloquer la situation.
    J'ai vraiment besoin d'aide, et tout conseil serait le bienvenue.

    Je joint à ce message le code actuel, et me tient disponible 24/24 en cas de réponse (et j'espère qu'il y en aura... )


    Je code actuellement sous Tkinter, mais ici le GUI n'a que peu d'importance puisqu'il ne sert qu'à montrer sous forme graphique les calculs internes du programme.

    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    # Créé par Elias, le 09/04/2016 en Python 3.2
    # -*- coding: utf-8 -*-
    """
    Éditeur de Spyder
     
    Ce script temporaire est sauvegardé ici :
    C:\Program Files (x86)\WinPython-32bit-3.3.2.1\settings\.spyder2\temp.py
    """
    from tkinter import*
    import sys
    from math import*
    from random import*
     
    print(sys.getrecursionlimit())
    sys.setrecursionlimit(5000)
     
    listeetude=[]
    listechoisi=[]
     
    class pion:
        """Cette classe ne définit pour le moment que:
        - Les coordonnées X
        - Les coordonnées Y
        - La position relative aux colonnes
        - La position relative aux lignes """
     
        def __init__(self):
            self.coordsx = 0
            self.coordsy = 0
            self.colonnes= 0
            self.lignes= 0
     
    class case: 
        """Cette classe définit, pour le moment:
            - La position relative aux colonnes et aux lignes.
            - La distance à l'arrivée en lignes et en colonnes.
            - La distance totale à l'arrivée
            - La distance au point de départ en lignes et en colonnes.
            - La distance totale au point de départ.
            - La qualité de cette case.
            - Dans quelle direction par rapport au noeud parent est placée cette case
            - Le type: Normal ou Bloqué.    """
        def __init__(self):
            self.colonnes=0
            self.lignes=0
            self.darcol=0
            self.darln=0
            self.dar = self.darcol+self.darln
            self.dgcol=0
            self.dgln=0
            self.dg= self.dgcol+self.dgln
            self.qual= self.dar + self.dg
            self.dir="direction"
            self.type=""
            self.parent=0
     
     
    def lignes_colonnes(x):
        x.lignes=int((x.coordsy/50)-0.5)+1
     
        x.colonnes=int((x.coordsx/50)-0.5)+1
     
     
     
    garde = pion()
    joueur = pion()
     
    p1=case()
    p2=case()
    p3=case()
    p4=case()
     
     
    compteur=0
     
     
    xpointdepart=25
    ypointdepart=25
     
    garde.coordsx=xpointdepart
    garde.coordsy=ypointdepart
     
    xpointarrivee=225
    ypointarrivee=225
     
    lignes_colonnes(garde)
     
    lignes_colonnes(garde)
    casegarde=case()
    casegarde.lignes=garde.lignes
    casegarde.colonnes=garde.colonnes
     
    joueur.coordsx=xpointarrivee
    joueur.coordsy=ypointarrivee
    lignes_colonnes(joueur)
    casearrivee=case()
    casearrivee.lignes=joueur.lignes
    casearrivee.colonnes=joueur.colonnes
     
    listechoisi.insert(0, casegarde)
    listeetude.insert(0, casegarde)
    listecaseobstacle=[]
    #304, 305, 306, 404
    xroot=0
    yroot=0
     
     
    OK=0
     
    colonne=0
    rang=0
     
    largeurcanvas=500
    hauteurcanvas=500
     
    largeurfenetre=800
    hauteurfenetre=500
     
    fen=Tk()
    fen.geometry(str(largeurfenetre)+"x"+str(hauteurfenetre))
    drawzone=Canvas(height=500, width=500, bg="white")
    drawzone.place(x=0,y=0)
     
    housetile=PhotoImage(file="rooftile.gif")
    pavestile=PhotoImage(file="paves.gif")
     
     
    mapfile1=open("maptest.txt")
     
    for ligne in mapfile1 : #On utilise le fichier texte joint pour créer le décor.
        for i in range(0,len (ligne)) :
            case = ligne[i]
            if case=='B':
                maison=drawzone.create_image(xroot,yroot, image=housetile, anchor="nw")
            if case=='P'   :
                rue=drawzone.create_image(xroot, yroot, image=pavestile, anchor="nw")
            xroot= xroot+50
        xroot=0
        yroot=yroot+50
     
    #zonebloquee=drawzone.create_polygon((100, 150), (150,150), (150,200), (100,200))
    #zonebloquee=drawzone.create_polygon((100, 200), (150,200), (150,250), (100,250))
    #zonebloquee=drawzone.create_polygon((100, 250), (150,250), (150,300), (100,300))
    #zonebloquee=drawzone.create_polygon((150, 150), (150,200), (200,200), (200,150))
     
     
     
    xroot=0
    yroot=0
     
    pointdepart=drawzone.create_oval(xpointdepart-10, ypointdepart-10, xpointdepart+10, ypointdepart+10, fill="green")
    pointarrivee=drawzone.create_oval(xpointarrivee-10, ypointarrivee-10, xpointarrivee+10, ypointarrivee+10, fill="blue")
     
    def qualitépoint(x): #Cette partie sert à déterminer la qualité de la case, en fonction de son statut et de sa position relative à celle du point d'arrivée.
        if ((x.lignes*100+x.colonnes) in listecaseobstacle) or (x in listechoisi): #Si la case est dans la liste des obstacles, ou a déjà été choisie par l'algorithme, on élimine la solution, en plaçant une valeur impossible à atteindre autrement.
            x.qual=999
        else: #On calcule ensuite la qualité du point grâce à la distance de Manhattan, à savoir :
            listeetude.append(x)
            x.darcol= fabs(casearrivee.colonnes-x.colonnes)  #Valeur absolue de la distance entre case d'arrivée et case de départ, sur x.
            x.darln= fabs(casearrivee.lignes-x.lignes) #Valeur absolue de la distance entre case d'arrivée et case de départ, sur y.
            x.dar= x.darcol + x.darln #Somme de ces deux valeurs
            x.qual=x.dar #Et qui donne la qualité du point.
     
     
    def pathfinding():
        chemin()
     
    def chemin(): #Cette partie du programme sert à vérifier la qualité des toutes les cases adjacentes à la dernière case étudiée.
        global compteur
     
        p1.colonnes=listechoisi[compteur].colonnes
        p1.lignes=(listechoisi[compteur].lignes)+1
        p1.direction="bas"
        p1.parent=listechoisi[compteur]
        qualitépoint(p1)
     
        p2.colonnes=(listechoisi[compteur].colonnes)
        p2.lignes=(listechoisi[compteur].lignes)-1
        p2.parent=listechoisi[compteur]
        p2.direction="haut"
        qualitépoint(p2)
     
        p3.colonnes=(listechoisi[compteur].colonnes)+1
        p3.lignes=(listechoisi[compteur].lignes)
        p3.direction="droite"
        p3.parent=listechoisi[compteur]
        qualitépoint(p3)
     
        p4.colonnes=(listechoisi[compteur].colonnes)-1
        p4.lignes=(listechoisi[compteur].lignes)
        p4.direction="gauche"
        p4.parent=listechoisi[compteur]
        qualitépoint(p4)
     
        if min(p1.qual, p2.qual, p3.qual, p4.qual) == p1.qual: #Cette partie sert à choisir la case ayant la qualité la plus basse, c'est à dire celle qui se rapproche le plus du point d'arrivée.
            listechoisi.append(p1)
            print("bas")
        elif min(p1.qual, p2.qual, p3.qual, p4.qual) == p2.qual:
            listechoisi.append(p2)
            print("haut")
        elif min(p1.qual, p2.qual, p3.qual, p4.qual) == p3.qual:
            listechoisi.append(p3)
            print("droite")
        elif min(p1.qual, p2.qual, p3.qual, p4.qual) == p4.qual:
            listechoisi.append(p4)
            print("gauche")
     
     
        compteur=compteur+1
     
        print(listechoisi[compteur].qual)
        print(listechoisi[compteur].colonnes, listechoisi[compteur].lignes)
        print(casearrivee.colonnes, casearrivee.lignes)
     
     
        drawzone.create_polygon((((listechoisi[compteur].colonnes-1)*50), ((listechoisi[compteur].lignes-1)*50)),(((listechoisi[compteur].colonnes)*50), ((listechoisi[compteur].lignes-1)*50)),(((listechoisi[compteur].colonnes)*50), ((listechoisi[compteur].lignes)*50)),(((listechoisi[compteur].colonnes-1)*50), ((listechoisi[compteur].lignes)*50)), fill="red" ) #Cette partie fait passer en rouge la case choisie par le programme.
     
     
     
     
     
     
     
    def deplacementpoint(evt): #Sert à déplacer le point de départ et le point d'arrivée: Touche fléchées pour le point de départ, et [zqsd] pour le point d'arrivée.
        global pointdepart
        global pointarrivee
        global xpointarrivee
        global ypointarrivee
        global xpointdepart
        global ypointdepart
        drawzone.delete(pointdepart, pointarrivee)
        if evt.keycode==38: #haut
            ypointdepart=ypointdepart-50
        elif evt.keycode==40: #bas
            ypointdepart=ypointdepart+50
        elif evt.keycode==37: #gauche
            xpointdepart=xpointdepart-50
        elif evt.keycode==39: #droite
            xpointdepart=xpointdepart+50
        elif evt.keycode==90: #"z"
            ypointarrivee=ypointarrivee-50
        elif evt.keycode==81: #"q"
            xpointarrivee=xpointarrivee-50
        elif evt.keycode==68: #"d"
            xpointarrivee=xpointarrivee+50
        elif evt.keycode==83: #"s"
            ypointarrivee=ypointarrivee+50
        garde.coordsx=xpointdepart
        garde.coordsy=ypointdepart
        lignes_colonnes(garde)
        joueur.coordsx=xpointarrivee
        joueur.coordsy=ypointarrivee
        lignes_colonnes(joueur)
        casegarde.lignes=garde.lignes
        casegarde.colonnes=garde.colonnes
        casearrivee.lignes=joueur.lignes
        casearrivee.colonnes=joueur.colonnes
        casearrivee.lignes=joueur.lignes
        casearrivee.colonnes=joueur.colonnes
        pointdepart=drawzone.create_oval(xpointdepart-10, ypointdepart-10, xpointdepart+10, ypointdepart+10, fill="green")
        pointarrivee=drawzone.create_oval(xpointarrivee-10, ypointarrivee-10, xpointarrivee+10, ypointarrivee+10, fill="blue")
     
     
     
     
    pathfindingbt=Button(text="Lancer procedure Pathfinding", command=pathfinding)
    pathfindingbt.place(x=550, y=100)
     
     
    fen.bind("<Key>", deplacementpoint)
     
     
    fen.mainloop()
    Ci-joint, les ressources nécessaires pour faire fonctionner le programme.maptest.txtNom : paves.gif
Affichages : 510
Taille : 1,6 KoNom : housetile.gif
Affichages : 515
Taille : 105 octets

    Je vous laisse le tester... Je ne saurais pas exactement dire quels bugs je rencontre, mais j'en ai repéré quelques uns:
    Tout d'abord, le fait que, d'une manière assez étrange, le programme choisira parfois une case en diagonale, ce qui n'est pas, en soi, un mauvais choix, mais rentre en contradiction nette avec ce qui est indiqué dans la fonction (chemin), puisque celle-ci ne permet de choisir que des cases situées à gauche, à droite, en bas ou en haut.

    Ensuite... Le fait que, passé les deux premières occurrences de la fonction (chemin), le programme fait... N'importe quoi, je ne saurais vraiment pas le décrire.


    J'ai vraiment besoin d'aide, pour le coup, c'est assez urgent, et je dois finir cela si je veux pouvoir passer à la suite...

    Merci beaucoup de votre attention, et merci d'avance si vous décidez de m'aider.

    A la prochaine !

    Saad

  2. #2
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Mars 2016
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mars 2016
    Messages : 18
    Points : 10
    Points
    10
    Par défaut Up !
    Up !

    (Vraaaaiment besoin d'un coup de main, les amis...)

  3. #3
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Salut,

    Ton code est vraiment illisible et incompréhensible
    Si tu sais coder en objet, fais le, car des globals dans tout les sens, c'est pas la panacée.

    Il y a un bon didacticiel en python sur cette page, c'est pour la résolution d'un labyrinthe en mode exploration, donc utilisant cet algo.

    http://www.laurentluce.com/posts/sol...-and-a-search/

    Bon courage
    Le temps ronge l'amour comme l'acide.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Mars 2016
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mars 2016
    Messages : 18
    Points : 10
    Points
    10
    Par défaut
    J'avais vu ce tutoriel, mais j'avais pas réussi à me dépatouiller avec...

    Je vous reposterai un code un peu plus lisible ce soir, les gens.


    En tous cas merci d'avoir répondu, ça fait plaisir !

  5. #5
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Quelqu'un qui voudrait t'aider devrait déjà se "farcir" les 273 lignes de ton code, et deviner (parce qu'il y a très peu de commentaires) ce que tu as voulu faire: tu en demandes vraiment beaucoup!

    Puisque tu es lycéen, applique la méthode de Pascal: découpe ton gros problème en plusieurs petits. Pour chacun d'entre eux, fais un petit code de test de 10 ou 20 lignes qui montre le problème que tu ne sais pas résoudre, et qu'on peut exécuter chez nous avec un simple copier-coller. Et là, tu auras plus de chances d'avoir des réponses.

    Et en faisant ça, il est d'ailleurs probable que tu auras toi-même trouvé une solution à plusieurs de tes petits problèmes! Et Il ne restera plus qu'à poster ici les petits problèmes restants.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  6. #6
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Mars 2016
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mars 2016
    Messages : 18
    Points : 10
    Points
    10
    Par défaut Message compris !
    Entendu les gens, désolé si je me suis emporté ^^
    C'est une des premières fois où je poste sur un forum de développement, j'ai pas encore tous les usages, je vous prie de m'excuser.


    Suivant vos conseils, voici mon code commenté, et une description de ce qui coince (pour le moment):

    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    def value(debut, fin): #On détermine ici la valeur H G ou Gaffiliée au point étudié (le point noté "début" dans les variables)
        global x #Ceci est la valeur calculée par l'algorithme, et qui sera soit affiliée à la valeur G ou à la valeur H
     
    #On utilise une case qu'on dira "fantôme", puisque le programme n'informe jamais le joueur de sa position et qu'elle ne sert qu'à calculer les distances, en allant case par case.
     
        if debut.lignes < p.lignes and debut.colonnes==p.colonnes: #On effectue le calcul case par case, en se rapprochant de la case voulue
            x=x+10
            p.lignes=p.lignes-1
     
     
        elif debut.lignes > p.lignes and debut.colonnes==p.colonnes:
            x=x+10
            p.lignes=p.lignes+1
     
     
        elif debut.colonnes < p.colonnes and debut.lignes==p.lignes:
            x=x+10
            p.colonnes=p.colonnes-1
     
        elif debut.colonnes > p.colonnes and debut.lignes==p.lignes:
            x=x+10
            p.colonnes=p.colonnes+1
     
     
        elif (debut.lignes < p.lignes and debut.colonnes<p.colonnes):
            x=x+14
            p.colonnes=p.colonnes-1
            p.lignes=p.lignes-1
     
        elif (debut.lignes > p.lignes and debut.colonnes<p.colonnes):
            x=x+14
            p.colonnes=p.colonnes-1
            p.lignes=p.lignes+1
     
        elif (debut.lignes > p.lignes and debut.colonnes>p.colonnes):
            x=x+14
            p.colonnes=p.colonnes+1
            p.lignes=p.lignes+1
     
     
        elif debut.lignes < p.lignes and debut.colonnes>p.colonnes:
            x=x+14
            p.colonnes=p.colonnes+1
            p.lignes=p.lignes-1
     
        #print(p.lignes, p.colonnes)
        #print(debut.lignes, debut.colonnes)
     
        if debut.lignes!=p.lignes or debut.colonnes!=p.colonnes: #Si jamais la case "p" est différente en colonnes ou en lignes à la case ciblée, l'étude n'est toujours pas terminée, et on la relance.
            fen.after(10, value(debut, fin))
     
    i=0
     
    def chemin(): #Cette partie du programme est la fonction affiliée au bouton de pathfinding.
        global i
        global x
        global courant
     
        listeouverte=[]
        listeF=[]
     
        drawzone.create_polygon((courant.colonnes-1)*50, (courant.lignes-1)*50, (courant.colonnes)*50, ((courant.lignes-1)*50), (courant.colonnes)*50, (courant.lignes)*50, (courant.colonnes-1)*50, (courant.lignes*50), fill="red")
     
        value(casegarde, casearrivee) #On calcule la valeur H de la case de début: la case du garde. Il s'agit de la distance entre la case garde et la case d'arrivée, la case joueur.
        casegarde.H=x #On fait de x, la valeur retournée par la fonction "value", la valeur H
        x=0 #On repasse la valeur de x à 0 pour pouvoir refaire un calul de valeur.
        value(courant, casegarde) #On calcule la valeur G de la case de début: la case du garde. Cette valeur est égale à 0, puisqu'il s'agit de la distance entre la case courante et la case garde. Or, le point courant est actuellement la case garde.
        casegarde.G=x #On fait de x, la valeur G
        x=0
        casegarde.F=casegarde.G+casegarde.H #On calcule la valeur F de casegarde, égale à la somme de G et de H
     
     
        #On étudie les p1, p2, ... , p8 en fonction du point courant: On modifie leurs valeurs colonnes et lignes, pour faire en sorte qu'elles soient les cases autour de la case courante.
        #Puis on calcule leurs valeurs H et G, sur le modèle de la case garde.
        #On calcule enfin leur qualité F, et on inclue cette qualité dans la listeF.
        #On les inclue ensuite dans la liste ouverte.
     
         #Droite
        p1.lignes=courant.lignes
        p1.colonnes=courant.colonnes+1
        p1.lincoln=p1.lignes, p1.colonnes
     
        if p1.lincoln not in listelincoln:
     
            listelincoln.append(p1.lincoln)
     
            p.colonnes=casearrivee.colonnes
            p.lignes=casearrivee.lignes
            value(p1, casearrivee)
            p1.H=x
            x=0
     
            p.colonnes=p1.colonnes
            p.lignes=p1.lignes
            value(casegarde, p1)
            p1.G=x
            x=0
     
            p1.F=p1.G + p1.H
            p1.parent=courant
            listeouverte.append(p1)
            listeF.append(p1.F)
            print(p1.H, p1.G, p1.F)
     
        #BasDroite
     
        p2.lignes=courant.lignes+1
        p2.colonnes=courant.colonnes+1
        p2.lincoln=p2.lignes, p2.colonnes
     
        if p2.lincoln not in listelincoln:
     
            listelincoln.append(p2.lincoln)
            p.colonnes=casearrivee.colonnes
            p.lignes=casearrivee.lignes
            value(p2, casearrivee)
            p2.H=x
            x=0
     
            p.colonnes=p2.colonnes
            p.lignes=p2.lignes
            value(casegarde, p2)
            p2.G=x
            x=0
     
            p2.F=p2.G + p2.H
            p2.parent=courant
            listeouverte.append(p2)
            listeF.append(p2.F)
            print(p2.H, p2.G, p2.F)
     
        #HautDroite
        p3.lignes=courant.lignes-1
        p3.colonnes=courant.colonnes+1
        p3.lincoln=p3.lignes, p3.colonnes
     
        if p3.lincoln not in listelincoln:
     
            listelincoln.append(p3.lincoln)
     
            p.colonnes=casearrivee.colonnes
            p.lignes=casearrivee.lignes
            value(p3, casearrivee)
            p3.H=x
            x=0
            p.colonnes=p3.colonnes
            p.lignes=p3.lignes
            value(casegarde, p3)
            p3.G=x
            x=0
     
            p3.F=p3.G + p3.H
            p3.parent=courant
            listeouverte.append(p3)
            listeF.append(p3.F)
            print(p3.H, p3.G, p3.F)
     
        #Gauche
        p4.lignes=courant.lignes
        p4.colonnes=courant.colonnes-1
        p4.lincoln=p4.lignes, p4.colonnes
     
        if p4.lincoln not in listelincoln:
     
            listelincoln.append(p4.lincoln)
     
            p.colonnes=casearrivee.colonnes
            p.lignes=casearrivee.lignes
            value(p4, casearrivee)
            p4.H=x
            x=0
     
            p.colonnes=p4.colonnes
            p.lignes=p4.lignes
            value(casegarde, p4)
            p4.G=x
            x=0
     
            p4.F=p4.G + p4.H
            p4.parent=courant
            listeouverte.append(p4)
            listeF.append(p4.F)
            print(p4.H, p4.G, p4.F)
     
     
        #BasGauche
        p5.lignes=courant.lignes+1
        p5.colonnes=courant.colonnes-1
        p5.lincoln=p5.lignes, p5.colonnes
     
        if p5.lincoln not in listelincoln:
     
            listelincoln.append(p5.lincoln)
     
            p.colonnes=casearrivee.colonnes
            p.lignes=casearrivee.lignes
            value(p5, casearrivee)
            p5.H=x
            x=0
     
            p.colonnes=p5.colonnes
            p.lignes=p5.lignes
            value(casegarde, p5)
            p5.G=x
            x=0
            p5.F=p5.G + p5.H
            p5.parent=courant
            listeouverte.append(p5)
            listeF.append(p5.F)
            print(p5.H, p5.G, p5.F)
     
        #HautGauche
        p6.lignes=courant.lignes-1
        p6.colonnes=courant.colonnes-1
        p6.lincoln=p6.lignes, p6.colonnes
     
        if p6.lincoln not in listelincoln:
     
            listelincoln.append(p6.lincoln)
     
        p.colonnes=casearrivee.colonnes
        p.lignes=casearrivee.lignes
        value(p6, casearrivee)
        p6.H=x
        x=0
     
        p.colonnes=p6.colonnes
        p.lignes=p6.lignes
        value(casegarde, p6)
        p6.G=x
        x=0
        p6.F=p6.G + p6.H
        p6.parent=courant
        listeouverte.append(p6)
        listeF.append(p6.F)
        print(p6.H, p6.G, p6.F)
     
        #Haut
     
        p7.lignes=courant.lignes-1
        p7.lignes=courant.colonnes
        p7.lincoln=p7.lignes, p7.colonnes
     
        if p7.lincoln not in listelincoln:
     
            listelincoln.append(p7.lincoln)
     
        p.colonnes=casearrivee.colonnes
        p.lignes=casearrivee.lignes
        value(p7, casearrivee)
        p7.H=x
        x=0
     
        p.colonnes=p7.colonnes
        p.lignes=p7.lignes
        value(casegarde, p7)
        p7.G=x
        x=0
        p7.F=p7.G + p7.H
        p7.parent=courant
        listeouverte.append(p7)
        listeF.append(p7.F)
        print(p7.H, p7.G, p7.F)
     
        #Bas
        p8.lignes=courant.lignes+1
        p8.lignes=courant.colonnes
        p8.lincoln=p1.lignes, p8.colonnes
     
        if p8.lincoln not in listelincoln:
     
            listelincoln.append(p8.lincoln)
     
            p.colonnes=casearrivee.colonnes
            p.lignes=casearrivee.lignes
            value(p8, casearrivee)
            p8.H=x
            x=0
     
            p.colonnes=p8.colonnes
            p.lignes=p8.lignes
            value(casegarde, p8)
            p8.G=x
            x=0
            p8.F=p8.G + p8.H
            p8.parent=courant
            listeouverte.append(p8)
            listeF.append(p8.F)
            print(p8.H, p8.G, p8.F)
     
     
        c=listeF.index(min(listeF)) #Ici, on trouve cherche la qualité la plus basse dans la liste F, et on note son index "c"
        print("c",c)
     
        print(listeouverte[c].colonnes, listeouverte[c].lignes)
        courant=listeouverte[c] #On fait de la case en position "c" la case courante: C'est la case ayant la qualité la plus faible, et donc celle dont on étudiera les voisins plus tard.
        listefermee.append(courant)
        print(courant.colonnes, courant.lignes)
     
        for i in range (0, len(listeouverte)): #Cette partie sert simplement à voir graphiquement les cases étudiées (vertes) et les cases choisies (rouges).
            drawzone.create_polygon(((listeouverte[i].colonnes-1)*50, (listeouverte[i].lignes-1)*50), ((listeouverte[i].colonnes)*50, (listeouverte[i].lignes-1)*50), ((listeouverte[i].colonnes)*50, (listeouverte[i].lignes)*50), ((listeouverte[i].colonnes-1)*50, (listeouverte[i].lignes)*50), fill="green" )
            drawzone.create_polygon((courant.colonnes-1)*50, (courant.lignes-1)*50, (courant.colonnes)*50, ((courant.lignes-1)*50), (courant.colonnes)*50, (courant.lignes)*50, (courant.colonnes-1)*50, (courant.lignes*50), fill="red")
        if courant.lignes != casearrivee.lignes or courant.colonnes != casearrivee.colonnes: #Si la case courant est la case d'arrivée, on met fin à la boucle. Sinon, on la répète.
            fen.after(500, chemin())
    Alors, je vous décris le soucis:
    Tout marche nickel chrome tant que je suis dans la partie gauche de l'écran, voir au dessus du token du joueur.
    Mais dès que je rentre dans la partie droite (donc si je suis techniquement plus loin que le joueur) il commence à me péter les plombs et à aller un peu n'importe où avant d'enfin arriver à la solution.

    J'avais déjà réglé un problème où il me faisait une boucle infinie dans ce cas précis, en rajoutant une vérification que vous reconnaîtrez sous le nom de "Lincoln" (lin-col + un peu de lol) et qui sert à vérifier qu'on ne repasse pas 2 fois sur le même point. Mais là...

    Auriez-vous une idée de ce qui se produit ?


    Le code que je vous ai filé est décomposé en deux parties:
    Une première def, qui calcule la qualité de la case en fonction de sa distance à un point donné (que ce soit la case de départ ou d'arrivée)

    Et une seconde, qui concentre une bonne partie du programme, et où vous pourrez trouver la définition et l'étude systématique des 8 cases qui entourent la case choisie par l'algorithme comme case courante.
    La case courante c'est le choix de l'algorithme sur le chemin à avoir, c'est une des étapes du chemin.
    Par exemple, la case garde est la première case à être considérée comme courante, elle fait partie du chemin.
    L'algorithme calcule ensuite la qualité de toutes les cases adjacentes, choisit la meilleure (celle qui offre le meilleur chemin: la qualité la plus basse) et en fait la case courante.
    Et on calcule ensuite la qualité de toutes les cases adjacentes du point courant, etc etc, jusqu'à arriver au point de destination.


    Je vais de ce pas tester une solution, je viens d'avoir une idée.
    Mais tant que j'y suis, je voudrais poser deux-trois petites questions:
    Est-il possible de checker si l'attribut d'un objet présent dans une classe est égale à l'attribut d'un objet externe à la classe ?

    Exemple, si j'ai des objets "Point" qui ont des attributs "X" et "Y"
    Supposons que j'ai:
    P1.X=5 ; P1.Y=2
    P2.X=3 ; P1.Y=1
    P3.X=7 ; P1.Y=5
    P4.X=1 ; P1.Y=3
    P5.X=5 ; P1.Y=8

    Et que je fait une liste listP=[P1, P2, P3, P4]

    Est-ce que je peux tester un truc du genre:
    if P5.X in listP.X ?



    En espérant que ce sera moins lourd à lire

Discussions similaires

  1. Aide requise sur "du code java"? (sur la documentation)
    Par corseb-delete dans le forum Général Java
    Réponses: 2
    Dernier message: 07/04/2008, 11h51
  2. [petit algorithme]Besoin d'aide
    Par Doom_aok dans le forum Mathématiques
    Réponses: 0
    Dernier message: 17/01/2008, 10h59
  3. BadImageExecption - Aide requise
    Par render-nick dans le forum C#
    Réponses: 1
    Dernier message: 22/01/2007, 19h05
  4. Besoin d'aide pour algorithme de traitement d'images
    Par Zenman94 dans le forum Algorithmes et structures de données
    Réponses: 13
    Dernier message: 07/04/2005, 14h31

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