On utilise une grille pour représenter un labyrinthe.
Plus précisément, on modélise ici un labyrinthe par une liste de listes. 0 indique un passage, 1 indique un mur, 2 indique la sortie. L'entrée est dans les exemples ci-dessous en (0,0).
# un premier labyrinthe possible :
dedale = [
[0,1,1,1,1,1],
[0,0,1,1,1,1],
[1,0,1,1,1,1],
[1,0,1,0,0,0],
[0,0,0,0,1,2],
[0,0,0,1,1,1],
[1,1,1,1,1,1]
]
# un second labyrinthe possible :
dedale = [
[0,0,0,0,0,0,1,1,1,1],
[0,1,0,0,1,1,1,1,0,1],
[0,1,0,1,0,0,0,0,0,2],
[0,1,0,0,0,1,1,1,1,1],
[0,1,1,1,0,1,0,0,0,2],
[0,0,0,1,0,0,0,1,0,1]
]
Un robot entre en (0,0) et doit sortir seul du labyrinthe. Le robot sait détecter qu'une case est bouchée, le robot peut mémoriser le fait qu'une case a déjà été visitée, il peut se déplacer dans les 4 directions principales nord, est, ouest, sud.
Proposer une fonction python récursive pour faire sortir ce robot.
- principe
- un code
- à poursuivre
- Cas de base : le robot est sur une case marquée 2, c'est terminé.
- Sinon, le robot essaie d'abord le sud (par exemple !) : si cela le mène à une case qui elle-même peut mener jusqu'à la sortie, il continue. Sinon, il essaie l'est... puis le nord puis l'ouest.
Il ne faut pas oublier de marquer les cases déjà visitées pour éviter les allers-retours incessants ou les boucles.
On marque par un 3 les cases visitées.
La sortie est marquée 5 lors de sa visite (ce n'est pas nécessaire, ici c'est un choix pour l'affichage).
dedale = [
[0,0,0,0,0,0,1,1,1,1],
[0,1,0,0,1,1,1,1,0,1],
[0,1,0,1,0,0,0,0,0,2],
[0,1,0,0,0,1,1,1,1,1],
[0,1,1,1,0,1,0,0,0,2],
[0,0,0,1,0,0,0,1,0,1]
]
nbLignes = len(dedale)
nbColonnes = len(dedale[0])
def affiche_etat(ligne,colonne):
""" affiche l'état mur, ouvert ou sortie de la 'cellule' """
if dedale[ligne][colonne] == 1:
print('Mur aux coordonnées {},{}.'.format(ligne,colonne))
elif dedale[ligne][colonne] == 0:
print('Passage aux coordonnées {},{}.'.format(ligne,colonne))
elif dedale[ligne][colonne] == 2:
print('Sortie aux coordonnées {},{}.'.format(ligne,colonne))
def affiche_dedale(dedale):
""" affiche le labyrinthe """
print(' ', end = ' ')
for i in range(nbColonnes) : print('_', end = ' ')
print()
for l,ligne in enumerate(dedale) :
if l == 0 : print('\u2192', end = ' ')
else : print('|', end = ' ')
for e, element in enumerate(ligne) :
if element == 1 : print('X', end=" ")
elif element == 0 or element == 2 : print(' ', end=" ")
elif element == 3 : print( '\u2658', end = ' ')
else : print('\u2658', end=" ") # cas 5 : sortie visitée
if e == nbColonnes-1 :
if element != 2 and element != 5 : print('|', end = ' ')
else : print('\u2192', end = ' ')
print()
print(' ', end = ' ')
for i in range(nbColonnes) : print('\u0305', end = ' ')
print()
def deplacement(ligne,colonne, trace ):
if trace : affiche_etat(ligne,colonne)
if dedale[ligne][colonne] == 2 :
dedale[ligne][colonne] += 3
return True
elif dedale[ligne][colonne] == 1 : return False
elif dedale[ligne][colonne] == 3 : return False
else : dedale[ligne][colonne] = 3
# à partir d'une cellule, on essaie les quatre directions
# la première menant jusqu'à la sortie est retenue
if ligne < nbLignes-1 and deplacement(ligne+1, colonne, trace) : return True
if colonne > 0 and deplacement(ligne, colonne-1, trace) : return True
if ligne > 0 and deplacement(ligne-1, colonne, trace) : return True
if colonne < nbColonnes-1 and deplacement(ligne, colonne+1, trace) : return True
return False
print("Labyrinthe : ")
affiche_dedale(dedale)
print("Parcours du labyrinthe :\n ")
deplacement(0, 0, trace = True)
affiche_dedale(dedale)
On obtient (les cavaliers marquent les cases par lesquelles le robot est passé) :
_ _ _ _ _ _ _ _ _ _ → ♘ ♘ ♘ X X X X | | ♘ X ♘ X X X X X | | ♘ X ♘ X → | ♘ X ♘ ♘ ♘ X X X X X | | ♘ X X X ♘ X ♘ ♘ ♘ ♘ → | ♘ ♘ ♘ X ♘ ♘ ♘ X ♘ X | ̅ ̅ ̅ ̅ ̅ ̅ ̅ ̅ ̅ ̅
Dans le cadre d'un projet, il resterait beaucoup à faire :
- Tracer le chemin menant de l'entrée à la sortie.
- Lorsque plusieurs chemins de sortie existent, trouver le plus court.
- Tester d'autres algorithmes de résolution, comparer leurs complexités.
- Ajouter une interface graphique pour représenter le labyrinthe et le chemin de sortie.
- Générer de façon automatique de nouveaux labyrinthes.
- etc...