diff --git a/minimax.py b/minimax.py
index bb6bebb..637bb88 100644
--- a/minimax.py
+++ b/minimax.py
@@ -1,80 +1,40 @@
-from math import sqrt # Utile pour avoir dynamiquement le nombre de cases a validé pour gagner une partie
+from math import sqrt, inf
+from random import choice
 
-class Minimax:
-    """Définition de l'algorithme minimax."""
-    def __init__(self, terminale: list, humain: str, ordinateur: str) -> None:
-        self.terminale = terminale
-        self.MIN = humain
-        self.MAX = ordinateur
-
-    def evaluation(self, nbAlign: list) -> list:
+class Morpion():
+    """Implémentation du Morpion."""
+    def __init__(self, joueurA: str = 'X', joueurB: str = 'O', taille: tuple = (3, 3)) -> None:
         """
-        `p` -> position
-
-        `nbAlign_i(p, J)` -> le nombre d'alignements réalisables, par le joueur `J`, pour lesquels il a déjà `i` symboles posés.
-
-        f(p) = (3.nbAlign_2(p, humain) + nbAlign_1(p, humain)) - (3.nbAlign_2(p, ordinateur) + nbAlign_1(p, ordinateur))
+        Initalise la classe Morpion :
+        - Par défaut :
+            - Le joueur A se nomme `X`.
+            - Le joueur B se nomme `O`.
+            - Le plateau à une taille `3x3`.
         """
-        pass
-
-    def terminale(self, etat: list) -> bool:
-        """Vrai si la partie est terminé."""
-        return etat in self.terminale
-
-    def casesVide(self, p: list) -> list: # c'est une liste de coordonées
-        """Renvoie la liste des cellules vides depuis un état."""
-        pass
-
-    def algorithme(self, n: int, p: list, j: str) -> list: # p state, n depth, j player
-        """Évaluation de `p` à une profondeur `n` (joueur j)."""
-        if self.terminale(p) or n == 0: # si p terminale ou n = 0
-            f = self.evaluation(p)
-        else: # = si n > 0
-            for Pm in self.casesVide(p):
-                x, y = Pm[0], Pm[1]
-                p[x][y] = j
-                score = self.main(p, n - 1, -j)
-                p[x][y] = 0
-                score[0], score[1] = x, y
-
-                if j == self.MAX:
-                    if score[2] > f[2]:
-                        f = score
-                else:
-                    if score[2] < f[2]:
-                        f = score
-
-        return f
-
-class Morpion(Minimax):
-    """
-    Implémentation de Minimax dans un Morpion.
-
-    Taille par défaut : `3x3`.
-
-    Joueur A est l'humain.
-
-    Joueur B est l'ordinateur.
-    """
-    def __init__(self, joueurA: str, joueurB: str, taille: tuple = (3, 3)) -> None:
+        if len(joueurA) != 1 or len(joueurB) != 1: # Gestion erreur nom des joueurs
+            print("Nom des joueurs invalide.")
+            return
         self.plateau: list = self._definitionPlateau(taille[0], taille[1])
         if len(self.plateau) == 0: # Gestion erreur du plateau
             print("Taille du plateau invalide.")
             return
-        self.nbCasesGagnantes = self._recuperationNbCasesGagnantes()
-        if len(joueurA) != 1 or len(joueurB) != 1: # Gestion erreur nom des joueurs
-            print("Nom des joueurs invalide.")
-            return
-        super().__init__(self._recuperationEtatsGagnants(), joueurA, joueurB)
-        self.joueurA = joueurA
-        self.joueurB = joueurB
-        self.gagnant = ''
+        self.nbCasesGagnantes = self._recuperationNbCasesGagnantes() # définit combien de cases les joueurs doivent aligner pour gagner
+        self.joueurA = joueurA # définit le joueur A
+        self.joueurB = joueurB # définit le joueur B
+        self.joueurActuel = choice([joueurA, joueurB]) # le joueur qui commence est choisi aléatoirement car le nom 'X' peut varier
+        self.gagnant = '' # à la fin, montre qui est le gagnant
+        """
+        Permet un bel affichage, la variable `tailleMaxCharactere` augmente en fonction de la taille du tableau et permet
+        de toujours avoir tout de centrer et tout de la bonne longueur
+        """
+        tailleMaxCharactere = len(str(self.plateau[-1][-1]))
+        self.tailleMaxCharactere = tailleMaxCharactere if tailleMaxCharactere % 2 != 0 else tailleMaxCharactere + 1
 
     def _definitionPlateau(self, x: int, y: int) -> list:
         """
-        Renvoie un plateau en fonction de dimensions `x` et `y`
+        Renvoie un plateau en fonction de dimensions `x` et `y`.
 
-        Valeur = int -> Cellule vide
+        Les cellules vides sont correspondent à leur "numéro de case".
         """
         if x <= 0 or y <= 0:
             return []
@@ -103,24 +63,20 @@ class Morpion(Minimax):
 
         return res
 
-    def _recuperationEtatsGagnants(self) -> list:
-        """Renvoie une liste de tous les états qui permettent de terminer la partie."""
-        self.plateau
-        pass
-
     def afficher(self) -> None:
         """Affiche le plateau."""
         print("\n" * 5) # petit espace par rapport à ce que le terminale de l'utilisateur à afficher dernièrement
-        espace = f"\n {'-' * len(self.plateau[0]) * 5}-" # taille des lignes qui séparent les valeurs du plateau
+        espace = f"\n {'-' * len(self.plateau[0]) * (3 + self.tailleMaxCharactere)}-" # taille des lignes qui séparent les valeurs du plateau
         for i in range(len(self.plateau)):
             print(f"{espace[1:] if i == 0 else espace}", end = "\n ") # on retire le saut de ligne à la première itération
             print("", end = "| ")
             for j in range(len(self.plateau[i])):
                 n = self.plateau[i][j]
                 if type(n) == int:
-                    print(f"{n:02d}", end = " | ") # on rajoute un "0" au chiffre < 10 (comme en C avec `%02d`)
+                    print(f"{n:0{self.tailleMaxCharactere}d}", end = " | ") # on rajoute un "0" au chiffre < 10 (comme en C avec `%02d`)
                 else:
-                    print("%02c" % n, end = " | ") # espace automatique pour pas décaler l'affichage (comme au dessus mais avec la syntaxe de python2)
+                    nombreEspaceRequis = (self.tailleMaxCharactere - 1) // 2
+                    print(f"{' ' * nombreEspaceRequis}{n}{' ' * nombreEspaceRequis}", end = " | ") # espace automatique pour pas décaler l'affichage
         print(espace)
 
     def _caseOccupee(self, x: int, y: int) -> bool:
@@ -211,9 +167,9 @@ class Morpion(Minimax):
         x, y = self._coordonneesCaseDepuisNumero(n)
         self.plateau[x][y] = joueur
 
-    def _demandeCase(self) -> int:
+    def _demandeCase(self, joueur) -> int:
         """Demande au joueur sur quelle case il veut poser sa pièce."""
-        prefix = f"({self.joueurA} - {self.nbCasesGagnantes} cases successives pour gagner)"
+        prefix = f"({joueur} - {self.nbCasesGagnantes} cases successives pour gagner)"
         print(f"{prefix} Entrez le numéro de case que vous voulez jouer : ", end = "")
         reponse = -1
         while int(reponse) < 0:
@@ -236,19 +192,82 @@ class Morpion(Minimax):
         return int(reponse)
 
     def gras(self, texte: str) -> str:
-        """Fonction qui renvoie le texte en argument en gras."""
+        """Fonction qui renvoie le texte en argument en gras.""" # source: https://stackoverflow.com/a/17303428
         return f"\033[1m{texte}\033[0m"
 
+    def _demandeCaseA(self) -> int:
+        """Demande au joueur A de jouer."""
+        return self._demandeCase(self.joueurA)
+
+    def _demandeCaseB(self) -> int:
+        """Demande au joueur B de jouer."""
+        return self._demandeCase(self.joueurB)
+
+    def _egalite(self) -> bool:
+        """Renvoie vrai si le plateau est plein."""
+        for i in range(len(self.plateau)):
+            for j in range(len(self.plateau[i])):
+                if not self._caseOccupee(i, j): # si case pas occupée par un joueur
+                   return False
+        return True
+
     def jouer(self) -> None:
         """Lance la partie de Morpion."""
-        while not self._terminer(): # tant que la partie n'est pas terminé
+        while not self._terminer() and not self._egalite(): # tant que la partie n'est pas terminé
             self.afficher() # affichage du plateau
-            reponse = self._demandeCase() # on demande où le joueur veut posé sa pièce
-            self._placementPiece(self.joueurA, reponse) # on place la pièce du joueur
-            # self._placementPiece(self.joueurB, self.algorithme())
+            if self.joueurActuel == self.joueurA:
+                self._placementPiece(self.joueurA, self._demandeCaseA()) # on place la pièce du joueur là où il veut
+                self.joueurActuel = self.joueurB
+            else:
+                self._placementPiece(self.joueurB, self._demandeCaseB()) # on place la pièce du joueur là où il veut
+                self.joueurActuel = self.joueurA
         self.afficher() # affichage du plateau final
-        print(f"🎉 Partie terminée, le {self.gras(f'joueur {self.gagnant}')} a gagné !")
+        if self._egalite():
+            print(f"😬 Partie terminée, {self.gras(f'égalité parfaite')}.")
+        else:
+            print(f"🎉 Partie terminée, le {self.gras(f'joueur {self.gagnant} a gagné')} !")
+
+class Minimax(Morpion):
+    """Définition de l'algorithme Minimax."""
+    def __init__(self, joueurA: str = 'X', joueurB: str = 'O', taille: tuple = (3, 3)) -> None:
+        """
+        Initalise la classe Minimax héritant du Morpion.
+        - Taille par défaut : `3x3`.
+        - Joueur A est l'humain.
+        - Joueur B est l'ordinateur.
+        """
+        super().__init__(joueurA, joueurB, taille = taille)
+
+    def _demandeCaseB(self) -> int:
+        """Utilise l'algorithme `Minimax` pour jouer le coup du joueur B."""
+        return self.minimax()
+
+    def minimax(self) -> list:
+        """
+        Fonction Minimax qui décide quel case est la plus intéressante.
+        """
+        return super()._demandeCaseB()
 
 if __name__ == "__main__": # Si on lance directement le fichier et on s'en sert pas comme module
-    Morpion('X', 'O').jouer() # On lance la partie à l'instanciation du Morpion
-    # Morpion('X', 'O', (4, 4)).jouer() # Si on veut lancer le morpion avec un plateau 4x4
+    """
+    J'ai fait 2 classes :
+    -> La classe Morpion permet de jouer au morpion entre deux humains.
+        -> Dans mon morpion :
+            -> `X` et `O` complètement personnalisable.
+            -> La taille du plateau peut s'étendre à l'infini.
+            -> Le joueur qui commence est choisit aléatoirement car `X` n'est pas obligatoirement le joueur A.
+            -> Pour rendre les parties avec de grands plateaux quand même intéréssant,
+               j'ai fait en sorte (avec la racine du côté le plus petit multiplié par 2)
+               de ne pas donner comme condition de victoire toutes une longueur ou une largeur
+               complété mais seulement un morceau. Ce morceau grossit en fonction de la taille du plateau.
+    -> La classe Minimax dépend de Morpion (mais elle peut être rataché à d'autre classe ce qui la rend extrêmement flexible)
+       et permet de remplacer le joueur B et ainsi jouer contre l'algorithme `Minimax`.
+
+    Minimax hérite donc des arguments de Morpion :
+    -> Pour configurer le morpion on peut lui donner :
+        -> Le nom du joueur A.
+        -> Le nom du joueur B.
+        -> Une taille de plateau (qui peut ne pas être identique, exemple : un plateau de 4x6).
+    -> Les noms de joueurs ne peuvent être que des string de un seule charactère (pour que l'affichage soit jolie).
+    """
+    Minimax().jouer() # On lance la partie à l'instanciation du Morpion