Université des Sciences et Technologies de Lille
Licence Miage - Programmation 1 - TP




Parcours de labyrinthe



Le problème est le suivant. Vous êtes dans un labyrinthe. L'entrée se trouve, par exemple, en haut à gauche, en (1,1), et la sortie en bas à droite. On veut à partir de l'entrée trouver un chemin qui mène à la sortie. Quatre directions sont autorisées : haut, bas, droite et gauche. Une solution est figurée avec des points.
                                   . #############
                                   .# ##....     #
                                   .. # .##. # ###
                                   #..... #......
                                   #  #  #######.#
                                   ######........#
                                   #     .########
                                   ##### .........

Un algorithme pour le labyrinthe

Construire un chemin libérateur dans le labyrinthe repose sur un algorithme de backtracking. On se place à l'entrée du labyrinthe, en (1,1), et on essaye la première direction autorisée. Disons, à droite. On se place en (2,1) et on stocke l'information (2,1) dans une pile. À partir de (2,1), on essaye toutes les directions possibles, par où le chemin n'est pas déjà passé : il n'y en a aucune. Le choix (2,1) était donc un mauvais choix, que l'on remet en cause en revenant sur ses pas jusqu'à la position (1,1) et en dépilant (2,1). De (1,1), on essaye maintenant la direction autorisée suivante, vers le bas, en (1,2). On empile (1,2), et on y va. De (1,2), la première direction autorisée est de nouveau vers le bas, en (1,3). On empile (1,3) et on s'y place. De (1,3), la première direction autorisée est vers la droite. On empile (2,3), et ainsi de suite. Si on arrive à une position bouchée, on remonte dans le chemin en dépilant un élément, et on essaye la direction suivante. Le procédé s'arrête quand on a trouvé la sortie, ou quand la pile est vide. Dans ce dernier cas, cela signifie que l'on a essayé tous les chemins en vain. Le labyrinthe est sans issue. Si au contraire la pile n'est pas vide, celle-ci indique un chemin de l'entrée vers la sortie.

Implémentation

Un squelette de programmation pour ce problème est disponible dans le répertoire
         ~touzet/ADA/Labyrinthe
Les fichiers paq_pile_gen.ad* contiennent un paquetage générique pour la gestion de piles. Le fichier laby.adb concerne la construction d'un chemin dans un labyrinthe. Il contient d'ores et déjà la définition des types Labyrinthe et Position, ainsi que la fonction Initialiser. Les fichiers lab1, lab2, ...sont des fichiers textes, avec des exemples que vous pourrez utiliser pour tester le programme.


La fonction Initialiser lit un labyrinthe dans un fichier texte, et le charge dans un tableau de type Labyrinthe. Une manière simple de délimiter les contours du labyrinthe est d'ajouter une rangée de murs en bas, en haut, à gauche et à droite. C'est-à-dire qu'un labyrinthe de 4× 4 est représenté par un tableau de 6 × 6. C'est ce que fait la fonction Initialiser.


Question 1. Pour construire le chemin, vous avez besoin d'une pile dont les éléments sont de type Position. Un paquetage générique vous est fourni, paq_pile_gen. Utilisez-le pour définir le type Pile dans laby.adb.


Question 2. Compléter la procédure Afficher(L:in Labyrinthe; Chemin:in Pile), qui affiche un labyrinthe avec un chemin, sur le modèle de la figure de l'énoncé. Pensez-bien que vous ne disposez pour cela que des instructions put et put_line.


Question 3. Compléter la procédure Trouver_chemin qui construit un chemin libérateur de Entree à Sortie dans le labyrinthe L et le mémorise dans Chemin. Pour cette procédure, pensez à définir, en plus du labyrinthe, un second tableau de booléens pour mémoriser les cases par lesquelles vous êtes déjà passé.