
################
##            ##
## Exercice 2 ##
##            ##
################





## Question 2.2

def extraire_dictionnaire():
    s="dictionnaire.txt"
    f_in = open(s, 'r', encoding = 'utf-8')
    L=[]
    for ligne in f_in:
        mot=ligne[0:-1] # le dernier symbole correspond au symbole '\n'
        L.append(mot)
    return L

dico=extraire_dictionnaire()


## Question 2.3

for i in range(20) :
    print( i , dico[i] , len(dico[i]) )



## Question 2.4



n=len(dico)
L=[]
for i in range(n) :
    L.append(len(dico[i]))

n=len(dico)
L=[]
for mot in dico :
    L.append(len(mot))

[ len(mot) for mot in dico ]

# On vérifie que ça marche bien
print(L[:3])




## Question 2.5


def longueur_max(dico):
    l_max=0
    for i in range(len(dico)):
        if len(dico[i])>l_max:
            l_max=len(dico[i])
    return l_max

def longueur_max(dico):
    l_max=0
    for mot in dico:
        if len(mot)>l_max:
            l_max=len(mot)
    return l_max


## Question 2.6


l_max=longueur_max(dico)
for m in dico :
    if len(m) == l_max :
        print(m)





################
##            ##
## Exercice 3 ##
##            ##
################
from random import randint
from unicodedata import normalize
from time import ctime


## Question 3.1

def mot_au_hasard():
    # dico est une variable globale
    n=len(dico)
    aléa=randint(0,n-1)
    return dico[aléa]

def mot_au_hasard():
    # dico est une variable globale
    n=len(dico)
    aléa=randint(0,n-1)
    if len(dico[aléa]) >=3:
        return dico[aléa]
    else:
        return mot_au_hasard()


## Question 3.2
def cache_lettre(mot):
    n=len(mot)
    assert(n>=3)
    res=mot[0]
    for i in range(1,n-1):
        res = res + '_'
    return res + mot[n-1]


## Question 3.3
def ajoute_lettre(mot,secret,lettre):
    n=len(mot)
    assert(n==len(secret))
    res=""
    for i in range(n):
        if secret[i]==lettre:
            res = res+secret[i]
        else:
            res = res+mot[i]
    return res


## Question 3.4
def pluriel(k,mot):
    if k==0 or k==1:
        return str(k) + ' ' + mot
    else:
        return str(k) + ' ' + mot + 's'


def nouvelle_partie(vies) :
    secret = mot_au_hasard() # le mot a deviner
    mot = cache_lettre(secret) # le mot partiellement decouvert
    print('il te reste' , vies , 'vies')
    while vies > 0 and '_' in mot :
        print(mot)
        c = input('Quelle lettre demandes-tu, humain ? ')
        ancien_mot=mot
        mot=ajoute_lettre(mot,secret,c)
        if mot != ancien_mot :
            print('Bien joué !')
        else :
            vies = vies-1
            print('Raté... Il te reste ' + pluriel(vies,'vie')+'.' )
    if vies == 0 :
        print('PENDU! Le mot secret était' , secret + '. On rejoue ?')
    else :
        print(m)
        print('GAGNÉ ! On rejoue ?')
        nom = input("Quel est ton nom :")
        ajout_score(vies,nom)# Pour l'exercice 4
        affiche_score()  # Pour l'exercice 4



## Question 3.6

def sans_accents(s):
    return normalize('NFKD',s).encode('ascii' , 'ignore').decode('ascii')


def ajoute_lettre(mot,secret,lettre):
    n=len(mot)
    assert(n==len(secret))
    res=""
    for i in range(n):
        if sans_accents(secret[i])==lettre:
            res = res+secret[i]
        else:
            res = res+mot[i]
    return res




################
##            ##
## Exercice 4 ##
##            ##
################


def date():
    t=localtime()
    heure=f"{t.tm_hour:0>2}:{t.tm_min:0>2}:{t.tm_sec:0>2}"
    jour =f"{t.tm_mday:0>2}/{t.tm_mon:0>2}/{t.tm_year:0>2}"
    return 'le ' + jour + ' à ' + heure

def découpe(ligne):
    k = ligne.index(" : ")
    return (int(ligne[:k]),ligne[k+3:])

def ajoute(nouvelle_ligne,liste):
    (score,chaîne)=nouvelle_ligne
    rés=[]
    i=0
    # On ajoute les scores supérieurs
    while i<len(liste) and liste[i][0]>score:
        rés.append(liste[i])
        i=i+1
    # On ajoute le nouveau score
    rés.append(nouvelle_ligne)
    # On ajoute les scores inférieurs
    while i<len(liste):
        rés.append(liste[i])
        i=i+1
    return rés

import os.path

def ajout_score(vies,nom):
    if os.path.isfile('score.txt'):# On vérifie si le fichier existe déjà.
        f_in = open('score.txt', 'r', encoding = 'utf-8')
        liste=f_in.readlines()
        f_in.close()
        liste=liste[2:] # on supprime les deux première ligne
        liste= [ découpe(ligne) for ligne in liste ]
    else:
        liste=[]
    nouvelle_ligne = (vies, nom+' '+date()+'\n')
    liste = ajoute(nouvelle_ligne,liste)
    f_out = open('score.txt', 'w', encoding = 'utf-8')
    f_out.write('Vies restantes (meilleur score)\n')
    f_out.write('===============================\n')
    for couple in liste:
        (v,c)=couple
        f_out.write(str(v) + ' : ' + c)
    f_out.close()

def afficher_score():
    assert(os.path.isfile('score.txt'))
    f_in = open('score.txt', 'r', encoding = 'utf-8')
    contenu=f_in.read()
    f_in.close
    print(contenu)




################
##            ##
## Exercice 5 ##
##            ##
################


## Question 5.1


# Version classique
def candidats(deb,fin,l) :
    L=[]
    for m in dico:
        if len(m) == l and m[0] == deb and m[-1] == fin:
            L.append(m)
    return L

# Version plus courte
def candidats(deb,fin,l) :
    return [ m for m in dico if len(m) == l and m[0] == deb and m[-1] == fin]

## Question 5.2


def choix_lettre(s,L):
    lettres = []
    l = len(s)
    for m in L :
        assert(len(m) == l)
        for i in range(l) :
            if s[i] == '_' :
                lettres.append(sans_accents(m[i]))
    x = randint(0, len(lettres) - 1)
    return lettres[x]

## Question 5.3


def filtre_lettre(c,L) :
    F=[]
    for m in L:
        if c not in sans_accents(m[1:-1]):
            F.append(m)
    return F

# Version plus courte
def filtre_lettre(c,L) :
    return [m for m in L if c not in sans_accents(m[1:-1])]


## Question 5.4


def est_compatible(s,m) :
    if len(s) != len(m) :
        return False
    for i in range(len(s)) :
        if s[i] != '_' and s[i] != m[i] :
            return False
        if s[i] == '_' and m[i] != '_' and m[i] in s[1:-1] :
            return False
    return True

## Question 5.5

def joue_chercheur(vies) :
    s = input('Quel est ton indice, humain? ')
    L = candidats(s[0],s[-1],len(s))

    while vies > 0 and len(L) > 1 :

        print("J'hésite entre" , L)
        lettre = choix_lettre(s,L)
        print('Je demande le ' , lettre + '.')

        while True :
            s2 = input('Nouvel indice? ')
            if est_compatible(s,s2) : break
            print('erreur de saisie. Ancien indice :',s)

        if s2 == s :
            # rate
            L = filtre_lettre(lettre,L)
            vies = vies - 1
            print('Il me reste' , vies , 'vie' + ('s' if vies > 2 else '') + '.')
        else :
            # bonne lettre
            s = s2
            L = [m for m in L if est_compatible(s,m)]

    if len(L) == 1 :
        print("J'ai trouvé :" , L[0])
    elif len(L) == 0 :
        print("Tricheur!")
    else :
        print("J'ai perdu, tu avais bien choisi ton mot...")

joue_chercheur(10)
