1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
| import tkinter as tk
import random
# nécessaire pour version de ptyhon < 3.6 sinon dict suffit
from collections import OrderedDict
def jouerSequence() :
''' Ajoute une couleur à la séquence et les joue '''
# Choix d'un identifiant couleur au pif
iid = random.choice(couleursIds)
# Ajout de l'identifiant à la séquence à répéter
sequence.append(iid)
# Init du délai
delai = 0
for iid in sequence :
delai += 300
# Récupération de la couleur de l'identifiant choisi
couleur = can.itemcget(iid, 'fill')
# Changement de la couleur un bref instant
can.after(delai, can.itemconfigure, iid, {'fill':COULEURS[couleur]})
delai += 300
# Remise à la couleur d'origine
can.after(delai, can.itemconfigure, iid, {'fill':couleur})
delai += 300
# Appel de la fonction d'activation des clics joueurs
can.after(delai, activerClic)
def validerSequence(evt) :
''' Validation de la répétition par le joueur de la séquence de couleurs jouée '''
# Si le clic n'est pas autorisé, on ne fait rien
if not statuts['clic'] : return
# Récupération sur le canevas des ids des items contenant le point x, y du clic
ids = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
# Parcours de ces ids
for iid in ids :
# Si l'id est dans la liste des ids des couleurs, interruption de la boucle
if iid in couleursIds :
break
else :
# La totalité de l'itérable ids a été parcouru sans concordance avec les
# ids des couleurs, rien à faire de plus
return
# Si l'id de l'item cliqué vaut l'élément de séquence ayant l'indice en cours
if sequence[statuts['indice']] == iid :
# Récupération de la couleur de l'item cliqué
couleur = can.itemcget(iid, 'fill')
try :
# Tentative de mise à jour de la couleur
can.itemconfigure(iid, fill=COULEURS[couleur])
except KeyError :
# clic trop rapide (couleur n'ayant pas eu le temps de se réinitialiser)
return
# Remise en état de la couleur d'origine de l'item cliqué
can.after(200, can.itemconfigure, iid, {'fill':couleur})
# Ajout de l'identifiant dans la séquence du joueur
sequenceJoueur.append(iid)
# Si les 2 séquences sont identiques
if sequenceJoueur == sequence :
# Remise à l'état de démarrage des valeurs
initialiser()
# Rappel de la fonction après un petit délai
can.after(500, jouerSequence)
else :
# Donc la séquence joueur n'est pas encore identique
# Incrémentation de l'indice en cours de vérification, afin de
# vérifier l'élément suivant au prochain clic
statuts['indice'] += 1
else :
# La couleur cliquée est donc mauvaise => fin de la partie
terminerJeu()
def activerClic() :
''' Active la prise en compte des clics joueurs '''
# Autorisation des clics joueur
statuts['clic'] = True
# Petit message indiquant que le joueur peut commencer à répéter la séquence
labelInfo['text'] = 'À VOUS !'
def initialiser() :
''' Initialisation des valeurs avant lancement d'une séquence '''
# Interdiction de valider les clics joueurs
statuts['clic'] = False
# Initialisation de l'indice de la séquence à répéter
statuts['indice'] = 0
# Purge de la liste des séquences saisies par le joueur
sequenceJoueur.clear()
# Initialisation du texte label à une chaîne vide
labelInfo['text'] = ''
def terminerJeu() :
''' Fin de partie '''
# Interdiction de prendre en compte les clics joueur
statuts['clic'] = False
# Affichage du message stipulant que le joueur a perdu
labelInfo.configure(bg='red', fg='white', text='PERDU !')
# Activation du bouton jouer, afin que le joueur puisse faire une autre partie
boutonJouer['state'] = tk.NORMAL
def jouer() :
''' Initialisation et lancement du jeu '''
# Désactivation du bouton jouer
boutonJouer['state'] = tk.DISABLED
# Init des couleurs du label
labelInfo.configure(bg='black', fg='green')
# Purge de la liste des séquences
sequence.clear()
# Amorce du jeu
initialiser()
jouerSequence()
# Constantes
LARGEUR_COULEUR = 400
HAUTEUR_COULEUR = 400
COULEURS = OrderedDict((
('darkRed', 'red'),
('darkBlue', 'blue'),
('darkGreen', 'green'),
('goldenrod', 'yellow'),
))
# Variables globales
sequence = [] # Séquence jouée par l'ordi
sequenceJoueur = [] # Séquence jouée par le joueur
couleursIds = [] # identifiants des items couleurs du canevas
statuts = dict(
clic=False, # Stipule si les clics joueurs doivent être validés
indice=0, # Indice de la séquence courante à répéter
)
# Création de tous les widgets tkinter
root = tk.Tk()
root['bg'] = 'black'
can = tk.Canvas(
root, width=LARGEUR_COULEUR, height=HAUTEUR_COULEUR, bg='black',
highlightthickness=0
)
can.grid(padx=10, pady=10)
can.bind('<Button-1>', validerSequence)
# Création d'un itérateur simple des couleurs (clés du dict)
icouleurs = iter(COULEURS)
# Création des 4 quarts de couleurs
for start in range(90, 90*4+1, 90) :
# Obtention de la couleur via l'itérateur
couleur = next(icouleurs)
# Quarts de cercles principaux et >> RÉACTIFS AUX CLICS <<
iid = can.create_arc(
0, 0, LARGEUR_COULEUR, HAUTEUR_COULEUR,
extent=90, start=start, fill=couleur, outline=couleur
)
# Ajout de l'identifiant à la liste des ids
couleursIds.append(iid)
# Quarts de cercles centraux et >> NON RÉACTIFS AUX CLICS <<
can.create_arc(
LARGEUR_COULEUR/2-30, HAUTEUR_COULEUR/2-30,
LARGEUR_COULEUR/2+30, HAUTEUR_COULEUR/2+30,
extent=90, start=start, fill=COULEURS[couleur],
state=tk.DISABLED, outline=COULEURS[couleur]
)
# Arcs de cercles externes et >> NON RÉACTIFS AUX CLICS <<
can.create_arc(
4, 4, LARGEUR_COULEUR-4, HAUTEUR_COULEUR-4,
extent=90, start=start, style=tk.ARC, fill=COULEURS[couleur],
width=5, state=tk.DISABLED, outline=COULEURS[couleur]
)
# Texte destiné à afficher succinctement les messages du jeu.
labelInfo = tk.Label(root, bg='black', fg='green', font=('serif', -20, 'bold'))
labelInfo.grid(sticky=tk.NSEW, ipady=5)
# Bouton de démarrage du jeu
boutonJouer = tk.Button(root, text="Jouer", command=jouer)
boutonJouer.grid(sticky=tk.NSEW)
root.mainloop() |
Partager