#JCourtin 11/2016
#Les tours de Hanoï

class Hanoi():
    move=0      # compteur de déplacements
    hauteur=None
    
    #les tours : Il faut trois tours au maximum
    tourA=None
    tourB=None
    tourC=None
    
    #le jeu
    tours=None
    
    #constructeur
    def __init__(self, hauteurMax):
        self.hauteur=hauteurMax
        self.tourA = self.Tour("TourA",hauteurMax)
        self.tourB = self.Tour("TourB",0)    
        self.tourC = self.Tour("TourC",0)
        self.tours = [self.tourA, self.tourB, self.tourC]
    
    #affichage
    def __str__(self): 
        #on s'appuie sur la méthode __str__ de la class Tour avec str()
        mesTours=str(self.tourA) + str(self.tourB) + str(self.tourC)+"\n"
        return mesTours
    
    
    #mouvement Tour : déplace n pierres de la tour de départ vers la tour
    #                 d'arrivée (et désigne la tour intermédiaire)
    def mouvement(self, n, tourD, tourA, tourI):
        if (n>0):
            self.mouvement(n-1, tourD, tourI, tourA) #déplace les n-1 vers I
            pierre=tourD.pull()                      #deplace la grosse
            tourA.push(pierre)                       #pierre du bas
            self.move+=1                             
            print(self); print("move = ", self.move) #(Affichage étape)
            self.mouvement(n-1, tourI, tourA, tourD) #ramène les n-1 au dessus.
        else:       #lignes
            return  #inutiles
            
            

     
        
    #---------------------------------------------------------------------------
    class Tour():           #=> implémentation d'une structure de Pile
        nom=""
        hauteur=None
        colonne=None
        
        #constructeur d'une tour
        def __init__(self, petitNom, hauteurTour):
            self.nom = petitNom
            self.hauteur = hauteurTour
            self.colonne = [hauteurTour-k for k in range(hauteurTour)]
        
        #affichage d'une tour
        def __str__(self):
            maTour="\n"+self.nom+" : "
            if (self.hauteur==0):
                return maTour
            for pierre in range(self.hauteur-1):  
                maTour+=str(self.colonne[pierre])+"-"
            maTour+=str(self.colonne[-1])
            return maTour
         

        def pull(self):                 #retire une pierre
            if (self.hauteur>0):
                self.hauteur-=1
                return self.colonne.pop(-1)
            else:
                print("impossible")
                return None
                
        def push(self, pierre):         #pose la pierre
            self.hauteur+=1
            self.colonne+=[pierre]
            
            
############################## MAIN ###################################
N=3
monPremierJeu=Hanoi(N)
print(monPremierJeu)

A = monPremierJeu.tourA
B = monPremierJeu.tourB
C = monPremierJeu.tourC
monPremierJeu.mouvement(N, A, B, C)

"""
#test manu-militari
x=monPremierJeu.tourA.pull()
monPremierJeu.tourC.push(x)
print(monPremierJeu)

x=monPremierJeu.tourA.pull()
monPremierJeu.tourB.push(x)
print(monPremierJeu)

x=monPremierJeu.tourC.pull()
monPremierJeu.tourB.push(x)
print(monPremierJeu)
"""
