from tkinter import *
from tkinter.messagebox import showinfo
from random import choice

    #Initialisation

Fenetre=Tk()
Fenetre.resizable(width=False, height=False)
Fenetre.title("Mastermind")


def init():
    global zone_dessin, grille, panel, Solution, Sol_save, ligneAVerifier, verification, etape, couleur_choisi, croix
    zone_dessin.delete(ALL) # efface tout dans la zone de dessin
    c=40
    b=11
    grille=[[zone_dessin.create_oval(i*(c+b)+b,j*(c+b)+b,(i+1)*(c+b),(j+1)*(c+b),fill='black',width=1,outline='#B09F91',tags='grille') for i in range(5)] for j in range(10)] # crée la zone de vérification (points rouges et blancs)
    verification=[[zone_dessin.create_oval(i*(c+b)+350,j*(c+b)+b,(i+1)*c+i*b+350,(j+1)*(c+b),fill='blue',width=1,outline='#B09F91') for i in range(5)] for j in range(10)] # crée la zone de proposition  du joueur
    Liste=['green','blue','yellow','red','#FF358B','brown','purple','#E87600']
    panel=[zone_dessin.create_oval(105+i*(c+b),520,105+(i+1)*c+i*b,520+c,fill=Liste[i],width=1,outline='#B09F91',tags='panel') for i in range(8)] # crée la liste des couleurs disponibles
    couleur_choisi=zone_dessin.create_oval(20,520,60,560,fill='grey',width=1,outline='black',tags='couleur_choisi') # crée la case de la couleur choisie
    croix=zone_dessin.create_text(40,540, text=X, font="Comic 60", fill='',tags='croix') # affiche une croix si la couleur est déjà utilisée dans la ligne
    zone_dessin.bind("<Button-1>",fonction)
    liste=['M','A','S','T','E','R','M','I','N','D']
    titre =[zone_dessin.create_text(650, 45+i*55, text=liste[i], font="Comic 30 ", fill="black")for i in range(10)]
    ligneAVerifier=9    # La première vérification concerne la ligne 9
    Solution=creation_solution()
    
    #Partie dessin

def ligne():    #Crée la liste proposition
    global ligneAVerifier, Proposition, Sauvegarde, Sol_save
    zone_dessin.itemconfigure(couleur_choisi,fill='') # réinitialise la zone de couleur choisie
    zone_dessin.itemconfigure(croix,fill='')
    Proposition=[]
    for i in range(5):
        Proposition.append(zone_dessin.itemcget(grille[ligneAVerifier][i],"fill"))
    if 'black' in Proposition:
        showinfo("Insuffisant","Votre prosposition doit contenir cinq couleurs différentes")
    else:
        Sol_save=list(Solution) #On fait des sauvegardes des listes car on les modifie pour compter le nombre de blancs
        rouge=nombre_rouge()
        blanc=nombre_blanc()
        for i in range(5):
            zone_dessin.itemconfigure(verification[ligneAVerifier][i],fill='black')
            if i<rouge:     #colorie les premiers disques en rouge en fonction du nombre de couleurs bien placées par le joueur
                zone_dessin.itemconfigure(verification[ligneAVerifier][i],fill='red')
        for i in range(5):
            if i<blanc:     #colorie les disques (encore non coloriés en rouge) en blanc en fonction du nombre de couleurs justes mais mal placées par le joueur
                zone_dessin.itemconfigure(verification[ligneAVerifier][i+rouge],fill='white')
        ligneAVerifier-=1
    fin()



def fonction(evt):  #Permet de mettre la couleur dans les cercles
    global elt, ligneAVerifier, etape, couleur
    elt=zone_dessin.find_withtag(CURRENT) # Prend l’élément sur lequel on a cliqué
    if elt!=():
        if etape==1 and 'grille' or 'panel' in zone_dessin.gettags(elt):# Vérifie si 'grille' ou 'panel' fait partie des tags, et donc que la couleur vient de la bonne zone
          couleur=zone_dessin.itemcget(elt,"fill") # Prend la couleur de l’élément désigné
          if couleur!='black': # empêche de choisir une case noire
              zone_dessin.itemconfigure(couleur_choisi,fill=couleur) # affiche la couleur choisie
              zone_dessin.itemconfigure(croix,fill='')
              etape=etape*-1        
        if etape==-1 and  elt[0] in grille[ligneAVerifier]:# Vérifie que l'on colorie la bonne ligne
            for i in range(5):
                couleur_ligne=zone_dessin.itemcget(grille[ligneAVerifier][i],"fill") # Détermine les couleurs déjà utilisées
                if couleur==couleur_ligne:                  
                    zone_dessin.itemconfigure(croix,fill='black') # Interdit d'utiliser deux fois la même couleur
                    showinfo("Dommage","Couleur déjà utilisée. Choisissez-en une autre !")
                    etape=etape*-1
        if etape==-1 and elt[0] in grille[ligneAVerifier]:# Vérifie que l'on colorie la bonne ligne
          zone_dessin.itemconfigure(elt,fill=couleur) # Change la couleur de l’élément désigné
          zone_dessin.itemconfigure(couleur_choisi,fill='') # réinitialise la couleur choisie
          etape=etape*-1




    #Partie programme

def creation_solution():    #Création d'une solution de n couleurs
    Solution=[]
    Liste=['green','blue','yellow','red','#FF358B','brown','purple','#E87600']
    for i in range(5):
        a=choice(Liste)
        Liste.remove(a)
        Solution.append(a)
    return Solution
    
def nombre_rouge(): #Calcul du nombre de couleurs correctes bien placées
        global rouge, Proposition, Sol_save, nombre_rouge
        i=0
        rouge=0
        while i<cases:
            if Proposition[i]==Sol_save[i]:
                rouge=rouge+1
                Proposition[i]='0'  #Parce que sinon il compte plusieurs fois des couleurs déjà comptées
                Sol_save[i]='00'
            i=i+1
        return rouge
    
def nombre_blanc(): #Calcul bonnes couleurs mal placées
        global Proposition, Sol_save, nombre_blanc
        i=0
        blanc=0
        while i<cases:
                j=0
                while j<cases:
                        if Proposition[i]==Sol_save[j] and i!=j:
                                blanc=blanc+1
                                Proposition[i]='000'      #Parce que sinon il compte plusieurs fois des couleurs déjà comptées    
                                Sol_save[j]='0000'
                        j=j+1
                i=i+1
        return blanc


def affiche_solution(): #fonction qui affiche la solution
    if ligneAVerifier==-1:
        for i in range(5):
            zone_dessin.itemconfigure(verification[0][i],fill=Solution[i])
        

        
    
        
def fin():  #Fonction qui définit si le joueur a gagné ou perdu
    global rouge
    if rouge==5:
        text_trouv = "Vous avez trouvé la solution en "+str(9-ligneAVerifier)+ " essais"
        showinfo("Victoire !",text_trouv)
        boutonVerif.config(state="disable")
    if ligneAVerifier==-1 and rouge<5:
        boutonsolution.config(state="normal")
        showinfo("Défaite","Vous n'avez pas trouvé la solution...\n Cliquez sur solution pour la bonne combinaison")


def rejouer():  #Fonction qui relance le jeu
    boutonVerif.config(state="normal")
    boutonsolution.config(state="disable")
    init()
    


       #Label et boutons


lb_resultat = Label(Fenetre)
zone_dessin=Canvas(Fenetre,width=700,height=570,bg='#B09F91',bd=8,relief="ridge")
boutonrejouer = Button(Fenetre, text="Rejouer", command=rejouer)
boutonquitter = Button(Fenetre, text="Quitter", command=Fenetre.destroy)
boutonVerif=Button(Fenetre, text="Vérifier la ligne",command=ligne)
boutonsolution = Button(Fenetre, text="Solution", command=affiche_solution)


zone_dessin.pack(side=LEFT)
boutonVerif.pack(side=RIGHT)
boutonrejouer.pack(side=RIGHT)
boutonquitter.pack(side=RIGHT)
boutonsolution.pack(side=RIGHT)
boutonsolution.config(state="disable")


    #Lancement du jeu

    #Programme de base

global cases, Solution, Proposition
global ligneAVerifier
cases=5
etape=1
rouge=0

if __name__ == "__main__":
    init()
    showinfo("Mastermind","Vous devez trouver la combinaison correcte de couleurs. Pour cela, remplissez la grille ligne par ligne avec les couleurs proposées.\n Un point rouge signifie qu'une couleur correcte est bien placée, un blanc qu'une couleur correcte est mal placée.\n Vous gagnez si vous trouvez la bonne combinaison. Bonne chance !")
    Fenetre.mainloop()






