On peut, en première approximation, représenter un labyrinthe sur une telle grille par un arbre : une pièce est reliée à une pièce voisine (graphe non-orienté) s'il y a une ouverture entre les deux. Le fait de prendre un arbre permet de garantir les deux propriétés suivantes :
On pourrait considérer des labyrinthes plus généraux, mais cette restriction suffira pour le TP...
L'archive contenant les fichiers necessaires pour le TP se trouve ici : http://www.lama.univ-savoie.fr/~hyvernat/Enseignement/0809/info505/tp.tgz .
Vous disposez en plus de deux fichiers labyrinthes.h et labyrinthes.h qui contiennent des définitions supplémentaires :
LARGEUR
et HAUTEUR
: c'est la taille de la grille
Tile
: un trucs entre les piles et les files. On peut insérer un élément en tête de structure et on peut récupérer soit le premier (comme dans une pile) soit le dernier (comme dans une file). On peut stocker des arcs (avec un but
, une origine
et un poids
), mais on peut également s'en servir pour stocker juste une valeur entière. (C'est juste qu'on n'utilise pas tous les champs.)
labyrinthes.c
contient, entre autre, la définition de la fonction grillePleine
: cela permet d'initialiser le graphe qui contient des passages entre toutes les pièces. Le graphe est non-orienté avec des poids aléatoires. Toutes les listes d'adjacences sont triées par ordre de poids croissant.
void afficheGrille(GrapheListe)
qui affiche un graphe sous forme de labyrinthe dans une grille.
Le graphe doit comporter exactement LARGEUR * HAUTEUR
sommet, et ne doit avoir que des arêtes entre des sommets k et :
LARGEUR
(case en bas) LARGEUR
(case en haut) Voici un exemple d'affichage pour un labyrinthe intéressant :
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | | | | | | | | | +--+--+ +--+ +--+ + + +--+ + + + +--+ +--+--+ + + + + | | | | | | | | | | | + + + + +--+--+--+--+ + + +--+--+ +--+ +--+ + +--+--+--+ | | | | | | | | | | | | | +--+--+--+--+ + +--+--+--+--+ + + + +--+ +--+ + +--+ +--+ | | | | | | | | | + +--+ + +--+--+--+--+ + +--+--+ + +--+--+ +--+--+ +--+ + | | | | | | | | | | | + +--+--+--+ + +--+ + +--+--+ +--+ +--+ + +--+ + + + + | | | | | | | | | | | | | | | + + +--+--+ + + + + +--+ + + +--+ + +--+ + +--+ +--+ | | | | | | | | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Tile
.
Pour pouvoir afficher le labyrinthe directement, vous remplacerez le tableau pere
par un GrapheListe
vide, auquel vous rajouterez les arêtes parcourues.
Testez et comparez les labyrinthes obtenus par cette méthode et la méthode précédente.
Comme les grilles pleines contiennent des arcs de poids aléatoire, une autre manière d'obtenir un labyrinthe est de chercher un arbre couvrant de poids minimal.
Utilisez l'algorithme de Kruskal (ou de Prim, au choix) pour chercher un tel arbre couvrant, et affichez le.
Comparez les labyrinthes obtenus par les 3 méthodes...
(a,b)
vers une case (c,d)
. Si un tels chemin existe, affichez le labyrinthe avec une solution optimale.