#-------------TP3 Récursivité-------------

#ex1

def Heron(u0,a,n): #version de départ
    if n==0:
        return u0
    else: 
        return (Heron(u0,a,n-1)+a/Heron(u0,a,n-1) )/2

#ex2

def pgcd(a,b):
    pass
    
def Bezout(a,b):
    pass

#ex3

def f1(x,n=0):#répondre aux questions AVANT d'exécuter, contrôler ensuite
    """Entrées :
        x est un réel supposé non nul (type float)
        n est un entier relatif (type int)
        si n est non renseigné, il prend la valeur par défaut : 0) """
    if x>=1 and x<2:
        return n
    elif x>=2:
        return f1(x/2,n+1)
    else:
        return f1(2*x,n-1)
        
#ex4
    
def convertitBase(n,a):
    """convertit l'entier n en base a
    la réponse est donnée sous forme de liste de symboles ("chiffres")"""
    pass
    
def retourBase10(seq,a):
    """convertit une séquence de "chiffres" écrite en base a 
    en un entier""" 
    pass
    
#ex5

def decimation(n,k,details=False):
    """modélise la suppression d'un élément sur k 
    de façon répétée et cyclique, 
    jusqu'à obtenir un dernier survivant"""
    liste=[i for i in range(n)]
    indice=k-1
    while len(liste)>1:
        del liste[indice]
        indice=(indice+k-1)%len(liste)
        if details:
            print(liste)
    return liste[0]

def survivant(n,k):
    pass

#ex6
           
def deplaceTour(plateau,numTige1,tailleTour,numTige2):
    #syntaxe plateau.deplaceBrique(numTige1,numTige2)
    pass
    
def Hanoi(nbrBriques=4,texteSeul=True,deltat=200):
    P=plateauHanoi(nbrBriques,texteSeul,deltat)   
    deplaceTour(P,0,nbrBriques,2)
    if not texteSeul:        
        #on attend le clic pour lancer l'animation
        P.canevas.bind('<Button-1>', P.OnOff)        
        P.canevas.mainloop()

#exo 7 motifs

def estConforme(texte,motif,it=0,im=0):
    """teste la conformité à partir des indices it et im"""
    pass
        
    
def nbConforme(texte,motif,it=0,im=0):
    """teste la conformité à partir des indices it et im"""
    pass

#exo 8 fonction nulle part dérivable

def graphe_f_n(xi,yi,xf,yf,n):
    """renvoie un couple : liste des abscisses, liste des ordonnées""" 
    pass
    
def traceGraphe_f_n(n):
    plt.figure()
    points=graphe_f_n(0,0,1,1,n)
    plt.plot(points[0],points[1])
    plt.show()


#exo 9 code à analyser

def f2(n,s): #répondre aux questions AVANT d'exécuter, contrôler ensuite
    if n>len(s)-2:
        print(s)
    else:
        f2(n+1,s)
        for i in range(n+1,len(s)):
            s[n],s[i]=s[i],s[n]
            f2(n+1,s)
            s[i],s[n]=s[n],s[i]
            
#-------------------------------------------------------------
#------------code pour les tours de Hanoi---------------------
#-------------------------------------------------------------

   
#deux variables globales (c'est juste pour la lisibilité)
animEnMarche=False
nbrCoups=0

from tkinter import * #pour interfaces graphiques 

class plateauHanoi():
    """classe chargée de préparer le plateau de jeu"""
    largeur=800
    hauteur=400
    abscisseTiges=[150,400,650] #abscisses des axes des trois tiges
    def __init__(self,nbrBriques,texteSeul,deltat):
        self.deltat=deltat
        self.texteSeul=texteSeul
        self.fenetre=Tk()
        self.nbrBriques=nbrBriques
        if texteSeul:
            self.titre="Situation initiale"
        else:
            self.titre="Cliquez pour démarrer/arrêter/reprendre"
        self.fenetre.title(self.titre)
        self.canevas=Canvas(self.fenetre,width=self.largeur,height=self.hauteur)  #crée une zone de dessin
        self.canevas.pack() #la positionne dans la fenêtre
        #création des tiges
        contenuT1=list(range(self.nbrBriques,0,-1))
        contenuT2=[]
        contenuT3=[]
        self.contenuTiges=[contenuT1,contenuT2,contenuT3]
        #tiges concrètes
        for x in self.abscisseTiges:
            self.canevas.create_rectangle(x-5,0,x+5,self.hauteur,fill="black")
            deltax=self.largeur//7
            deltay=self.hauteur//(2*(nbrBriques+1))
            self.canevas.create_rectangle(x-deltax,self.hauteur-deltay,x+deltax,self.hauteur,fill="black")
        #création des briques concrètes (de la classe Brique)
        self.briques=[Brique(self,i) for i in range (1,nbrBriques+1)]
        self.animEnMarche=False
        self.listeMouvements=[]
        self.nbrCoups=0
    def OnOff(self,event):
        self.animEnMarche=not self.animEnMarche
        self.mouvementBriques()
    def mouvementBriques(self):
        if self.nbrCoups<len(self.listeMouvements):
            numBrique,altitude,centre=self.listeMouvements[self.nbrCoups]
            laBrique=self.briques[numBrique-1]
            laBrique.bouge(centre,altitude)
            self.nbrCoups+=1
            if self.animEnMarche:
                self.canevas.after(self.deltat,self.mouvementBriques) 
    def deplaceBrique(self,numTige1,numTige2):
        if self.texteSeul:
            print("Brique de",numTige1,"à",numTige2)
        else:
            contenuTige1=self.contenuTiges[numTige1]
            contenuTige2=self.contenuTiges[numTige2]
            numBrique=contenuTige1.pop()
            nombreTige2=len(contenuTige2)
            contenuTige2.append(numBrique)
            #coordonnées d'arrivée
            xArrivee=self.abscisseTiges[numTige2]
            altitude=nombreTige2
            #ajout du mouvement à la liste des mouvements : num de la brique, coord d'arrivée
            self.listeMouvements.append([numBrique,altitude,xArrivee])
    
    
class Brique():
    """classe chargée de dessiner les briques, 
    de mémoriser leurs caractéristiques"""
    def __init__(self,plateau,taille):
        self.plateau=plateau
        self.taille=taille
        N=plateau.nbrBriques
        self.epaisseur=plateau.hauteur//(N+1)
        self.longueur=taille*plateau.largeur//(7*N)
        centre=plateau.abscisseTiges[0]
        x1=centre-self.longueur
        x2=centre+self.longueur
        y1=self.epaisseur*(taille-0.5)
        y2=self.epaisseur*(taille+0.5)
        self.dessin=plateau.canevas.create_rectangle(x1,y1,x2,y2,fill="blue")
    def bouge(self,centre,altitude):
        antialti=self.plateau.nbrBriques-altitude
        x1=centre-self.longueur
        x2=centre+self.longueur
        y1=self.epaisseur*(antialti-0.5)
        y2=self.epaisseur*(antialti+0.5)
        self.plateau.canevas.coords(self.dessin,x1,y1,x2,y2)

