TD 9

Rush Hour


Votre opinion sur le cours de ce lundi : Votre opinion sur le TD de la semaine dernière :

 Login :  Mot de passe :

Préambule

Création d'un projet dédié au TD9

  1. Lancez Visual Studio Code (VS Code par la suite), par exemple en exécutant la commande code dans le terminal, ou en cliquant sur un raccourci; la touche [Alt] fait apparaître / disparaître la barre du menu horizontale.
  2. Dans VS Code tapez la combinaison de touches [Ctrl]+[Shift]+[P] (ou [Alt]+[V] puis cliquez sur command Palette) puis tapez «java: create» dans la barre qui apparaît et sélectionnez Create Java Project et l'option No build tools.
  3. Une fenêtre s'ouvre et vous invite à choisir votre espace de travail.
  4. Indiquez le nom de votre projet (TD9) dans la barre de texte.

Activer assert dans votre machine virtuelle Java

Vérifier que les assert's sont activés en exécutant le programme TestAssert.java. En cas de problème, suivez la procédure ci-dessous dans Visual Studio Code: tapez la combinaison de touches [Ctrl]+[,] (la second touche c'est `virgule'), indiquez vm args dans la barre de recherche. L'item Java>Debug>settings: Vm Args apparaît avec une barre de texte dans laquelle vous devez écrire -ea (pour enable asserts).

Consignes de programmation

Nommez les classes, variables et méthodes exactement comme le demande l'énoncé.

Pour des questions relatives à la syntaxe de Java, consultez ce mémento.

Documentation

Pour obtenir la description d'une classe Java standard, consultez internet. Il suffit souvent d'effectuer une recherche en indiquant Java suivi du nom de la classe dont vous souhaitez la documentation (e.g. Java LinkedList ou Java Array).

La documentation officielle (internet) est ici : Java 11.


Avertissement : tout votre code doit être écrit dans le fichier TD9.java

Afin de minimiser les risques d'erreurs de manipulation lors des dépôts de fichiers, toutes les classes que vous avez à modifier sont réunies dans un même fichier TD9.java que vous devez déposer après chaque question.

On rappelle néanmoins qu'en dehors de circonstances exceptionnelles, on écrit plutôt des classes différentes dans des fichiers différents, tant pour la lisibilité du code que pour l'efficacité de la compilation.

Jeu Rush Hour et but du TD

Rush Hour est un jeu de la société Thinkfun dont le but consiste à dégager une voiture d'un embouteillage. Les véhicules se déplacent sur une grille 6x6, soit horizontalement, soit verticalement. Chaque véhicule occupe 2 ou 3 cases de long. Les véhicules ne peuvent pas sortir du plateau, à l'exception de la voiture rouge qui peut sortir par la droite du plateau ; c'est là le but du jeu. Voici un exemple de configuration de départ :

L'objectif de ce TD est d'écrire un programme qui trouve la solution d'un tel problème, en un minimum de déplacements.

Si vous souhaitez vous familiariser avec ce jeu, vous pouvez jouer par exemple ici.

À télécharger

Extraire le contenu du fichier src.zip dans le répertoire src du projet.

1. Représentation du problème

On adopte la représentation suivante du problème. Les 6 lignes sont numérotées de haut en bas, de 0 à 5, et les 6 colonnes de gauche à droite, de 0 à 5. La classe RushHour modélise un plateau de jeu général décrit par les cinq champs suivants :

Par convention, la voiture rouge est le véhicule d'indice 0 et de longueur 2.

L'état du plateau à un moment du jeu est représenté par un objet de la classe State qui contient les champs suivants :



Question 1.1 : Testez votre code en exécutant le fichier Test11.java.

Déposez le fichier TD9.java :

Le nom du fichier à déposer
Il faut se connecter avant de pouvoir déposer



Question 1.2 : Complétez les méthodes : Testez votre code en exécutant le fichier Test12.java.

Déposez le fichier TD9.java :

Le nom du fichier à déposer
Il faut se connecter avant de pouvoir déposer

2. Déplacements possibles

À partir de maintenant, on ne travaille plus que dans la classe RushHour.



Question 2 : Complétez la méthode LinkedList<State> moves(State s) qui détermine l'ensemble des états que l'on peut atteindre à partir de l'état s en effectuant un unique déplacement (d'une seule case). Cet ensemble est représenté par une LinkedList<State>, l'ordre dans cette liste n'étant pas important. Pour écrire cette méthode, servez-vous de la méthode boolean[][] free de la classe State qui indique quelles sont les cases du plateau qui sont libres et que vous avez écrite dans la section précédente.

Testez votre code en exécutant le fichier Test2.java.

Déposez le fichier TD9.java :

Le nom du fichier à déposer
Il faut se connecter avant de pouvoir déposer

3. Recherche d'une solution

On s'attaque maintenant à la recherche d'une solution, grâce à un parcours d'exploration des états du jeux.

3.1 Parcours en profondeur

On va commencer par implémenter un parcours en profondeur, qui représente la façon ``humaine'' de jouer.
Il y a deux idées pour cela



Question 3.1 : Complétez la méthode State solveDFS(State s) pour qu'elle réalise cet algorithme. Elle doit renvoyer l'état correspondant à une solution (celui où la voiture rouge est située immédiatement devant la sortie).

Testez votre code en exécutant le fichier Test31.java.

Déposez le fichier TD9.java :

Le nom du fichier à déposer
Il faut se connecter avant de pouvoir déposer

3.2 Parcours en largeur

On veut maintenant trouver la solution la plus courte (i.e. avec le moins de déplacement), pour cela on va utiliser une file.

Si on représente l'ensemble des états par un arbre dont la racine est l'état de départ et dont chaque noeud s a pour enfants les états que l'on peut atteindre à partir de s en effectuant un déplacement, on souhaite parcourir les noeuds de cet arbre « par niveaux », comme ceci :

                   1
                  / \
                 /   \
                2     3
              / | \   | \
             4  5  6  7  8
            /...


Question 3.2 : Complétez la méthode State solveBFS(State s) pour qu'elle réalise cet algorithme. Elle doit renvoyer l'état correspondant à une solution (celui où la voiture rouge est située immédiatement devant la sortie).

Testez votre code en exécutant le fichier Test32.java.

Déposez le fichier TD9.java :

Le nom du fichier à déposer
Il faut se connecter avant de pouvoir déposer

4. Affichage d'une solution

Question 4 : Compléter la méthode void printSolution(State s) qui affiche une solution, étant donné l'état s correspondant à la solution (l'état final). On note que les états formant la solution sont chaînés à partir de s en suivant le champ prev. On s'appliquera à afficher la solution dans le bon ordre.

Cette méthode doit également afficher le nombre total de déplacements. On pourra ajouter un champ statique nbMoves à la class RushHour pour cela.
On utilisera possiblement une version récursive pour ce faire.

Testez votre code en exécutant le fichier Test4.java, qui doit donner quelque chose comme :

46 déplacements
on déplace le véhicule bleu vers la droite
on déplace le véhicule noir vers la droite
on déplace le véhicule vert vers le haut
on déplace le véhicule rose vers le bas
....

Note : votre solution peut différer de celle-ci (cela dépend de la façon dont la liste est construite par moves) mais elle doit comporter le même nombre de déplacements (46).

Déposer le fichier TD9.java :

Le nom du fichier à déposer
Il faut se connecter avant de pouvoir déposer