# Gestion automatique de l'importation try : from tkinter import * except : from Tkinter import * from Outils.Moteur_de_jeu.Plateau import * from Outils.Moteur_de_jeu.Conversion import * ##################### # Saisie des noms : # ##################### def valider_saisie(partie, fenetre, nom_A, nom_B) : caracteres_autorises = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'+-=_" nom_A_corrige = "" if partie.joueurA.est_humain() and nom_A != "" : for i in range(len(nom_A)) : if nom_A[i] not in caracteres_autorises : nom_A_corrige += "_" else : nom_A_corrige += nom_A[i] partie.joueurA.nom = nom_A_corrige nom_B_corrige = "" if partie.joueurB.est_humain() and nom_B != "" : for i in range(len(nom_B)) : if nom_B[i] not in caracteres_autorises : nom_B_corrige += "_" else : nom_B_corrige += nom_B[i] partie.joueurB.nom = nom_B_corrige fenetre.destroy() partie.lancement() def saisie_noms(partie) : fenetre = Tk() fenetre.title("Quoridor") fenetre.geometry("500x120+420+300") config = partie.joueurA.type + partie.joueurB.type saisie_A = Entry(fenetre) saisie_B = Entry(fenetre) bouton = Button(fenetre, text = "Valider", command = lambda : valider_saisie(partie, fenetre, saisie_A.get(), saisie_B.get())) if config == "HH" : texte = Label(fenetre, text = "Saisissez vos noms") texte.pack(padx = 5, pady = 5) saisie_A.pack(padx = 5, pady = 5) saisie_B.pack(padx = 5, pady = 5) elif config == "HO" : texte = Label(fenetre, text = "Saisissez votre nom") texte.pack() saisie_A.pack(padx = 5, pady = 5) else : texte = Label(fenetre, text = "Saisissez votre nom") texte.pack(padx = 5, pady = 5) saisie_B.pack(padx = 5, pady = 5) bouton.pack(padx = 5, pady = 5) fenetre.mainloop() #################### #Classe vide initialement dans laquelle seront déclarées deux variables statiques : partie et barriere_en_construction class Global : pass def clic_canevas(clic) : # Quentin 04/10/2016 #Les coordonnées du clic sont accessibles avec clic.x et clic.y selection = (-1,-1) bord = Global.partie.affichage.bord esp = Global.partie.affichage.esp lg_case = Global.partie.affichage.lg_case for x in range(Global.partie.plateau.lg) : for y in range(Global.partie.plateau.ht) : #Test de collision d'un rectangle dans le cas des cases ou des cercles, selon l'étape du tour if (Global.partie.etape == "J" and \ clic.x >= (lg_case + esp)*x + bord and clic.x <= (lg_case + esp)*(x+1) + bord - esp and clic.y >= (lg_case + esp)*y + bord and clic.y <= (lg_case + esp)*(y+1) + bord - esp) \ or (Global.partie.etape == "B1" and\ ((lg_case + esp)*(x+1) + bord - esp/2 - 1 - clic.x)**2 + ((lg_case + esp)*(y+1) + bord - esp/2 - 1 - clic.y)**2 <= Global.partie.affichage.Rselect**2) : selection = (x,y) barriere_h = Barriere("h",selection[0],selection[1]) barriere_v = Barriere("v",selection[0],selection[1]) h_ok = Global.partie.est_selectionnable(barriere_h) v_ok = Global.partie.est_selectionnable(barriere_v) if Global.partie.etape == "J" and Global.partie.joueur_actuel().type == "H" and selection in Global.partie.cases_selectionnables : Global.partie.executer_tour(Coup("M", case = selection)) Global.partie.affichage.rafraichissement(Global.partie) elif Global.partie.etape == "B1" and (h_ok or v_ok) : Global.barriere_en_construction = selection if h_ok and v_ok : #Si on a le choix entre h et v Global.partie.etape = "B2" Global.partie.affichage.rafraichissement(Global.partie) elif h_ok : clic_boutonH() else : clic_boutonV() def presser_touche(key) : if key.char == '*' : print(code_from_plateau(Global.partie.plateau)) elif Global.partie.etape == "J" and Global.partie.joueur_actuel().type == "O" : clic_bouton() def clic_bouton() : # Quentin 04/10/2016 if Global.partie.etape == "J" : if Global.partie.joueur_actuel().type == "H" : Global.partie.etape = "B1" else : Global.partie.executer_tour( Global.partie.coup_IA() ) elif Global.partie.etape == "B1" : Global.partie.etape = "J" elif Global.partie.etape == "B2" : Global.partie.etape = "B1" else : Global.partie.affichage.fenetre.destroy() Global.partie = Global.partie.relancer() Global.partie.demarrer() return Global.partie.affichage.rafraichissement(Global.partie) def clic_boutonH() : # Quentin 04/10/2016 Global.partie.executer_tour( Coup("B", barriere = Barriere( "h", Global.barriere_en_construction[0], Global.barriere_en_construction[1]) ) ) Global.partie.affichage.rafraichissement(Global.partie) def clic_boutonV() : # Quentin 04/10/2016 Global.partie.executer_tour( Coup("B", barriere = Barriere( "v", Global.barriere_en_construction[0], Global.barriere_en_construction[1]) ) ) Global.partie.affichage.rafraichissement(Global.partie) def clic_case_graphe() : Global.partie.affichage.rafraichissement(Global.partie) def clic_case_bouton() : if Global.partie.joueur_actuel().type == "O" : clic_bouton() Global.partie.affichage.rafraichissement(Global.partie) def clic_regles() : sous_fenetre = Toplevel() sous_fenetre.title("Règles du jeu") texte = Label(sous_fenetre, text = "Vous contrôlez un des deux pions. Votre objectif est d'atteindre le bord opposé du plateau.\nÀ chaque tour, vous devez effectuer une seule de ces deux actions :\n\n-> Se déplacer d'une case horizontalement ou verticalement. Si le pion adverse se situe à côté de vous, vous pouvez sauter par dessus.\nOU\n-> Poser une barrière en travers du chemin de votre adversaire pour le ralentir. La seule contrainte est que vous devez lui laisser au moins un chemin libre vers son objectif.") texte.grid(row = 0, column = 0, sticky = W) def afficher_cercle(a,x,y) : """ Affiche un cercle de sélection en bas à droite de la case (x,y), selon les dimensions renseignées dans a """ a.canevas.create_rectangle((a.lg_case + a.esp)*(x + 1) + a.bord - a.esp/2 - a.Rselect - 1, (a.lg_case + a.esp)*(y + 1) + a.bord - a.esp/2 - a.Rselect - 1,\ (a.lg_case + a.esp)*(x + 1) + a.bord - a.esp/2 + a.Rselect - 1, (a.lg_case + a.esp)*(y + 1) + a.bord - a.esp/2 + a.Rselect - 1, outline = "white", width = 3) class Affichage : def __init__(a, plateau, afficher_case_bouton) : # Quentin 17/11/2016 a.bord = 20 #Espace entre le bord du plateau et les cases extrémales a.esp = 10 #Espace entre les cases a.lg_case = 50 #Largeur d'une case a.Rpion = 10 #Rayon des pions a.Rselect = 8 #Rayon des cercles de sélection a.ep_select = 2 #Epaisseur du cadre autour de la case du joueur actif a.Rnoeud = 22 #Rayon des noeuds a.ep_ar = 4 #Epaisseur des arêtes a.fenetre = Tk() a.fenetre.title("Quoridor") largeur_canevas = (a.lg_case + a.esp) * plateau.lg + a.bord + a.esp hauteur_canevas = (a.lg_case + a.esp) * plateau.ht + a.bord + a.esp a.canevas = Canvas(a.fenetre, bg = "#844B16", width = largeur_canevas, height = hauteur_canevas) a.canevas_graphe = Canvas(a.fenetre, bg = "#999999", width = largeur_canevas, height = hauteur_canevas) a.var_graphe = IntVar() a.case_graphe = Checkbutton(a.fenetre, variable = a.var_graphe, text = "Afficher ou masquer le graphe") a.case_graphe.config(command = clic_case_graphe) a.case_graphe.grid(row = 4, column = 0, sticky = W) if afficher_case_bouton : a.var_bouton = IntVar() a.case_bouton = Checkbutton(a.fenetre, variable = a.var_bouton, text = "Activer ou désactiver la demande de confirmation") a.case_bouton.config(command = clic_case_bouton) a.case_bouton.grid(row = 5, column = 0, sticky = W) a.canevas.bind("",clic_canevas) a.canevas.bind("", presser_touche) a.canevas.focus_set() a.texte = Label(a.fenetre,text = "") a.bouton = Button(a.fenetre,text = "",command = clic_bouton) a.boutonH = Button(a.fenetre,text = "Horizontalement -",command = clic_boutonH) a.boutonV = Button(a.fenetre,text = "Verticalement |",command = clic_boutonV) a.bouton_regles = Button(a.fenetre,text = "Règles du jeu", command = clic_regles) a.texte_barrieres = Label(a.fenetre, text = "") a.canevas.grid(row = 0, column = 0, columnspan = 3, padx = 10) a.texte.grid(row = 1, column = 0, columnspan = 3) a.texte_barrieres.grid(row = 4, column = 2, rowspan = 2, sticky = E) a.bouton_regles.grid(row = 4, column = 1, rowspan = 2, padx = 10) def afficher_canevas(a,partie) : # Quentin 04/10/2016 a.canevas.delete(ALL) #Cases : for x in range(partie.plateau.lg) : for y in range(partie.plateau.ht) : if partie.plateau.joueur_sur_case(partie.plateau.tour, x, y) : a.canevas.create_rectangle((a.lg_case + a.esp)*x + a.bord + a.ep_select, (a.lg_case + a.esp)*y + a.bord + a.ep_select,\ (a.lg_case + a.esp)*(x+1) + a.bord - a.esp - a.ep_select + 1, (a.lg_case + a.esp)*(y+1) + a.bord - a.esp - a.ep_select + 1,\ width = a.ep_select, outline = "white", fill = "black") else : if (x,y) in partie.cases_selectionnables and partie.etape == "J" : couleur = "grey" else : couleur = "black" a.canevas.create_rectangle((a.lg_case + a.esp)*x + a.bord, (a.lg_case + a.esp)*y + a.bord, (a.lg_case + a.esp)*(x+1) + a.bord - a.esp, (a.lg_case + a.esp)*(y+1) + a.bord - a.esp,\ width = 0, fill = couleur) a.canevas.create_rectangle(a.bord, a.bord - 13, a.bord + (a.lg_case + a.esp) * partie.plateau.lg - a.esp, a.bord - 3, width = 0, fill = "#C9660A") a.canevas.create_rectangle(a.bord, (a.lg_case + a.esp) * partie.plateau.ht - a.esp + a.bord + 3,\ a.bord + (a.lg_case + a.esp) * partie.plateau.lg - a.esp, (a.lg_case + a.esp) * partie.plateau.ht - a.esp + a.bord + 13,\ width = 0, fill = "#EAC019") for b in partie.plateau.liste_barrieres : if b.orientation == "h" : a.canevas.create_rectangle((a.lg_case + a.esp)*b.x + a.bord + 3, (a.lg_case + a.esp)*b.y + a.lg_case + a.bord + 1,\ (a.lg_case + a.esp)*(b.x + 1) + a.bord + a.lg_case - 3, (a.lg_case + a.esp)*(b.y + 1) + a.bord, width = 0,fill = "#FCEBDB") else : a.canevas.create_rectangle((a.lg_case + a.esp)*b.x + a.bord + a.lg_case + 1, (a.lg_case + a.esp)*b.y + a.bord + 3,\ (a.lg_case + a.esp)*(b.x + 1) + a.bord, (a.lg_case + a.esp)*(b.y + 1) + a.bord + a.lg_case - 3, width = 0,fill = "#FCEBDB") #Emplacements libres : if partie.etape == "B1" : for b in partie.barrieres_selectionnables : afficher_cercle(a, b.x, b.y) #Coin sélectionné : elif partie.etape == "B2" : afficher_cercle(a, Global.barriere_en_construction[0], Global.barriere_en_construction[1]) # Affichage des pions : L = a.bord + a.lg_case//2 # Terme constant ((x1,y1),(x2,y2)) = partie.plateau.pions a.canevas.create_rectangle((a.lg_case + a.esp)*x1 + L - a.Rpion, (a.lg_case + a.esp)*y1 + L - a.Rpion,\ (a.lg_case + a.esp)*x1 + L + a.Rpion, (a.lg_case + a.esp)*y1 + L + a.Rpion, fill = "#EAC019") a.canevas.create_rectangle((a.lg_case + a.esp)*x2 + L - a.Rpion, (a.lg_case + a.esp)*y2 + L - a.Rpion,\ (a.lg_case + a.esp)*x2 + L + a.Rpion, (a.lg_case + a.esp)*y2 + L + a.Rpion, fill = "#C9660A") def afficher_canevas_graphe(a, partie) : # Quentin 04/10/2016 a.canevas_graphe.delete(ALL) chemin = path_finding(partie.plateau, partie.plateau.pions[partie.plateau.tour][0], partie.plateau.pions[partie.plateau.tour][1], partie.plateau.rangee_desiree(partie.plateau.tour)) L = a.bord + a.lg_case//2 # Terme constant #Affichage de toutes les arêtes horizontales : for x in range(partie.plateau.lg - 1) : for y in range(partie.plateau.ht) : a.canevas_graphe.create_line((a.lg_case + a.esp)*x + L, (a.lg_case + a.esp)*y + L,\ (a.lg_case + a.esp)*(x + 1) + L, (a.lg_case + a.esp)*y + L, fill = "black", width = a.ep_ar) #Affichage de toutes les arêtes verticales : for x in range(partie.plateau.lg) : for y in range(partie.plateau.ht - 1) : a.canevas_graphe.create_line((a.lg_case + a.esp)*x + L, (a.lg_case + a.esp)*y + L,\ (a.lg_case + a.esp)*x + L, (a.lg_case + a.esp)*(y + 1) + L, fill = "black", width = a.ep_ar) #Effacement des arêtes barrées for b in partie.plateau.liste_barrieres : c = "#999999" if b.orientation == "v" : a.canevas_graphe.create_line((a.lg_case + a.esp)*b.x + L, (a.lg_case + a.esp)*b.y + L,\ (a.lg_case + a.esp)*(b.x + 1) + L, (a.lg_case + a.esp)*b.y + L, fill = c, width = a.ep_ar) a.canevas_graphe.create_line((a.lg_case + a.esp)*b.x + L, (a.lg_case + a.esp)*(b.y + 1) + L,\ (a.lg_case + a.esp)*(b.x + 1) + L, (a.lg_case + a.esp)*(b.y + 1) + L, fill = c, width = a.ep_ar) else : a.canevas_graphe.create_line((a.lg_case + a.esp)*b.x + L, (a.lg_case + a.esp)*b.y + L,\ (a.lg_case + a.esp)*b.x + L, (a.lg_case + a.esp)*(b.y + 1) + L, fill = c, width = a.ep_ar) a.canevas_graphe.create_line((a.lg_case + a.esp)*(b.x + 1) + L, (a.lg_case + a.esp)*b.y + L,\ (a.lg_case + a.esp)*(b.x + 1) + L, (a.lg_case + a.esp)*(b.y + 1) + L, fill = c, width = a.ep_ar) for x in range(partie.plateau.lg) : for y in range(partie.plateau.ht) : if partie.plateau.joueur_sur_case(partie.plateau.tour, x, y) : couleur = "#21C421" elif (x,y) in chemin : couleur = "red" else : couleur = "#666666" a.canevas_graphe.create_rectangle((a.lg_case + a.esp)*x + L - a.Rnoeud, (a.lg_case + a.esp)*y + L - a.Rnoeud,\ (a.lg_case + a.esp)*x + L + a.Rnoeud, (a.lg_case + a.esp)*y + L + a.Rnoeud, fill = couleur) def rafraichissement(a,partie) : # Quentin 17/11/2016 a.afficher_canevas(partie) apostrophe = partie.joueur_actuel().nom + " : " a.bouton.grid_forget() a.boutonH.grid_forget() a.boutonV.grid_forget() if partie.etape == "J" : if not partie.joueur_actuel().est_humain() : a.bouton.config(text = "Lancer") a.bouton.grid(row = 2, column = 1) a.texte.config(text = "Cliquez sur le bouton pour que l'I.A. joue son coup.") else : if partie.plateau.barrieres_restantes[partie.plateau.tour] > 0 : a.bouton.config(text = "Placer une barrière") a.bouton.grid(row = 2, column = 1) a.texte.config(text = apostrophe + "Déplacez-vous ou placez une barriere") else : a.texte.config(text = apostrophe + "Déplacez-vous") elif partie.etape == "B1" : a.bouton.config(text = "Annuler") a.texte.config(text = apostrophe + "Choisissez l'emplacement du milieu de votre barrière") a.bouton.grid(row = 2, column = 1) elif partie.etape == "B2" : a.bouton.config(text = "Annuler") a.bouton.grid(row = 2, column = 1) a.boutonH.grid(row = 3, column = 0) a.boutonV.grid(row = 3, column = 2) a.texte.config(text = apostrophe + "Choisissez l'orientation de votre barrière") else : #"F" a.bouton.config(text = "Rejouer") a.bouton.grid(row = 2, column = 1) gagnant = 1 - partie.plateau.tour if partie.joueurs[gagnant].est_humain() : a.texte.config(text = partie.joueurs[gagnant].nom + " a gagné") else : a.texte.config(text = "L'I.A. a gagné") if a.var_graphe.get() == 1 : a.canevas_graphe.grid(row = 0, column = 4) a.afficher_canevas_graphe(partie) else : a.canevas_graphe.grid_forget() nb_0 = partie.plateau.barrieres_restantes[0] nb_1 = partie.plateau.barrieres_restantes[1] texte = "Joueur jaune : " + str(nb_0) + " barrière" if nb_0 != 1 : texte += "s" texte += "\nJoueur orange : " + str(nb_1) + " barrière" if nb_1 != 1 : texte += "s" a.texte_barrieres.config(text = texte + "\n") def affichage_sauvage(partie) : Global.partie = partie partie.affichage = Affichage(partie.plateau, False) partie.affichage.rafraichissement(partie)