Étape 2 : Création du labyrinthe
Le principe
Il faut imaginer cette grille comme un graphe, où chaque sommet est une case reliée à ses voisines par un mur.
Toutes les cases ont 4 voisines sauf celles du bord qui n'en n'ont que 2 ou 3.
On fait un parcours en profondeur de ce graphe en utilisant la boucle draw()
Dans le setup()
current<-- la case 0p(une pile) <---current
Dans le draw() ( qui est une boucle )
On note
currentcomme visitéeOn la met en bleu
voisines<--- la liste de ses voisines non déjà visitéesSi
voisinesn'est pas une liste vide :next<--- l'une d'entre ellesp<---nextOn élimine le mur entre
currentetnextcurrent<---next
Sinon :
Si la pile n'est pas vide :
On dépile
pdanscurrent
Sinon : on a terminé
Méthode : Mise en œuvre
Il nous faudra une classe Pile : ( à récupérer et à écrire dans un nouvel onglet de maze_generator).
Il faudra rajouter un attribut de classe à la classe Cell pour noter le fait qu'une case est visitée ou pas.
# coding=utf-8 (nécessaire dans Processing)class Cell:
def __init__(self,j,i,w=30):
self.i=i
self.j=j
self.w=w
self.walls=[True,True,True,True]
self.visited=False
Il faudra modifier la méthode show
Si la case a été visitée, on change sa couleur.
def show(self):
''' '''x=self.i*self.w
y=self.j*self.w
w=self.w
stroke(255)
if self.walls[0]:
line(x,y,x+w,y)
if self.walls[1]:
line(x+w,y,x+w,y+w)
if self.walls[2]:
line(x+w,y+w,x,y+w)
if self.walls[3]:
line(x,y+w,x,y)
if self.visited:
noStroke()fill(255,0,255,100)
rect(x,y,w,w)
Voilà le setup()
grid=[]p=Pile()
w=40 # dimension(on peut modifier)
def setup():
''' '''size(610,410)
global cols,rows,current # déclarées comme globales
#global currentcols=width//w
rows=height//w
#creation du tableaufor j in range(rows):
for i in range(cols):
cell=Cell(j,i,w)
grid.append(cell)
current=grid[0]
p.empiler(current)
frameRate(30)#vitesse (max 60)
Voici la méthode de la classe Cell qui permet de calculer l'indice d'une case à partir de ses coordonnées.
def index(self,i,j):
w=self.w
cols=int(width/w)
rows=int(height/w)
if (i < 0 or j < 0 or i > cols-1 or j > rows-1):
return -1
else:return j*cols + i
Voici la fonction qui efface le mur entre deux cases.
def removeWalls(a,b):
''' efface le mur entre a et b '''x=a.i-b.i
if x==1:
a.walls[3]=False
b.walls[1]=False
elif x==-1:
a.walls[1]=False
b.walls[3]=False
y=a.j-b.j
if y==1:
a.walls[0]=False
b.walls[2]=False
elif y==-1:
a.walls[2]=False
b.walls[0]=False
À faire : Expliquer le principe de cette fonction.
Voici la méthode de la classe Cell qui permet de récupérer la liste des indices des voisines d'une case
Cette méthode utilise la fonction index ( donc attention si par hasard vous avez placé les classes dans des fichiers séparés...)
def checkVoisin(self):
''' renvoie la liste des numéros des cases voisines ''' voisins=[]top_case = self.index(self.i,self.j-1)
right_case = self.index(self.i+1, self.j)
bottom_case = self.index(self.i, self.j+1)
left_case =self.index(self.i-1, self.j)
if top_case!=-1:
voisins.append(top_case)
if right_case!=-1:
voisins.append(right_case)
if bottom_case!=-1:
voisins.append(bottom_case)
if left_case!=-1:
voisins.append(left_case)
return voisins
Voici la fonction qui transforme la liste des indices des voisines en liste de voisines non visitées
def voisinage(liste):
''' renvoie la liste des voisines non visitées ''' neighbors=[]for vois in liste:
if grid[vois].visited==False:
neighbors.append(grid[vois])
return neighbors
Simulation : Le draw() pour terminer
Il vous reste à écrire ce qu'il faut dans le draw...
Pour terminer le programme (une fois le labyrinthe créé) il suffit d'écrire l'instruction noLoop()
def draw():
''' fonction qui boucle (par defaut 60 fois/seconde) '''global current,next
background(51)
for i in range(len(grid)):
grid[i].show()
current.highlight()
# à compléter




