Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 128 additions & 21 deletions src/main/scala/labyrinthe/Jeu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,42 @@ object Jeu {
/** @param chemin un chemin de labyrinthe
* @return la position du joueur dans le labyrinthe selon le chemin donné
*/
def positionCourante(chemin: Chemin): Position = ??? // TODO
def positionCourante(chemin: Chemin): Position = {
chemin match
case x :: _ => x
}

/** @param p une position dans un labyrinthe
* @param chemin un chemin d'un labyrinthe
* @return true ssi la position p est la position courante du joueur selon le
* chemin donné.
*/
def estPositionCourante(p: Position, chemin: Chemin): Boolean = ??? // TODO
def estPositionCourante(p: Position, chemin: Chemin): Boolean =
p == positionCourante(chemin)

/** @param laby un labyrinthe
* @param chemin un chemin dans laby
* @return vrai ssi le chemin mène à la sortie de laby.
*/
def estResolu(laby: Labyrinthe, chemin: Chemin): Boolean = ??? // TODO
def estResolu(laby: Labyrinthe, chemin: Chemin): Boolean = {
chemin match
case x :: _ => x == sortieLabyrinthe(laby)
}

/** @param laby un labyrinthe
* @return le chemin initial, c'est-à-dire celui avec lequel on commence à jouer.
*/
def cheminInitial(laby: Labyrinthe): Chemin = ??? // TODO
def cheminInitial(laby: Labyrinthe): Chemin = entreeLabyrinthe(laby) :: Nil

/** @param chemin un chemin
* @return le chemin correspondant à l'annulation du dernier déplacement dans chemin,
* si des déplacements ont déjà été effectués.
*/
def annulerBouger(chemin: Chemin): Chemin = ??? // TODO
def annulerBouger(chemin: Chemin): Chemin = {
chemin match
case x :: Nil => chemin
case x :: y => y
}

/** Directions des déplacements dans un labyrinthe */
sealed trait Direction
Expand All @@ -67,7 +78,11 @@ object Jeu {
* @param d une direction
* @return la position voisine de pos, suivant direction
*/
def voisine(p: Position, d: Direction): Position = ??? // TODO
def voisine(p: Position, d: Direction): Position = (d, p) match
case (Nord, (x, y)) => (x - 1, y)
case (Sud, (x, y)) => (x + 1, y)
case (Est, (x, y)) => (x, y + 1)
case (Ouest, (x, y)) => (x, y - 1)

/** @param laby un labyrinthe
* @param p une position
Expand All @@ -88,15 +103,25 @@ object Jeu {
laby: Labyrinthe,
p: Position,
d: Direction
): Boolean = ??? // TODO
): Boolean = {
d match {
case Nord => laby.f(p) match { case Cellule(e, _) => e == Ouvert }
case Est => laby.f(p) match { case Cellule(_, e) => e == Ouvert }
case Sud =>
laby.f(voisine(p, d)) match { case Cellule(e, _) => e == Ouvert }
case Ouest =>
laby.f(voisine(p, d)) match { case Cellule(_, e) => e == Ouvert }
}
}

/** @param laby un labyrinthe
* @param p une position dans laby
* @return une liste de positions voisines accessibles depuis p dans laby
*
* @note utiliser directions, filter et map
*/
def voisines(laby: Labyrinthe, p: Position): List[Position] = ??? // TODO
def voisines(laby: Labyrinthe, p: Position): List[Position] =
directions.filter(y => passageOuvert(laby, p, y)).map(y => voisine(p, y))

/** @param laby un labyrinthe
* @param chemin un chemin dans le labyrinthe laby
Expand All @@ -108,15 +133,22 @@ object Jeu {
laby: Labyrinthe,
chemin: Chemin,
direction: Direction
): Chemin = ??? // TODO
): Chemin = if passageOuvert(laby, chemin.head, direction)
then (voisine(chemin.head, direction) :: chemin)
else (chemin)

/** @param p0 une position dans un labyrinthe
* @param p1 une position dans un labyrinthe
* @return la direction de déplacement de p0 vers p1
*
* @note indication de longueur : moins de 10 lignes
*/
def directionDeplacement(p0: Position, p1: Position): Direction = ??? // TODO
def directionDeplacement(p0: Position, p1: Position): Direction =
(p0._1 - p1._1, p0._2 - p1._2) match
case (-1, 0) => Nord
case (1, 0) => Sud
case (0, -1) => Ouest
case (0, 1) => Est

/** @param chemin un chemin
* @return la direction dans laquelle se déplace le joueur ayant suivi ce chemin,
Expand All @@ -127,7 +159,9 @@ object Jeu {
* @note indication de longueur : moins de 5 lignes
* @note utiliser la fonction directionDeplacement
*/
def sensDeplacement(chemin: Chemin): Direction = ??? // TODO
def sensDeplacement(chemin: Chemin): Direction = chemin match
case x :: y :: _ => directionDeplacement(x, y)
case _ => Est

/** @param laby un labyrinthe
* @param chemin un chemin dans le labyrinthe laby
Expand Down Expand Up @@ -156,7 +190,10 @@ object Jeu {
def etatLabyrinthe(
laby: Labyrinthe,
chemin: Chemin
): EtatLabyrinthe = ??? // TODO
): EtatLabyrinthe = p =>
if p == positionCourante(chemin) then Courante(Nil)
else if chemin.contains(p) then Visitee(Nil)
else NonVisitee

/* ======================================*/
/* RÉSOLUTION : recherche d'une solution */
Expand Down Expand Up @@ -193,7 +230,57 @@ object Jeu {
def bougeStrategieMainDroite(
laby: Labyrinthe,
chemin: Chemin
): Chemin = ??? // TODO
): Chemin = {
sensDeplacement(chemin) match
case Est =>
(
passageOuvert(laby, chemin.head, Sud),
passageOuvert(laby, chemin.head, Est),
passageOuvert(laby, chemin.head, Nord),
passageOuvert(laby, chemin.head, Ouest)
) match {
case (true, _, _, _) => bouge(laby, chemin, Sud)
case (_, true, _, _) => bouge(laby, chemin, Est)
case (_, _, true, _) => bouge(laby, chemin, Nord)
case _ => bouge(laby, chemin, Ouest)
}
case Nord =>
(
passageOuvert(laby, chemin.head, Est),
passageOuvert(laby, chemin.head, Nord),
passageOuvert(laby, chemin.head, Ouest),
passageOuvert(laby, chemin.head, Sud)
) match {
case (true, _, _, _) => bouge(laby, chemin, Est)
case (_, true, _, _) => bouge(laby, chemin, Nord)
case (_, _, true, _) => bouge(laby, chemin, Ouest)
case _ => bouge(laby, chemin, Sud)
}
case Ouest =>
(
passageOuvert(laby, chemin.head, Nord),
passageOuvert(laby, chemin.head, Ouest),
passageOuvert(laby, chemin.head, Sud),
passageOuvert(laby, chemin.head, Est)
) match {
case (true, _, _, _) => bouge(laby, chemin, Nord)
case (_, true, _, _) => bouge(laby, chemin, Ouest)
case (_, _, true, _) => bouge(laby, chemin, Sud)
case _ => bouge(laby, chemin, Est)
}
case Sud =>
(
passageOuvert(laby, chemin.head, Ouest),
passageOuvert(laby, chemin.head, Sud),
passageOuvert(laby, chemin.head, Est),
passageOuvert(laby, chemin.head, Nord)
) match {
case (true, _, _, _) => bouge(laby, chemin, Ouest)
case (_, true, _, _) => bouge(laby, chemin, Sud)
case (_, _, true, _) => bouge(laby, chemin, Est)
case _ => bouge(laby, chemin, Nord)
}
}

/** @param laby un labyrinthe parfait
* @param chemin un chemin dans le labyrinthe laby
Expand All @@ -206,7 +293,17 @@ object Jeu {
def resoudreParStrategieMainDroite(
laby: Labyrinthe,
chemin: Chemin
): Chemin = ??? // TODO
): Chemin = {
chemin match
case x :: _ =>
if (x == sortieLabyrinthe(laby)) then { chemin }
else {
resoudreParStrategieMainDroite(
laby,
bougeStrategieMainDroite(laby, chemin)
)
}
}

/** @param chemin un chemin d'un labyrinthe
* @return le chemin obetenu en enlevant les détours éventuels du chemin
Expand All @@ -221,7 +318,13 @@ object Jeu {
* @note Notre solution utilise la méthode span
* Cf. https://www.scala-lang.org/api/2.13.3/scala/collection/immutable/List.html#span(p:A=%3EBoolean):(List[A],List[A])
*/
def simplifie(chemin: Chemin): Chemin = ??? // TODO
def simplifie(chemin: Chemin): Chemin = chemin match
case x :: Nil => x :: Nil
case x1 :: x2 :: xs =>
val (pVrai, pFaux) = xs.span(_ != x1)
if (pFaux.isEmpty) then x1 :: simplifie(x2 :: xs)
else simplifie(pFaux)
case Nil => Nil

/** @param laby un labyrinthe parfait
* @param chemin un chemin dans le labyrinthe laby
Expand All @@ -236,7 +339,9 @@ object Jeu {
*
* @note utiliser les fonctions simplifie et resoudreParStrategieMainDroite
*/
def resoudre(laby: Labyrinthe, chemin: Chemin): Chemin = ??? // TODO
def resoudre(laby: Labyrinthe, chemin: Chemin): Chemin = simplifie(
resoudreParStrategieMainDroite(laby, chemin)
) ++ chemin

/** @param laby un labyrinthe parfait
* @param chemin un chemin valide dans le labyrinthe laby
Expand All @@ -249,7 +354,9 @@ object Jeu {
* peut être utile. xs.takeRight(n) renvoie les n derniers
* éléments de la liste xs.
*/
def indice(laby: Labyrinthe, chemin: Chemin): Chemin = ??? // TODO
def indice(laby: Labyrinthe, chemin: Chemin): Chemin = simplifie(
resoudre(laby, chemin).takeRight(chemin.length + 1)
)

/* RÉSOLUTION PAR FORCE BRUTE (Très difficile)
===========================================
Expand Down Expand Up @@ -285,7 +392,7 @@ object Jeu {
def etendreCheminJusquaArrivee(
laby: Labyrinthe,
chemin: Chemin
): Chemin = ??? // TODO
): Chemin = ??? // TODO

/** @param laby un labyrinthe parfait
* @param chemin un chemin dans le labyrinthe laby
Expand All @@ -303,7 +410,7 @@ object Jeu {
def resoudreForceBrute(
laby: Labyrinthe,
chemin: Chemin
): Chemin = ??? // TODO
): Chemin = ??? // TODO

/** @param laby un labyrinthe parfait
* @param chemin un chemin valide dans le labyrinthe laby
Expand All @@ -314,6 +421,6 @@ object Jeu {
*
* @note Utiliser la fonction resoudreForceBrute
*/
def indiceForceBrute(laby: Labyrinthe, chemin: Chemin): Chemin = ??? // TODO
def indiceForceBrute(laby: Labyrinthe, chemin: Chemin): Chemin = ??? // TODO

}
}
Loading