#!/usr/bin/env python """Jeu de Hanoï pour implémenter des piles""" from typing import Optional def main() -> None: p1 = Pile() p2 = Pile() p3 = Pile() p2 = ajout_tous_disques(p2) while not partie_finie(p1, p2, p3): affiche_etat_piles(p1, p2, p3) faire_coup(p1, p2, p3) print("Bravo, vous avez terminé") class Pile: """Une pile composée de maillons""" def __init__(self) -> None: self.val: Optional[int] = None self.suivant: Optional[Pile] = None def est_vide(self) -> bool: """Vérifie si la pile est vide""" return self.suivant is None def empile(self, nombre: int): """Empile nombre sur la pile""" maillon = Pile() maillon.val = nombre maillon.suivant = self return maillon def depile(self): """Dépile la pile""" return self.suivant def valeur_top(self) -> Optional[int]: """Retourne la valeur en haut de la pile sans dépiler""" if self.est_vide(): return None return self.val def ajout_tous_disques(pile: Pile) -> Pile: """Ajoute tous les disques sur p""" nombre_disques = int(input("Combien de disques ? ")) while nombre_disques >= 1: pile = pile.empile(nombre_disques) nombre_disques -= 1 return pile def partie_finie(p1: Pile, p2: Pile, p3: Pile) -> bool: """Détermine si la partie est finie""" return p2.est_vide() and (p1.est_vide() or p3.est_vide()) def affiche_etat_piles(p1: Pile, p2: Pile, p3: Pile) -> None: """Afficher l'état des trois piles""" print("Pile 1 :") affiche_etat(p1) print("Pile 2 :") affiche_etat(p2) print("Pile 3 :") affiche_etat(p3) def affiche_etat(pile: Pile) -> None: """Affiche l'état d'une pile""" if pile.est_vide(): print("La pile est vide") else: diam = pile.valeur_top() print(f"Le disque en haut de la pile est de diamètre {diam}") def faire_coup(p1: Pile, p2: Pile, p3: Pile) -> None: """Demande à l'utilisateur de jouer""" num_pile = int(input("Où voulez-vous prendre le disque ? ")) pile_a_depiler = selection_pile(p1, p2, p3, num_pile) if pile_a_depiler.est_vide(): print("Impossible, cette pile est vide") return diam = pile_a_depiler.valeur_top() print(f"Vous avez sélectionné le disque de diamètre {diam}") num_pile = int(input("Où voulez-vous poser le disque ? ")) pile_ou_empiler = selection_pile(p1, p2, p3, num_pile) if not pile_ou_empiler.est_vide() and diam > pile_ou_empiler.valeur_top(): print("Coup non autorisé") else: pile_a_depiler = pile_a_depiler.depile() pile_ou_empiler = pile_ou_empiler.empile(diam) def selection_pile(p1: Pile, p2: Pile, p3: Pile, num_pile: int) -> Pile: """Retourne la pile correspondant à num_pile""" if num_pile == 1: return p1 if num_pile == 2: return p2 return p3 if __name__ == "__main__": main()