le jeu du taquin est constitué de 8 tuiles numérotées de 1 à 8 qui peuvent glisser verticalement ou horizontalement dans la direction de la place vide
Le but est de réarranger les tuiles dans l'ordre croissant,en partant de la situation initiale vers la situation finale comme on peut le voir ci-dessus
Le projet consiste à implémenter une IA pour un jeu du taquin ayant n*n - 1 tuiles pour n compris entre 2 et 128
Ce projet s'inspire d'un projet "Slider Puzzle" en Java de Sedgewick et Wayne
La classe Plateau est définie dans un fichier plateau.py
La classe Plateau modélise l'évolution du plateau de jeu
Voici l'API de la classe Plateau qu'il faudra implémenter en respectant les consignes ci-dessous
Toutes les méthodes devront être spécifiées et testées (avec doctest )
class Plateau:
def __init__(self,n:int):
"""
constructeur
"""
pass
def __str__(self)->str:
"""
représentation du plateau
"""
pass
def hamming(self)->int:
"""
distance de hamming
"""
pass
def manhattan(self)->int:
"""
distance de manhattan
"""
pass
def est_solution(self)->bool:
"""
retourne vrai si le plateau est solution
"""
pass
def est_egal(self,other)->bool:
"""
retourne vrai si self est le même plateau que other
"""
pass
def voisins(self)->list:
"""
retourne la liste des voisins de self
"""
pass
Définir le constructeur
le constructeur reçoit en paramètre n un entier égal au côté du plateau carré, avec 2 <= n <= 128
Il faudra filtrer l'entrée du constructeur en gérant l'erreur si n n'est pas un entier vérifiant 2 <= n <= 128 (voir TP )
La classe Plateau a deux attributs:
Définir la méthode __str__() qui donne une réprésentation du plateau sous forme d'une chaîne de caractères
La distance de manhattan entre deux points est la somme des décalages verticaux et horizontaux pour passer d'un point à l'autre
Par exemple sur l'image ci-dessous la distance manhattan entre A et B est de 5
Définir deux méthodes hamming() et manhattan() qui mesurent la distance entre le plateau actuel et la solution
Pour définir ces distances nous avons besoin d'un repère, défini par la numérotation des cases du plateau par i + j*n + 1 avec i indice de ligne et j indice de colonne dans le tableau 2D tableaux2
Définir la méthode voisins() qui retourne la liste des plateaux voisins du plateau self
Suivant la position de l'emplacement vide un plateau a 2, 3 ou 4 voisins
Pour définir l'IA nous avons besoin d'un outil appelé permutation
Regardons les tuiles comme des personnes dans une pièce à qui on demande de se déplacer pour arriver à la solution
On choisit un repèrage absolu (peut-on faire un repèrage relatif ?)
Ou encore imaginons que l'on peut "libérer" les tuiles de toute contrainte de déplacement, ainsi la façon la plus rapide de passer de l'état actuel du plateau à la solution est
On note le tableau de valeurs de cette fonction p de déplacement relativement au repère choisi sous cette forme
0 1 2 3 4 5 6 7 8
6 0 1 3 4 2 5 7 8
ce qui signifie p(1) = 0, p(2) = 1, etc...
Pour comprendre ce que signifie cette notion regardons les images successives de 1
1 -> 0 -> 6 -> 5 -> 2 -> 1
On revient ensuite en 1
On dit qu'on a une permutation circulaire qu'on note (1 9 6 5 2) et on dit qu'elle a pour longueur 5
Autrement dit on peut écrire p = (1 0 6 5 2) = (0 6 5 2 1)
Peut on savoir uniquement à partir de cette information qu'il y a une solution? Comment trouver la suite de coups de la solution ?
On transforme le plateau de jeu en une file comme expliqué dans l'article suivant
Voir iciOn a disposé la file de telle sorte que tout déplacement d'une tuile vers la case vide qui n'est pas dans le sens de la file fait "gagner ou perdre un nombre pair de places" à cette tuile dans la file
Il y a donc un invariant pour n'importe quel mouvement sur le plateau, c'est la parité du nombre d'inversions
Un plateau donné pourra être transformé en plateau solution si le nombre d'inversions associé à chaque file a la même parité
Pour n = 2 il y a 4! = 24 dispositions différentes pour le plateau et chaque configuration a exactement deux voisins dans le graphe du jeu
On observe deux parties distinctes du graphe (deux composantes connexes) chacune ayant 12 éléments
On observe que la solution est dans une des composantes connexes
On observe que l'échange de deux tuiles voisines (aucune des deux n'est vide) fait changer de composante connexe
On admettra que ces observations restent vraies quelque soit la valeur de n >= 2
Les observations précédentes nous donnent l'idée d'un algorithme pour une IA pour le jeu du taquin