Bonjour,

Dans le cadre de mes études d'ingénieur, je dois réaliser un programme qui génère un labyrinthe carré dont la densité de murs est donnée par l'entrée "densite" et dont la taille d'un coté est donnée par la variable "TAILLE".

J'ai développé les fonctions nécessaires à ce programme sous python 3.4, après exécution tout fonctionne à merveille. En revanche, l'objectif final de ce travail est de modéliser en 3D ce labyrinthe à l'aide du logiciel FreeCAD dont la version python est la 2.7. Lors du transfert, le programme a tourné dans le vide. Mon professeur m'a alors conseillé de vérifier mon code freeCAD, ce que je fis à l'aide d'une matrice que j'ai entrée à la main dans la console; le résultat était alors celui attendu. J'ai ensuite essayé d'exécuter mon programme sous python 2.7 pour voir si le résultat venait de là et j'ai alors eu le même problème que précédemment.

Après une longue recherche dans le code, la fonction qui "merde" est la fonction generer_grille(densite).

L'objectif de cette fonction est de générer une grille (liste de listes) dans laquelle la densité de murs est un entier entré par l'utilisateur compris entre 0 et 100, un espace vide est représenté par un 1 et un mur par un 0.

Pour les densités supérieures à 15, ce programme fonctionne comme un vers dans une pomme. La grille est initialement créée uniquement avec de 0 ( fonction grille-pleine(0)), on prend une coordonnée de départ au hasard et selon la position du point de départ on choisit de se déplacer soit à droite, gauche, bas ou haut; on affecte alors à la case la valeur de 1 et ainsi de suite. Si le vers tombe sur une case qu'il a déjà creusé, il est téléporté vers une autre afin de commencer un nouveau trou. La fonction s'arrête lorsque la densité de murs est atteinte.

Pour les densités inférieures à 15, les murs sont placés aléatoirement dans le labyrinthe vide.

Voici les fonctions

###############################

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
from random import *
TAILLE=10   #taille arbitraire
 
def grille_pleine(val):
    """ l'objectif de cette fonction est de generer une matrice TAILLE*TAILLE dont chaque case a la meme valeur val"""
    grille=[]
    for i in range(TAILLE):
        L=[]
        for j in range(TAILLE):
            L.append(val)
        grille.append(L)
    return grille
 
def position_alea():
    """ cette fonction renvoie l'abscisse et l'ordonnee d'un point choisi aleatoirement dans la grille """
    x=randint(0,TAILLE-1)
    y=randint(0,TAILLE-1)
    return x,y
 
def generer_grille(densite):
    """l'objectif de cette fonction est de generer une grille (liste de listes) dans laquelle la densite de murs est un entier entre par lutilisateur compris entre 0 et 100, un espace vide est represente par un 1 et un mur par un 0 """
    y,x=position_alea()                             # on choisit une case de depart au hasard
    if densite>=15:                  # Cette division en 2 cas permet de diminuer grandement le temps de calcul; la borne 15 a ete obtenue experimentalement car c'est pour cette valeur que la duree d'execution varie drastiquement
        grille=grille_pleine(0)                     # on cree une grille pleine de mur
        sommematrice=0                              # on initialise la valeur qui nous permettra de suivre l'evolution du nombre de cases vides creees au court de l'evolution de la fonction  
        espacevide=[]                               # on creer un liste regroupant les espaces vides
        while sommematrice<(TAILLE**2)*(1-(densite/100)):  #tant que l'on a pas atteint la densite de murs souhaitee             
            espacevide.append([y,x])                # on met a jour la liste des espaces vides
            if x==0:                                # si on se trouve sur la face ouest
                chemin=choice("d")                  # h pour haut, b pour bas, g pour gauche, d pour droite // choice("hbgd") permet de choisir au hasard une lettre entre h,b,g,d avec equiprobabilite
            elif x==TAILLE-1:                       # si on se trouve sur la face est
                chemin=choice("g")                  # cela pemet de diminuer le nombre de chemins sur les exterieurs
            elif y==0:                              # si on se trouve sur la face sud
                chemin=choice("b")
            elif y==TAILLE-1:                       # si on se trouve sur la face nord
                chemin=choice("h")            
            elif x==0 and y==0:                     # si on se trouve dans le coin nord ouest
                chemin=choice("bd")
            elif x==0 and y==TAILLE-1:              # si on se trouve dans le coin sud ouest 
                chemin=choice("hd")
            elif x==TAILLE-1 and y==0:              # si on se trouve dans le coin nord est
                chemin=choice("bg")
            elif x==TAILLE-1 and y==TAILLE-1:       # si on se trouve dans le coin sud est
                chemin=choice("gh")
            else:
                chemin=choice("hbgd")               # si on se trouve dans le coeur du labyrinthe
            if chemin=='d':
                x+=1
            elif chemin=='g':
                x+=-1
            elif chemin=='h':
                y+=-1
            elif chemin=='b':
                y+=1
            if grille[y][x]==1:                     # si la case est deja vide
                [y,x]=espacevide[randrange(len(espacevide))]            #on vient prendre les coordonnees d'un espace vide et on recommence a creuser            
            else:                                   # sinon elle devient une case vide
                grille[y][x]=1
                sommematrice+=1
    else:                                       # sinon on choisit de venir placer les murs aleatoirement dans la grille
        sommematrice=TAILLE**2
        grille=grille_pleine(1)                 # on vient creer une grille vide
        while sommematrice>(TAILLE**2)*(1-(densite/100)):  # tant que la densite souhaitee n'est pas atteinte, on continue
            x,y=position_alea()
            grille[x][y]=0
            sommematrice+=-1
    return grille
###############################################################

Je ne comprend pas d'où provient cette différence d'exécution entre les deux versions.
Pourriez vous m'aider à adapter ma fonction à la version 2.7 s'il vous plait.

Merci d'avance pour le temps de réflexion accordé.


Larry