Un petit jeu de morpion (tic-tac-toe) en python2.6.
- le premier script morbak500.pyw est relativement basique et est une réponse à la question que se posait un membre du site sur 'comment faire une interface Tkinter pour un morpion ?'.
- le deuxième morbak500c.pyw permet de changer de format (3x3,4x4,5x5) et contient une petite Intelligence Artificielle à 3 niveaux.
Source / Exemple :
# -*- coding: cp1252 -*-
################################################################################
# #
# Morbak 500 #
# #
# Jeu de morpion #
# version 2.1 #
# Langage : Python 2.6 #
# Auteur : Guillaume Michon #
# date 14/05/1013 #
################################################################################
from Tkinter import *
from random import randrange
def nouvelle_partie():
"""Méthode appelée à chaque nouvelle partie. Demande le nom des joueurs et leur type (humain/ordinateur)."""
global nomJoueur1,typeJoueur1,scoreJoueur1,niveauIntelOrdi1,nomJoueur2,typeJoueur2,scoreJoueur2,niveauIntelOrdi2,\
tempsRepOrdi,var,fenetre2,entree,rb_intelOrdi1,rb_intelOrdi2,joueurActif
#--- Réinitialisation des scores et des noms des joueurs ---#
nomJoueur1 = 'Joueur 1'
typeJoueur1 = 'humain'
scoreJoueur1 = 0
canevaJoueur1.itemconfig(textNomJoueur1,text=nomJoueur1)
canevaJoueur1.itemconfig(textScore1,text=str(scoreJoueur1))
niveauIntelOrdi1 = 0
nomJoueur2 = 'Joueur 2'
typeJoueur2 = 'humain'
scoreJoueur2 = 0
canevaJoueur2.itemconfig(textNomJoueur2,text=nomJoueur2)
canevaJoueur2.itemconfig(textScore2,text=str(scoreJoueur2))
niveauIntelOrdi2 = 0
tempsRepOrdi = 750 #- temps entre chaque coup de l'ordi
#--- Création des widgets de saisie de nom et de niveau d'intelligence de l'ordinateur pour le premier joueur ---#
var = 1
fenetre2 = Toplevel()
fenetre2.resizable(0,0)
tabGeometry = fenetre.geometry().split('+')
pos = '+' + tabGeometry[1] + '+' + tabGeometry[2]
fenetre2.geometry(pos)
fenetre2.wait_visibility()
fenetre2.grab_set()
fenetre2.transient(fenetre)
fenetre2.focus_force()
fenetre2.protocol("WM_DELETE_WINDOW",fermeture_croix)
label = Label(fenetre2,text='Nom du Joueur 1 :' )
label.grid(column=0,row=0)
entree = Entry(fenetre2,bd=5)
entree.bind('<Return>',recup_nom)
entree.grid(column=0,row=1)
label = Label(fenetre2,text='Ordinateur :')
label.grid(column=0,row=2)
rb_intelOrdi1 = IntVar()
tabTexteValeur = [('sans',0),('MouDuBulbe',40),('MrToulMonde',85),('Kasparov',100)]
ligne = 3
for texte,valeur in tabTexteValeur:
rb = Radiobutton(fenetre2,text=texte,variable=rb_intelOrdi1,value=valeur,command=sel_intelOrdi1)
rb.grid(column=0,row=ligne,sticky=W)
ligne += 1
label = Label(fenetre2,text='Entrer ou Croix pour valider')
label.grid(column=0,row=7)
#--- Attente de la fermeture de la fenêtre contenant ces widgets avant de poursuivre
fenetre.wait_window(fenetre2)
#--- Création des widgets de saisie de nom et de niveau d'intelligence de l'ordinateur pour le deuxième joueur ---#
var = 2
fenetre2 = Toplevel()
fenetre2.resizable(0,0)
fenetre2.geometry(pos)
fenetre2.wait_visibility()
fenetre2.grab_set()
fenetre2.transient(fenetre)
fenetre2.focus_force()
fenetre2.protocol("WM_DELETE_WINDOW",fermeture_croix)
label = Label(fenetre2,text='Nom du Joueur 2 :')
label.grid(column=0,row=0)
entree = Entry(fenetre2,bd=5)
entree.grid(column=0,row=1)
entree.bind('<Return>',recup_nom)
label = Label(fenetre2,text='Ordinateur :')
label.grid(column=0,row=2)
rb_intelOrdi2 = IntVar()
ligne = 3
for texte,valeur in tabTexteValeur:
rb = Radiobutton(fenetre2,text=texte,variable=rb_intelOrdi2,value=valeur,command=sel_intelOrdi2)
rb.grid(column=0,row=ligne,sticky=W)
ligne += 1
label = Label(fenetre2,text='Entrer ou Croix pour valider')
label.grid(column=0,row=7)
#--- Attente de la fermeture de la fenêtre contenant ces widgets avant de poursuivre
fenetre.wait_window(fenetre2)
#--- On determine le joueur qui a la main
joueurActif = randrange(1,3)
initialisation()
def fermeture_croix():
"""Méthode qui est invoquée quand on clique sur la croix de la fenêtre de saisie."""
recup_nom('<Return>')
def recup_nom(event):
"""Méthode qui récupère le nom saisie pour chaque joueur."""
global nomJoueur1,nomJoueur2
saisie = entree.get()
if var == 1:
if saisie != '':
nomJoueur1 = saisie
canevaJoueur1.itemconfig(textNomJoueur1,text=nomJoueur1)
else:
if saisie != '':
nomJoueur2 = saisie
canevaJoueur2.itemconfig(textNomJoueur2,text=nomJoueur2)
fenetre2.destroy()
def sel_intelOrdi1():
"""Méthode qui détermine le niveau d'intelligence de l'ordinateur 1 en fonction des choix de l'utilisateur."""
global niveauIntelOrdi1,typeJoueur1
niveauIntelOrdi1 = rb_intelOrdi1.get()
if niveauIntelOrdi1 == 0:
entree.delete(0,END)
typeJoueur1 = 'humain'
else:
typeJoueur1 = 'ordinateur'
tabTexteValeur = [('sans',0),('MouDuBulbe',40),('MrToulMonde',85),('Kasparov',100)]
for texteValeur in tabTexteValeur:
if niveauIntelOrdi1 == texteValeur[1]:
entree.delete(0,END)
entree.insert(0,texteValeur[0])
def sel_intelOrdi2():
"""Méthode qui détermine le niveau d'intelligence de l'ordinateur 2 en fonction des choix de l'utilisateur."""
global niveauIntelOrdi2,typeJoueur2
niveauIntelOrdi2 = rb_intelOrdi2.get()
if niveauIntelOrdi2 == 0:
entree.delete(0,END)
typeJoueur2 = 'humain'
else:
typeJoueur2 = 'ordinateur'
tabTexteValeur = [('sans',0),('MouDuBulbe',40),('MrToulMonde',85),('Kasparov',100)]
for texteValeur in tabTexteValeur:
if niveauIntelOrdi2 == texteValeur[1]:
entree.delete(0,END)
entree.insert(0,texteValeur[0])
def initialisation():
"""Méthode d'initialisation des variables de jeu."""
global matriceJeu,tabCasesGagnantes
# on efface tout
caneva.delete(ALL)
#on dessine la grille
grille_jeu()
# on initialise une matrice de jeu
matriceJeu = []
for i in range(nbrLigne):
matriceJeu.append([0]*nbrColonne)
# tableau qui contiendra les coordonnées matricielles des cases gagnantes
tabCasesGagnantes = []
# on cache tous les emotes
canevaJoueur1.itemconfigure(emoteJoueur1Gagne,state=HIDDEN)
canevaJoueur1.itemconfigure(emoteJoueur1Perdu,state=HIDDEN)
canevaJoueur1.itemconfigure(emoteJoueur1MatchNul,state=HIDDEN)
canevaJoueur2.itemconfigure(emoteJoueur2Gagne,state=HIDDEN)
canevaJoueur2.itemconfigure(emoteJoueur2Perdu,state=HIDDEN)
canevaJoueur2.itemconfigure(emoteJoueur1MatchNul,state=HIDDEN)
menuBarre.entryconfig(1,state=DISABLED)
# actions à exécuter en fonction du joueur qui a la main
if joueurActif == 1:
canevaJoueur1.config(bg='light green')
canevaJoueur2.config(bg='ivory')
if typeJoueur1 == 'humain':
caneva.bind('<Button-1>',click_souris)
else:
fenetre.after(tempsRepOrdi,coup_ordi,2,22)
else:
canevaJoueur2.config(bg='light green')
canevaJoueur1.config(bg='ivory')
if typeJoueur2 == 'humain':
caneva.bind('<Button-1>',click_souris)
else:
fenetre.after(tempsRepOrdi,coup_ordi,22,2)
def click_souris(event):
"""Méthode qui place le nombre du joueur humain qui a la main dans la matrice de jeu."""
global joueurActif
if event.x > margeGauche and event.x < margeGauche+(nbrLigne*largeurSprite) and event.y > margeHaut and event.y < margeHaut+(nbrColonne*hauteurSprite):
indiceColonne = (event.x-margeGauche)/largeurSprite
indiceLigne = (event.y-margeHaut)/hauteurSprite
if matriceJeu[indiceLigne][indiceColonne] == 0:
if joueurActif == 1:
matriceJeu[indiceLigne][indiceColonne] = 2
affichage()
verif_morpion(2,22)
else:
matriceJeu[indiceLigne][indiceColonne] = 22
verif_morpion(22,2)
affichage()
def coup_ordi(nombreJoueurActif,nombreAdversaire):
"""Fonction principale de l'intelligence artificielle."""
# l'algorithmie fonctionne par priorité mais en fonction de l'IA certaines d'entre-elles seront évitées (marge d'erreur):
# 1 - recherche d'un coup gagnant pour le joueur qui a la main
# 2 - recherche d'un coup gagnant pour l'adversaire, pour contrecarré ce coup
# 3 - recherche du coup le plus judicieux à jouer en fonction de la longueur des ensembles du joueur qui a la main
# 4 - placement au hazard
global joueurActif
caneva.unbind('<Button-1>')
# tableau contenant tous les coups possibles en coordonnée matricielle du joueur qui a la main
tabCoupsJoueurActifPossibles = []
# coordonnée matricielle du coup a jouer
coordCoup = None
if joueurActif == 1:
niveauIntelOrdi = niveauIntelOrdi1
else:
niveauIntelOrdi = niveauIntelOrdi2
# un jet de 100 est effectué, si sa valeur est supérieur au niveau de l'IA, certains algorithmes de recherche de positionnement seront évités
hazard = randrange(0,100)
if hazard <= niveauIntelOrdi:
#--- 1ère priorité
tabCoupsJoueurActifPossibles = recherche_coups_possibles(nombreJoueurActif,nombreAdversaire)
# si dans le tableau renvoyé par 'recherche_coups_possibles' une chaine de coups dans une direction n'a qu'un élément alors c'est un coup gagnant
for coup in tabCoupsJoueurActifPossibles:
if len(coup) == 1:
coordCoup = coup[0]
break
hazard = randrange(0,100)
if hazard <= niveauIntelOrdi:
#--- 2ème priorité
if not coordCoup :
tabCoupsAdversesPossibles = recherche_coups_possibles(nombreAdversaire,nombreJoueurActif)
# si dans le tableau renvoyé par 'recherche_coups_possibles' une chaine de coups dans une direction n'a qu'un élément alors c'est un coup gagnant
for coup in tabCoupsAdversesPossibles:
if len(coup) == 1:
coordCoup = coup[0]
break
hazard = randrange(0,100)
if hazard <= niveauIntelOrdi:
#--- 3ème priorité
if not coordCoup:
# si au moins une forme a été placée 'tabCoupsJoueurActifPossibles' n'est pas vide
if tabCoupsJoueurActifPossibles:
longeurRef = 1000
# tableau contenant les plus petites chaines de coups possibles
tabCoupsJudicieux = []
# remplissage de ce tableau
for chaineCoupsPossibles in tabCoupsJoueurActifPossibles:
if len(chaineCoupsPossibles) < longeurRef:
tabCoupsJudicieux = []
longeurRef = len(chaineCoupsPossibles)
tabCoupsJudicieux.append(chaineCoupsPossibles)
elif len(chaineCoupsPossibles) == longeurRef:
tabCoupsJudicieux.append(chaineCoupsPossibles)
# on tire au hazard une direction dans ce tableau
hazard = randrange(len(tabCoupsJudicieux))
directionRetenue = tabCoupsJudicieux[hazard]
# et dans la chaine retenue on tire au hazard une position
hazard = randrange(len(directionRetenue))
coordCoup = directionRetenue[hazard]
#--- 4ème priorité
if not coordCoup :
# tableau contenant tous les coups encore possibles
tabZero = []
for indiceLigne in range(len(matriceJeu)):
for indiceColonne in range(len(matriceJeu[0])):
if matriceJeu[indiceLigne][indiceColonne] == 0:
tabZero.append([indiceLigne,indiceColonne])
if tabZero:
hazard = randrange(0,len(tabZero))
coordCoup = tabZero[hazard]
else:
return
# on positionne le chiffre du joueur qui a la main dans la matrice de jeu
matriceJeu[coordCoup[0]][coordCoup[1]] = nombreJoueurActif
# on reactualise l'affichage
affichage()
# on verifie si un morpion s'est formé
verif_morpion(nombreJoueurActif,nombreAdversaire)
affichage()
def recherche_coups_possibles(nombre1,nombre2):
"""" Fonction de recherche de tous les positionnements possibles en ligne,colonne et diagonale (coord. matricielles des zéro) en fonction d'un chiffre particulier."""
global tabCasesGagnantes
# tableau contenant toutes les chaines de coups possibles
tabCoupsPossibles = []
#--- recherche en Ligne
indiceLigne = 0
for ligne in matriceJeu:
tabZero = [] # tableau contenant tous les zero de l'exploration dans une direction
tabCasesGagnantes = [] # le tableau contenant toutes les coordonées matricielles des cases gagnantes
if nombre1 in ligne and nombre2 not in ligne:
for indiceColonne in range(len(ligne)):
# dans chaque direction d'exploration le tableau de coord. des cases gagnantes est rempli des coordonnées d'exploration
tabCasesGagnantes.append([indiceLigne,indiceColonne])
if matriceJeu[indiceLigne][indiceColonne] == 0:
tabZero.append([indiceLigne,indiceColonne])
# si à la fin d'une exploration le tableau des zero est vide il y a forcemment morpion de formé
if not tabZero:
retour = 'morpion'
return retour
tabCoupsPossibles.append(tabZero)
indiceLigne += 1
#--- recherche en Colonne
for indiceColonne in range(len(matriceJeu[0])):
colonne = []
tabZero = []
tabCasesGagnantes = []
for indiceLigne in range(len(matriceJeu)):
colonne.append(matriceJeu[indiceLigne][indiceColonne])
if nombre1 in colonne and nombre2 not in colonne:
for indLigne in range(len(colonne)):
tabCasesGagnantes.append([indLigne,indiceColonne])
if colonne[indLigne] == 0:
tabZero.append([indLigne,indiceColonne])
if not tabZero:
retour = 'morpion'
return retour
tabCoupsPossibles.append(tabZero)
#--- recherche suivant la Diagonale gauche-droite
diagonale = []
tabZero = []
tabCasesGagnantes = []
for indiceLigneColonne in range(len(matriceJeu)):
diagonale.append(matriceJeu[indiceLigneColonne][indiceLigneColonne])
if nombre1 in diagonale and nombre2 not in diagonale:
for indiceLigneColonne in range(len(diagonale)):
tabCasesGagnantes.append([indiceLigneColonne,indiceLigneColonne])
if diagonale[indiceLigneColonne] == 0:
tabZero.append([indiceLigneColonne,indiceLigneColonne])
if not tabZero:
retour = 'morpion'
return retour
tabCoupsPossibles.append(tabZero)
#--- recherche suivant la Diagonale droite-gauche
diagonale = []
tabZero = []
tabCasesGagnantes = []
for indiceLigneColonne in range(len(matriceJeu)):
diagonale.append(matriceJeu[indiceLigneColonne][len(matriceJeu[0])-1-indiceLigneColonne])
if nombre1 in diagonale and nombre2 not in diagonale:
for indiceLigneColonne in range(len(diagonale)):
tabCasesGagnantes.append([indiceLigneColonne,len(matriceJeu[0])-1-indiceLigneColonne])
if diagonale[indiceLigneColonne] == 0:
tabZero.append([indiceLigneColonne,len(matriceJeu[0])-1-indiceLigneColonne])
if not tabZero:
retour = 'morpion'
return retour
tabCoupsPossibles.append(tabZero)
tabZero = []
tabCasesGagnantes = []
for indiceLigne in range(len(matriceJeu)):
for indiceColonne in range(len(matriceJeu[0])):
if matriceJeu[indiceLigne][indiceColonne] == 0:
tabZero.append([indiceLigne,indiceColonne])
return tabCoupsPossibles
def verif_morpion(nombreJoueurActif,nombreAdversaire):
"""Méthode qui vérifie si un morpion s'est formé."""
# 'recherche_coups_possibles' renvoie soit un tableau de coord. de zéro correspondant aux placements possibles qui peuvent encore faire un morpion
# soit un tableau vide si ce n'est plus le cas, soit le mot 'morpion' si le dernier placement en a formé un
retourDeRecherche = recherche_coups_possibles(nombreJoueurActif,nombreAdversaire)
# si 'recherche_coups_possibles' a renvoyé un tableau de coord de zéro vide ou non
if retourDeRecherche != 'morpion':
la_main_passe()
# si ce tableau est vide on regarde si des zéro sont encore présent dans la matrice de jeu
if not retourDeRecherche:
matchNul = True
for ligne in matriceJeu:
if 0 in ligne:
matchNul = False
if matchNul:
menuBarre.entryconfig(1,state=ACTIVE)
canevaJoueur1.itemconfigure(emoteJoueur1MatchNul,state=NORMAL)
canevaJoueur2.itemconfigure(emoteJoueur1MatchNul,state=NORMAL)
# si 'recherche_coups_possibles' a décelé un morpion
elif retourDeRecherche == 'morpion':
affichage()
partie_gagnee()
def la_main_passe():
""""Méthode qui effectue les actions nécessaires lorsque la main passe."""
global joueurActif
joueurActif += 1
if joueurActif == 3:
joueurActif = 1
if joueurActif == 1 :
canevaJoueur1.config(bg='light green')
canevaJoueur2.config(bg='ivory')
if typeJoueur1 == 'humain':
caneva.bind('<Button-1>',click_souris)
else:
fenetre.after(1000,coup_ordi,2,22)
else:
canevaJoueur2.config(bg='light green')
canevaJoueur1.config(bg='ivory')
if typeJoueur2 == 'humain':
caneva.bind('<Button-1>',click_souris)
else:
fenetre.after(tempsRepOrdi,coup_ordi,22,2)
def partie_gagnee():
""""Méthode qui effectue les actions nécessaires lorsque la partie est gagnée."""
global scoreJoueur1,scoreJoueur2
caneva.unbind('<Button-1>')
menuBarre.entryconfig(1,state=ACTIVE)
if joueurActif == 1 :
scoreJoueur1 += 1
canevaJoueur1.itemconfig(textScore1,text=str(scoreJoueur1))
canevaJoueur1.itemconfigure(emoteJoueur1Gagne,state=NORMAL)
canevaJoueur2.itemconfigure(emoteJoueur1Perdu,state=NORMAL)
else:
scoreJoueur2 += 1
canevaJoueur2.itemconfig(textScore2,text=str(scoreJoueur2))
canevaJoueur1.itemconfigure(emoteJoueur1Perdu,state=NORMAL)
canevaJoueur2.itemconfigure(emoteJoueur1Gagne,state=NORMAL)
def affichage():
"""Méthode actualisant l'affichage de la mtrice de jeu."""
for indiceLigne in range(len(matriceJeu)):
for indiceColonne in range(len(matriceJeu[0])):
coordX = margeGauche+(indiceColonne*largeurSprite)
coordY = margeHaut+(indiceLigne*hauteurSprite)
if matriceJeu[indiceLigne][indiceColonne] == 2:
caneva.create_image(coordX,coordY,image=imageCroix,anchor=NW)
if matriceJeu[indiceLigne][indiceColonne] == 22:
caneva.create_image(coordX,coordY,image=imageRond,anchor=NW)
if tabCasesGagnantes:
for case in tabCasesGagnantes:
rectangle = caneva.create_rectangle(case[1]*largeurSprite+margeGauche,case[0]*hauteurSprite+margeHaut,
case[1]*largeurSprite+margeGauche+largeurSprite,case[0]*largeurSprite+margeHaut+hauteurSprite,fill='gold')
caneva.lower(rectangle)
def grille_jeu():
"""Méthode affichant la grille de jeu."""
for coordY_ligne in range(margeHaut,(nbrLigne*hauteurSprite)+margeHaut+1,hauteurSprite):
if (coordY_ligne-margeHaut) % (nbrLigne*hauteurSprite) == 0:
epaisseur = 5
else:
epaisseur = 1
caneva.create_line(margeGauche,coordY_ligne,(nbrColonne*largeurSprite)+margeGauche,coordY_ligne,width=epaisseur)
for coordX_colonne in range(margeGauche,(nbrColonne*largeurSprite)+margeGauche+1,largeurSprite):
if (coordX_colonne-margeGauche) % (nbrColonne*largeurSprite) == 0:
epaisseur = 5
else:
epaisseur = 2
caneva.create_line(coordX_colonne,margeHaut,coordX_colonne,(nbrLigne*hauteurSprite)+margeHaut,width=epaisseur)
def format3x3():
"""Méthode passant la matrice de jeu et le caneva principal au format 3x3."""
global nbrLigne,nbrColonne
nbrLigne = nbrColonne = 3
caneva.delete(ALL)
caneva.config(width=(2*margeGauche)+(nbrColonne*largeurSprite),height=(2*margeHaut)+(nbrLigne*hauteurSprite))
canevaJoueur1.config(width=150,height=(2*margeHaut)+(nbrLigne*hauteurSprite))
canevaJoueur2.config(width=150,height=(2*margeHaut)+(nbrLigne*hauteurSprite))
grille_jeu()
nouvelle_partie()
def format4x4():
"""Méthode passant la matrice de jeu et le caneva principal au format 4x4."""
global nbrLigne,nbrColonne
nbrLigne = nbrColonne = 4
caneva.delete(ALL)
caneva.config(width=(2*margeGauche)+(nbrColonne*largeurSprite),height=(2*margeHaut)+(nbrLigne*hauteurSprite))
canevaJoueur1.config(width=150,height=(2*margeHaut)+(nbrLigne*hauteurSprite))
canevaJoueur2.config(width=150,height=(2*margeHaut)+(nbrLigne*hauteurSprite))
grille_jeu()
nouvelle_partie()
def format5x5():
"""Méthode passant la matrice de jeu et le caneva principal au format 5x5."""
global nbrLigne,nbrColonne
nbrLigne = nbrColonne = 5
caneva.delete(ALL)
caneva.config(width=(2*margeGauche)+(nbrColonne*largeurSprite),height=(2*margeHaut)+(nbrLigne*hauteurSprite))
canevaJoueur1.config(width=150,height=(2*margeHaut)+(nbrLigne*hauteurSprite))
canevaJoueur2.config(width=150,height=(2*margeHaut)+(nbrLigne*hauteurSprite))
grille_jeu()
nouvelle_partie()
def quitter():
"""Quitte l'application."""
fenetre.quit()
fenetre.destroy()
if __name__ == '__main__':
#--- Fenêtre Principale ---
fenetre = Tk()
fenetre.configure(bg='light blue')
fenetre.title("Morbak500")
fenetre.resizable(0,0)
hauteurEcran = fenetre.winfo_height()
largeurEcran = fenetre.winfo_width()
fenetre.winfo_screenwidth()
pos_x = str(((fenetre.winfo_screenwidth()-largeurEcran)/2)-300)
pos_y = str(((fenetre.winfo_screenheight()-hauteurEcran)/2)-300)
pos = '+' + pos_x + '+' + pos_y
fenetre.geometry(pos)
#--- Chargement des images ---
imageCroix = PhotoImage(file="croix.gif")
imageRond = PhotoImage(file="rond.gif")
imageEmoteGagne = PhotoImage(file="emoteGagne.gif")
imageEmotePerdu = PhotoImage(file="emotePerdu.gif")
imageEmoteMatchNul = PhotoImage(file="emoteMatchNul.gif")
#--- Variables de mise en forme ---
largeurSprite = imageCroix.width()
hauteurSprite = imageRond.height()
margeGauche, margeHaut = 20, 20
nbrLigne, nbrColonne = 3, 3
#--- Caneva principal ---
caneva = Canvas(fenetre,bg='light blue',width=(2*margeGauche)+(nbrColonne*largeurSprite),height=(2*margeHaut)+(nbrLigne*hauteurSprite),relief='groove')
caneva.grid(row=0,column=1)
#--- Caneva du joueur 1 ---
canevaJoueur1 = Canvas(fenetre,bg='ivory',width=150,height=(2*margeHaut)+(nbrLigne*hauteurSprite),relief='ridge')
canevaJoueur1.grid(row=0,column=0)
canevaJoueur1.create_image(40,10,image=imageCroix,anchor=NW)
nomJoueur1 = 'Joueur 1'
textNomJoueur1 = canevaJoueur1.create_text(75,100,text=nomJoueur1,anchor=N,font="Century 16 normal bold",fill='black')
scoreJoueur1 = 0
textScore1 = canevaJoueur1.create_text(75,150,text=str(scoreJoueur1),anchor=N,font="Century 28 normal bold",fill='black')
emoteJoueur1Gagne = canevaJoueur1.create_image(45,200,image=imageEmoteGagne,anchor=NW,state=HIDDEN)
emoteJoueur1Perdu = canevaJoueur1.create_image(45,200,image=imageEmotePerdu,anchor=NW,state=HIDDEN)
emoteJoueur1MatchNul = canevaJoueur1.create_image(45,200,image=imageEmoteMatchNul,anchor=NW,state=HIDDEN)
#--- Caneva du joueur 2 ---
canevaJoueur2 = Canvas(fenetre,bg='ivory',width=150,height=(2*margeHaut)+(nbrLigne*hauteurSprite),relief='ridge')
canevaJoueur2.grid(row=0,column=2)
canevaJoueur2.create_image(40,10,image=imageRond,anchor=NW)
nomJoueur2 = 'Joueur 2'
textNomJoueur2 = canevaJoueur2.create_text(75,100,text=nomJoueur2,anchor=N,font="Century 16 normal bold",fill='black')
scoreJoueur2 = 0
textScore2 = canevaJoueur2.create_text(75,150,text=str(scoreJoueur2),anchor=N,font="Century 28 normal bold",fill='black')
emoteJoueur2Gagne = canevaJoueur2.create_image(45,200,image=imageEmoteGagne,anchor=NW,state=HIDDEN)
emoteJoueur2Perdu = canevaJoueur2.create_image(45,200,image=imageEmotePerdu,anchor=NW,state=HIDDEN)
emoteJoueur2MatchNul = canevaJoueur2.create_image(45,200,image=imageEmoteMatchNul,anchor=NW,state=HIDDEN)
#--- Barre de menu ---
menuBarre = Menu(fenetre,tearoff=0)
fenetre.config(menu=menuBarre)
menuNllePartie = Menu(menuBarre,tearoff=0)
menuBarre.add_cascade(label='Nouvelle Partie',menu=menuNllePartie)
menuFormat = Menu(menuNllePartie)
menuNllePartie.add_cascade(label='Format',menu=menuFormat)
menuFormat.add_radiobutton(label='3x3',command=format3x3)
menuFormat.add_radiobutton(label='4x4',command=format4x4)
menuFormat.add_radiobutton(label='5x5',command=format5x5)
menuBarre.add_command(label='Nouvelle Manche',command=initialisation,state=DISABLED)
menuNllePartie.add_separator()
menuNllePartie.add_command(label='Quitter',command=quitter)
grille_jeu()
fenetre.mainloop()
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.