Find all about S.I

mardi 8 octobre 2013

Code source python: jeu de morpion (tic-tac-toe)

DESCRIPTION

Un petit jeu de morpion (tic-tac-toe) développé 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()

Aucun commentaire:

Enregistrer un commentaire