Aller au contenu

Tours de Hanoi POO et UI

But du projet

Ce projet de difficulté intermédiaire a pour but de proposer une version graphique de la résolution du problème des tours de Hanoï, en utilisant une librairie graphique et une modélisation à l'aide de classes Python. Je recommande :

  • La librairie pyxel. C'est la librairie qui sera utilisée lors de l'événement La Nuit du Code à la fin de l'année. Si vous souhaitez participer à cette événement, alors cela peut-être l'occasion de vous familiariser avec l'utilisation de cette librairie. Des tutoriels sont disponibles sur le site de La Nuit du Code.
  • p5 pour Python. Le site The Coding Train ainsi que la chaine youtube associée regorgent de tutoriels et d'exemples de mini projets dont vous pouvez vous inspirer.
  • La librairie pygame. Probablement la librairie la plus complète (ça n'est pas forcément un avantage).

Description du projet

Une organisation possible pour ce projet est de créer une classe par "élément" du jeu des tours de Hanoï. Ainsi, on créera une classe Pilier, une classe Disque, et enfin une classe Jeu qui contiendra toutes les instances des variables de type Pilier et Disque créées. La classe Jeu sera responsable de l'affichage des différents éléments du jeu, ainsi que de déterminer la liste des coups permettant de le résoudre. Dans un premier temps, aucune animation ne sera effectuée, on se contentera d'afficher tous les éléments du jeu les uns après les autres à chaque frame.

La classe Disque

Attributs

On pourra éventuellement utiliser tout ou partie des attributs suivants de la classe Disques :

  • pos : (int, int)

    Représente les coordonnées (x, y) du coin inférieur gauche du disque.

  • numero : int

    Représente le numéro du disque. Le disque numéro 0 est le plus petit, plus le numéro d'un disque est élevé, plus le disque est grand.

  • largeur : int

    Représente la largeur du disque. Peut être calculé à l'aide de son numéro.

  • hauteur : int

    Représente la hauteur du disque. Peut être fixé à l'avance.

  • couleur

    Type à déterminer suivant la librairie utilisée. Représente la couleur du pilier.

Méthodes

On pourra éventuellement coder tout ou partie des méthodes suivantes de la classe Disque :

  • affiche(self: Disque) -> NoneType

    Affiche le disque : c'est un rectangle dont le coin inférieur gauche a pour coordonnées (x, y) et le coin supérieur droit a pour coordonnées (x + largeur, y + hauteur), si (x, y) = pos et que le pilier a pour largeur largeur et pour hauteur hauteur.

La classe Pilier.

Attributs

On pourra éventuellement utiliser tout ou partie des attributs suivants de la classe Pilier :

  • pos : (int, int)

    Représente les coordonnées (x, y) du coin inférieur gauche du pilier.

  • largeur : int

    Représente la largeur du pilier.

  • hauteur : int

    Représente la hauteur du pilier.

  • couleur

    Type à déterminer suivant la librairie utilisée. Représente la couleur du pilier.

  • disques : [Disque]

    Liste des disques présents sur le pilier. Le disque à la base du pilier est le disque d'indice 0, le disque au sommet du pilier est le disque d'indice maximal dans la liste.

Méthodes

On pourra éventuellement coder tout ou partie des méthodes suivantes de la classe Pilier :

  • affiche(self: Pilier) -> NoneType

    Affiche le pilier : c'est un rectangle dont le coin inférieur gauche a pour coordonnées (x, y) et le coin supérieur droit a pour coordonnées (x + largeur, y + hauteur), si (x, y) = pos et que le pilier a pour largeur largeur et pour hauteur hauteur.

  • deposer(self: Pilier, disque: Disque) -> NoneType

    Ajoute un disque à la liste self.disques.

  • retirer(self: Pilier) -> Disque | NoneType

    Renvoie le disque présent au sommet du pilier. Si aucun disque n'est présent sur le pilier, renvoie None. Supprime le disque retiré de la liste self.disques.

La classe Jeu

Attributs

On pourra éventuellement utiliser tout ou partie des attributs suivants de la classe Jeu :

  • pos : (int, int)

    Représente les coordonnées (x, y) du coin inférieur gauche du jeu.

  • largeur : int

    Représente la largeur du jeu.

  • hauteur : int

    Représente la hauteur du jeu.

  • piliers : [Pilier]

    La liste des piliers du jeu.

  • disques : [Disque]

    La liste des disques du jeu.

Méthodes

On pourra éventuellement coder tout ou partie des méthodes suivantes de la classe Jeu :

  • affiche(self: Jeu) -> NoneType

    Affiche tous les éléments du jeu : à la fois les piliers et les disques.

  • genere_disques(self: Jeu, n: int) -> NoneType

    Créé n disques de taille croissante et les ajoute dans le bon ordre au premier pilier de la liste self.piliers.

  • deplace(self: Jeu, p1: Pilier, p2: Pilier) -> bool

    Déplace un disque du pilier p1 au pilier p2 si cela est autorisé par les règles. Renvoie True si le déplacement a effectivement été réalisé, False sinon. On actualisera l'affichage à l'issue d'un déplacement.

  • autre(self: Jeu, p1: Pilier, p2: Pilier) -> Pilier

    Étant donné deux piliers p1 et p2, renvoie le pilier distinct de p1 et p2 de la liste self.piliers.

  • resoudre(self: Jeu, n: int, depart: Pilier, arrivee: Pilier) -> NoneType

    Déplace n disques du pilier depart vers le pilier arrivee, en faisant appel à la méthode deplace.