# Situation

class `Situation.``Situation`(liste_voiture)
  Variables

    - liste_voiture (list) – La liste de voitures

    - grille (list) – La grille représentant une situation

  `__init__`(liste_voiture)

    Constructeur de la classe.

    Paramètres

      liste_voiture (list) – Une liste de voiture

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>> situation = Situation([a,b,c,x])
        >>> len(situation.liste_voiture)
        4

  `__eq__`(situation)

    Indique l’égalité ou non entre 2 situations.

    On condisère que 2 situations sont identiques si leur liste de voitures sont identiques.

    La méthode retourne donc :

    - `True` : Les deux situations ont la même liste de voitures

    - `False` : Les deux situations ont des listes de voitures différentes

    Paramètres

      situation (Situation) – Une situation

    Type renvoyé

      `boolean`

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>> from Direction import Direction
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation_1= Situation([a,b,c,x])
        >>> situation_2= Situation([c,b,a,x])
        >>> situation_3 = Situation([c,b])
        >>> situation_1 == situation_2
        True
        >>> situation_1 == situation_3
        False

  `afficher`()

    Affiche la grille d’une situation

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation = Situation([a,b,c,x])
        >>> situation.afficher()
        [A][A][ ][ ][ ][ ]
        [ ][ ][ ][ ][ ][ ]
        [ ][X][X][ ][ ][ ]
        [ ][ ][ ][ ][ ][ ]
        [ ][ ][ ][ ][B][B]
        [ ][ ][C][C][C][ ]

  `est_gagnante`()

    Indique si la situation est gagnante.

    - `True` : La voiture « XX » est aux coordonées [4;2]

    - `False` : La voiture « XX » n’est pas en [4:2]

    Type renvoyé

      `boolean`

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>> from Direction import Direction
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation = Situation([a,b,c,x])
        >>> situation.est_gagnante()
        False
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(4,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation = Situation([a,b,c,x])
        >>> situation.est_gagnante()
        True

  `generer_grille`(liste_voiture)

    Génère la grille représentant la situation. Cette méthode est appelée par le constructeur. Elle est composée de :

    - `Voiture`

    - `CaseVide`

    Paramètres

      liste_voiture (list) – Une liste de voiture

    Type renvoyé

      `list(list())`

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation = Situation([a,b,c,x])
        >>> situation.grille is not None
        True

  `get_case_vide`()

    Retourne la liste des cases vides d’une situation

    Type renvoyé

      `list(CaseVide)`

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation = Situation([a,b,c,x])
        >>> [(c.x,c.y) for c in situation.get_case_vide()]
        [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 1), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (5, 0), (5, 1), (5, 2), (5, 3), (5, 5)]

  `get_liste_voiture`()

    Retourne la liste des voitures triées par ordre alphabétique.

    Type renvoyé

      `list(Voiture)`

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation = Situation([a,b,c,x])
        >>> [x.lettre for x in situation.get_liste_voiture()]
        ['A', 'B', 'C', 'X']

  `get_mouvements_possibles`()

    Retourne la liste des mouvements possibles d’une situation. Un mouvement est possible quand :

    - une case vide est voisine avec une voiture

    - la case vide est dans un sens adéquat permettant le déplacement d’une voiure

    Type renvoyé

      `list(Mouvement)`

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation = Situation([a,b,c,x])
        >>> situation.afficher()
        [A][A][ ][ ][ ][ ]
        [ ][ ][ ][ ][ ][ ]
        [ ][X][X][ ][ ][ ]
        [ ][ ][ ][ ][ ][ ]
        [ ][ ][ ][ ][B][B]
        [ ][ ][C][C][C][ ]
        >>> [ (m.voiture.lettre,m.direction.name) for m in situation.get_mouvements_possibles()]
        [('X', 'GAUCHE'), ('C', 'GAUCHE'), ('A', 'DROITE'), ('X', 'DROITE'), ('B', 'GAUCHE'), ('C', 'DROITE')]

  `get_mouvements_solution`(arbre)

    Retourne la liste ordonée des mouvements à faire pour résoudre le Rush Hour.

    Cette liste de listes est de la forme [ [<mouvement_à_faire>, <occurence>]].

    Paramètres

      arbre (Arbre) – Un arbre ayant comme noeux la situation gagnante

    Type renvoyé

      `list(list())`

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>> from Direction import Direction
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation= Situation([a,b,c,x])
        >>> arbre = situation.resoudre()
        >>> [ (m[0].info(),m[1]) for m in situation.get_mouvements_solution(arbre)]
        [({'voiture': 'X', 'direction': 'Direction.DROITE'}, 3)]

  `get_situations_suivantes_possibles`()

    Retourne la liste des situations suivantes possibles après avoir effectué un seul mouvement.

    Cette liste de tuple est de la forme [ (situation_suivante_possible,mouvement_effectué) ]

    Type renvoyé

      `list(tuple())`

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>> from Direction import Direction
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation = Situation([a,b,c,x])
        >>> situation.get_situations_suivantes_possibles()

  `resoudre`()

    Trouve la situation gagnante du Rush Hour.

    Cette méthode génère toutes les situations possibles et construit un arbre au fur et à mesure.

    Chaque noeud de l’arbre est un tuple de la forme ( <situation>,<mouvement_effectue> ).

    La profondeur d’un noeud de l’arbre correspond au nombre de coups nécessaires pour atteindre la situation.

    Un parcours en largeur est effectué pour trouver la situation gagante.

    Type renvoyé

      `Arbre`

        >>> from Sens import Sens
        >>> from Taille import Taille
        >>> from Voiture import Voiture
        >>> from Direction import Direction
        >>>
        >>> a = Voiture(0,0,"A", Sens.HORIZONTAL, Taille.DEUX)
        >>> b = Voiture(4,4,"B", Sens.HORIZONTAL, Taille.DEUX)
        >>> c = Voiture(2,5,"C", Sens.HORIZONTAL,Taille.TROIS)
        >>> x = Voiture(1,2,"X",Sens.HORIZONTAL,Taille.DEUX)
        >>>
        >>> situation= Situation([a,b,c,x])
        >>> arbre = situation.resoudre()
        >>> type(arbre)
        <class 'Arbre.Arbre'>