Partage
  • Partager sur Facebook
  • Partager sur Twitter

Projet ISN : IA Morpion

    29 avril 2015 à 23:59:50

    Bonjour à toutes et à tous. Je suis parvenu à créer un jeu en python permettant de jouer à deux joueurs au morpion sur un même tableau avec Tkinter.

    Souhaitant continuer sur cette voie, je suis parvenu (en partant d'un exercice n'utilisant pas mon programme) à créer mon IA sur mon morpion, sans Tkinter.

    Seulement voilà, il s'agit là de deux programmes différents, et je n'arrive pas à intégrer l'IA comme je souhaiterait le faire sur mon programme avec Tkinter, ou à mettre en lien les deux programmes de façon à ce que lorsque l'on appuie sur le bouton 'jouer contre l'IA', le jeu se mette en jeu 1 joueur ou l'on peut jouer avec l'IA.

    Le premier programme utilisant des images, je me suis permi de l'héberger afin que vous puissiez le faire fonctionner : https://www.dropbox.com/sh/6ftqabnskll5rx1/AAAKColoIxlHeSFyr1PZ5ycda?dl=0

    Il est de cette forme : 

    from tkinter import *  # On importe l'interface graphique tkinter
    
    TableauDeJeu = [[0, 0, 0], [0, 0, 0],[0, 0, 0]]  # On initialise le tableau de jeu
    TableauDeParametre = [1, 0, 0, 0]  # On initialise l'ordre de jeu et les scores
    Fenetre = Tk()  # On ouvre la fenetre grace à tkinter
    Fenetre.title("Projet - Morpion")  # Nom de la fenetre
    Fenetre.configure(background='black')  # Couleur du fond
    
    ImageVide = PhotoImage(file="Images\Vide.png")  # Images correspondantes
    ImageRond = PhotoImage(file="Images\Rond.png")  #
    ImageCroix = PhotoImage(file="Images\Croix.png")  #
    
    
    def Message(texte, Label):  # On définit la fonction pour les messages à afficher
        Label.config(text=texte)
    
    
    def ChangerdeJoueur(joueur):  # On définit la fonction pour changer de joueur -- Iris
        if joueur == 1:
            joueur = 2
        else:
            joueur = 1
        Message(('Joueur ' + str(joueur) + ' à votre tour !'),
                ChampLabel)  #On affiche un message pour indiquer le changement de joueur
        return joueur
    
    
    def CoordonneeVersBoutons(col, l):  # On définit les boutons par rapport aux coordonnées en fonction des lignes / cases -- Iris
        if l == 0 and col == 0:
            return Bouton1
        if l == 0 and col == 1:
            return Bouton2
        if l == 0 and col == 2:
            return Bouton3
        if l == 1 and col == 0:
            return Bouton4
        if l == 1 and col == 1:
            return Bouton5
        if l == 1 and col == 2:
            return Bouton6
        if l == 2 and col == 0:
            return Bouton7
        if l == 2 and col == 1:
            return Bouton8
        if l == 2 and col == 2:
            return Bouton9
    
    
    def JoueurVersIcone(joueur):  # On définit l'image à utiliser en fonction du joueur -- Bastien
        if joueur[0] == 1:
            return ImageCroix
        else:
            return ImageRond
    
    
    def VerificationMatchnul(tab):  # On définit la fonction en cas de match nul -- Bastien
        matchnul = 0
        compzero = 0
    
        for i in range(3):
            for j in range(3):
                if tab[i][j] == 0:          #Si on ne peut plus remplir aucune case et si personne n'a gagné
                    compzero = compzero + 1
    
        if compzero == 0:                   #On obtient alors un match nul
            matchnul = 1
        else:
            matchnul = 0                    #Si non, pas de match nul
        return matchnul
    
    
    def ActiverBouton():                        #On définit la fonction qui active tous les boutons -- Bastien
        Bouton1.configure(state=ACTIVE)
        Bouton2.configure(state=ACTIVE)
        Bouton3.configure(state=ACTIVE)
        Bouton4.configure(state=ACTIVE)
        Bouton5.configure(state=ACTIVE)
        Bouton6.configure(state=ACTIVE)
        Bouton7.configure(state=ACTIVE)
        Bouton8.configure(state=ACTIVE)
        Bouton9.configure(state=ACTIVE)
    
    
    def DesactiverBouton():                     #On définit la fonction qui désactive tous les boutons -- Bastien
        Bouton1.configure(state=DISABLED)
        Bouton2.configure(state=DISABLED)
        Bouton3.configure(state=DISABLED)
        Bouton4.configure(state=DISABLED)
        Bouton5.configure(state=DISABLED)
        Bouton6.configure(state=DISABLED)
        Bouton7.configure(state=DISABLED)
        Bouton8.configure(state=DISABLED)
        Bouton9.configure(state=DISABLED)
    
    
    def InitialisationPartie(tab, tabparam):    #On définit la fonction initialisant la partie grille / joueur etc. -- Iris
        for ligne in range(3):
            for colonne in range(3):
                tab[ligne][colonne] = 0
    
        ActiverBouton()
        InitialisationBouton()
    
    
        # Fonction qui choisit au hasard qui commence
        if random.randint(0, 1) == 0:
            tabparam[0] = 1
        else:
            tabparam[0] = 2
    
        Message(('Joueur ' + str(tabparam[0]) + ' à votre tour !'), ChampLabel)
    
    
    def InitialisationBouton():                     #On définit toutes les cases comme vides grâce à l'image vide -- Iris
        Bouton1.configure(image=ImageVide)
        Bouton2.configure(image=ImageVide)
        Bouton3.configure(image=ImageVide)
        Bouton4.configure(image=ImageVide)
        Bouton5.configure(image=ImageVide)
        Bouton6.configure(image=ImageVide)
        Bouton7.configure(image=ImageVide)
        Bouton8.configure(image=ImageVide)
        Bouton9.configure(image=ImageVide)
    
    
    def EvenementClicBouton(tab, tabparam, col, l):    #On définit la fonction qui permettera à l'appli de réagir aux inputs -- Iris & Bastien
        BoutonX = CoordonneeVersBoutons(col, l)        #On établit le lien avec les boutons définis précedemment
        if BoutonX.__getitem__('state') != DISABLED:
            if tab[l][col] == 0:        #Si les coordonnées sont libres
                tab[l][col] = tabparam[0]
    
                BoutonX.configure(image=JoueurVersIcone(tabparam))  #On regarde quelle image utiliser
    
                if VerificationVictoire(tab) == 1:      #si le joueur 1 a gagné
                    Message(('Le joueur ' + str(tabparam[0]) + ' gagne !'), ChampLabel)     #Message informatif
                    DesactiverBouton()      #On désactive les boutons
    
                    if tabparam[0] == 1:    #Boucle pour ajouter la victoire du 11 au compteur
                        tabparam[1] = tabparam[1] + 1
                        Message(('Nombre de victoire joueur 1 : ' + str(tabparam[1])), VictoireJoueur1)
                    else:
                        tabparam[2] = tabparam[2] + 1 #Sinon et pas match nul, victoire J2
                        Message(('Nombre de victoire joueur 2 : ' + str(tabparam[2])), VictoireJoueur2)
    
                elif VerificationMatchnul(tab) == 1:    #On vérifie le match nul
                    DesactiverBouton()
                    tabparam[3] = tabparam[3] + 1       #On comptabilise la match nul
                    Message(('Match Nul'), ChampLabel)  #On informe du match nul
                    Message(('Nombre de match nul : ' + str(tabparam[3])), VictoireMatchNul)    #On affiche nb de matchs nul
    
                else:
                    tabparam[0] = ChangerdeJoueur(tabparam[0])
    
            else:
                Message(('Les coordonnées sont déjà prises.\n\rVous pouvez rejouer joueur ' + str(tabparam[0])), ChampLabel)
    
    
    def VerificationVictoire(tab):          #On définit toutes les possibilités selon lesquelles il y a une victoire -- Iris
        victoire = 0
    
        if tab[0][0] != 0 and tab[0][0] == tab[1][1] and tab[1][1] == tab[2][2]:
            victoire = 1
        elif tab[0][2] != 0 and tab[0][2] == tab[1][1] and tab[1][1] == tab[2][0]:
            victoire = 1
        elif tab[0][0] != 0 and tab[0][0] == tab[0][1] and tab[0][1] == tab[0][2]:
            victoire = 1
        elif tab[1][0] != 0 and tab[1][0] == tab[1][1] and tab[1][1] == tab[1][2]:
            victoire = 1
        elif tab[2][0] != 0 and tab[2][0] == tab[2][1] and tab[2][1] == tab[2][2]:
            victoire = 1
        elif tab[0][0] != 0 and tab[0][0] == tab[1][0] and tab[1][0] == tab[2][0]:
            victoire = 1
        elif tab[0][1] != 0 and tab[0][1] == tab[1][1] and tab[1][1] == tab[2][1]:
            victoire = 1
        elif tab[0][2] != 0 and tab[0][2] == tab[1][2] and tab[1][2] == tab[2][2]:
            victoire = 1
        return victoire
    
    
    
    #Toutes les lignes suivantes décrivent l'image, les ombres, le bouton à appuyer pour le déclencher,les
    #coordonnées qui se comptabilisent et la position des boutons sur lesquels on peut appuyer -- Bastien & Iris
    
    
    Bouton1 = Button(Fenetre)
    Bouton1.configure(image=ImageVide, relief=GROOVE)
    Bouton1.bind("<ButtonPress-1>",
                 lambda event, tab=TableauDeJeu, joueur=TableauDeParametre, col=0, l=0: EvenementClicBouton(tab, joueur,
                                                                                                            col, l))
    Bouton1.grid(row=0, column=1, padx=3, pady=3)
    
    Bouton2 = Button(Fenetre)
    Bouton2.configure(image=ImageVide, relief=GROOVE)
    Bouton2.bind("<ButtonPress-1>",
                 lambda event, tab=TableauDeJeu, joueur=TableauDeParametre, col=1, l=0: EvenementClicBouton(tab, joueur,
                                                                                                            col, l))
    Bouton2.grid(row=0, column=2, padx=3, pady=3)
    
    Bouton3 = Button(Fenetre)
    Bouton3.configure(image=ImageVide, relief=GROOVE)
    Bouton3.bind("<ButtonPress-1>",
                 lambda event, tab=TableauDeJeu, joueur=TableauDeParametre, col=2, l=0: EvenementClicBouton(tab, joueur,
                                                                                                            col, l))
    Bouton3.grid(row=0, column=3, padx=3, pady=3)
    
    Bouton4 = Button(Fenetre)
    Bouton4.configure(image=ImageVide, relief=GROOVE)
    Bouton4.bind("<ButtonPress-1>",
                 lambda event, tab=TableauDeJeu, joueur=TableauDeParametre, col=0, l=1: EvenementClicBouton(tab, joueur,
                                                                                                            col, l))
    Bouton4.grid(row=1, column=1, padx=3, pady=3)
    
    Bouton5 = Button(Fenetre)
    Bouton5.configure(image=ImageVide, relief=GROOVE)
    Bouton5.bind("<ButtonPress-1>",
                 lambda event, tab=TableauDeJeu, joueur=TableauDeParametre, col=1, l=1: EvenementClicBouton(tab, joueur,
                                                                                                            col, l))
    Bouton5.grid(row=1, column=2, padx=3, pady=3)
    
    Bouton6 = Button(Fenetre)
    Bouton6.configure(image=ImageVide, relief=GROOVE)
    Bouton6.bind("<ButtonPress-1>",
                 lambda event, tab=TableauDeJeu, joueur=TableauDeParametre, col=2, l=1: EvenementClicBouton(tab, joueur,
                                                                                                            col, l))
    Bouton6.grid(row=1, column=3, padx=3, pady=3)
    
    Bouton7 = Button(Fenetre)
    Bouton7.configure(image=ImageVide, relief=GROOVE)
    Bouton7.bind("<ButtonPress-1>",
                 lambda event, tab=TableauDeJeu, joueur=TableauDeParametre, col=0, l=2: EvenementClicBouton(tab, joueur,
                                                                                                            col, l))
    Bouton7.grid(row=2, column=1, padx=3, pady=3)
    
    Bouton8 = Button(Fenetre)
    Bouton8.configure(image=ImageVide, relief=GROOVE)
    Bouton8.bind("<ButtonPress-1>",
                 lambda event, tab=TableauDeJeu, joueur=TableauDeParametre, col=1, l=2: EvenementClicBouton(tab, joueur,
                                                                                                            col, l))
    Bouton8.grid(row=2, column=2, padx=3, pady=3)
    
    Bouton9 = Button(Fenetre)
    Bouton9.configure(image=ImageVide, relief=GROOVE)
    Bouton9.bind("<ButtonPress-1>",
                 lambda event, tab=TableauDeJeu, joueur=TableauDeParametre, col=2, l=2: EvenementClicBouton(tab, joueur,
                                                                                                            col, l))
    Bouton9.grid(row=2, column=3, padx=3, pady=3)
    
    BoutonRejouer = Button(Fenetre)
    BoutonRejouer.configure(width='6', height='3', text='Rejouer', )
    BoutonRejouer.grid(row=2, column=0)
    BoutonRejouer.bind("<ButtonPress-1>",
                       lambda event, tab=TableauDeJeu, tabparam=TableauDeParametre: InitialisationPartie(tab, tabparam))
    
    BoutonIA = Button(Fenetre)
    BoutonIA.configure(width='30', height='3', relief=GROOVE, text = "Jouer contre l'IA",)
    BoutonIA.grid(row=3, column=4)
    BoutonIA.bind("<ButtonPress-1>",
                  lambda event, tab=TableauDeJeu, joueur=TableauDeParametre : IA)
    
    
    
    #Les lignes suivantes décrivent la taille, la couleur, les ombres, la position des messages interactifs -- Iris & Bastien
    
    
    ChampLabel = Label(Fenetre)
    ChampLabel.configure(width='30', height='5', relief=GROOVE, bg="beige", bd=9)
    ChampLabel.grid(row=1, column=0, padx=25, pady=0)
    Message(('Joueur ' + str(TableauDeParametre[0]) + ' à votre tour !'), ChampLabel)
    
    VictoireJoueur1 = Label(Fenetre)
    VictoireJoueur1.configure(width='30', height='5', relief=GROOVE, bg="beige", bd=3)
    VictoireJoueur1.grid(row=0, column=4, padx=25, pady=0)
    Message(('Victoire(s) du joueur 1 : ' + str(TableauDeParametre[1])), VictoireJoueur1)
    
    VictoireJoueur2 = Label(Fenetre)
    VictoireJoueur2.configure(width='30', height='5', relief=GROOVE, bg="beige", bd=3)
    VictoireJoueur2.grid(row=1, column=4, padx=25, pady=0)
    Message(('Victoire(s) du joueur 2 : ' + str(TableauDeParametre[2])), VictoireJoueur2)
    
    VictoireMatchNul = Label(Fenetre)
    VictoireMatchNul.configure(width='30', height='5', relief=GROOVE, bg="beige", bd=3)
    VictoireMatchNul.grid(row=2, column=4, padx=25, pady=0)
    Message(('Nombre de match nul : ' + str(TableauDeParametre[3])), VictoireMatchNul)
    
    Realisation = Label(Fenetre)
    Realisation.configure(width='30', height='5', bg='beige')
    Realisation.grid(row=3, column=0, padx=25, pady=0)
    Message("Par Iris et Bastien", Realisation)
    
    Fenetre.mainloop()
    

    L'IA est comme ceci : 

    __author__ = 'Bastien'
    # IA moyenne :
    
    import random
    
    def initableau(case):
        # Cette fonction définit la grille 3x3 qui sera utilisée par l'ia
    
        # "board" est une liste de 10 strings représentant la grille (on ignore l'index 0)
        print('   |   |')
        print(' ' + case[7] + ' | ' + case[8] + ' | ' + case[9])
        print('   |   |')
        print('-----------')
        print('   |   |')
        print(' ' + case[4] + ' | ' + case[5] + ' | ' + case[6])
        print('   |   |')
        print('-----------')
        print('   |   |')
        print(' ' + case[1] + ' | ' + case[2] + ' | ' + case[3])
        print('   |   |')
    
    def LettreJoueur():
        # On laisse le choix au joueur du signe qu'il souhaite utiliser
        # Retourne une liste avec le signe du joueur en premier, et celui de l'ordinateur en deuxieme
        letter = ''
        while not (letter == 'X' or letter == 'O'):
            print('Voulez jouer les X ou les O?')
            letter = input().upper()
    
        # Le premier signe est donc celui entré et joué par le joueur, le second est celui qui sera joué par l'ordi
        if letter == 'X':
            return ['X', 'O']
        else:
            return ['O', 'X']
    
    def QuiCommence():
        # Fonction qui choisit au hasard qui commence
        if random.randint(0, 1) == 0:
            return 'computer'
        else:
            return 'player'
    
    def Rejouer():
        # On permet au joueur de recommencer si il le souhaite
        print('Rejouer ? (oui ou non)')
        return input().lower().startswith('o')
    
    def Jouer(case, letter, move):
        case[move] = letter
    
    def Gagne(bo, le):
        # Cette fonction retourne 'gagnant' si le joueur a gagné
        # On utilise le board ainsi que la lettre utilisée pour ne pas avoir à trop développer
        return ((bo[7] == le and bo[8] == le and bo[9] == le) or # ligne du haut
        (bo[4] == le and bo[5] == le and bo[6] == le) or # ligne du milieu
        (bo[1] == le and bo[2] == le and bo[3] == le) or # ligne du bas
        (bo[7] == le and bo[4] == le and bo[1] == le) or # colonne de gauche
        (bo[8] == le and bo[5] == le and bo[2] == le) or # colonne du milieu
        (bo[9] == le and bo[6] == le and bo[3] == le) or # colonne de droite
        (bo[7] == le and bo[5] == le and bo[3] == le) or # diagonale partant d'en haut à gauche
        (bo[9] == le and bo[5] == le and bo[1] == le)) # diagonale partant d'en bas à gauche
    
    def CopieGrille(case):
        # On effectue une copie du tableau pour le réutiliser à chaque tour
        dupeBoard = []
    
        for i in case:
            dupeBoard.append(i)
    
        return dupeBoard
    
    def PlaceRestante(case, move):
        #Fonction pour vérifier la place
        return case[move] == ' '
    
    def MouvementJoueur(case):
        # Fonction qui laisse au joueur le soin de décider où il va jouer
        move = ' '
        while move not in '1 2 3 4 5 6 7 8 9'.split() or not PlaceRestante(case, int(move)):
            print('Où souhaitez vous jouer (entrez un chiffre de 1 à 9)')
            move = input()
        return int(move)
    
    def MouvementAleatListe(case, movesList):
        # Cette fonction retourne un coup valide en fonction des cases de libres
        # Elle ne retourne rien si il n'y a pas de case libre
        possibleMoves = []
        for i in movesList:
            if PlaceRestante(case, i):
                possibleMoves.append(i)
    
        if len(possibleMoves) != 0:
            return random.choice(possibleMoves)
        else:
            return None
    
    def MouvementOrdi(case, computerLetter):
        #Grâce à une case et au signe de l'ordinateur, on détermine où jouer et la fonction retourne ce coup.
        if computerLetter == 'X':
            playerLetter = 'O'
        else:
            playerLetter = 'X'
    
        # L'IA du Morpion commence réellement ici
        # On regarde si on peut gagner au prochain coup
        for i in range(1, 10):
            copy = CopieGrille(case)
            if PlaceRestante(copy, i):
                Jouer(copy, computerLetter, i)
                if Gagne(copy, computerLetter):
                    return i
    
        # On regarde si le joueur pourrait gagner lors de son prochain coup pour le bloquer
        for i in range(1, 10):
            copy = CopieGrille(case)
            if PlaceRestante(copy, i):
                Jouer(copy, playerLetter, i)
                if Gagne(copy, playerLetter):
                    return i
    
        # On tente de jouer sur l'un des coins, si ils sont libres
        move = MouvementAleatListe(case, [1, 3, 7, 9])
        if move != None:
            return move
    
        # On essaye de prendre le centre si il est libre
        if PlaceRestante(case, 5):
            return 5
    
        # On joue sur l'un des côtés
        return MouvementAleatListe(case, [2, 4, 6, 8])
    
    def GrilleRemplie(case):
        # Cette fonction retourne vrai si la grille est completement remplie. Sinon, elle retourne faux
        for i in range(1, 10):
            if PlaceRestante(case, i):
                return False
        return True
    
    
    print('Bienvenue sur le jeu de Morpion')
    
    while True:
        # On reset la grille
        theBoard = [' '] * 10
        playerLetter, computerLetter = LettreJoueur()
        turn = QuiCommence()
        print('Le ' + turn + ' commence')
        gameIsPlaying = True
    
        while gameIsPlaying:
            if turn == 'player':
                # Tour du joueur
                initableau(theBoard)
                move = MouvementJoueur(theBoard)
                Jouer(theBoard, playerLetter, move)
    
                if Gagne(theBoard, playerLetter):
                    initableau(theBoard)
                    print('Bien joué !Vous avez gagné')
                    gameIsPlaying = False
                else:
                    if GrilleRemplie(theBoard):
                        initableau(theBoard)
                        print('Match nul')
                        break
                    else:
                        turn = 'computer'
    
            else:
                # Tour de l'ordinateur
                move = MouvementOrdi(theBoard, computerLetter)
                Jouer(theBoard, computerLetter, move)
    
                if Gagne(theBoard, computerLetter):
                    initableau(theBoard)
                    print('L IA gagne ! Vous avez perdu.')
                    gameIsPlaying = False
                else:
                    if GrilleRemplie(theBoard):
                        initableau(theBoard)
                        print('Match Nul !')
                        break
                    else:
                        turn = 'player'
    
        if not Rejouer():
            break

    En vous remerciant d'avance pour votre aide !

    -
    Edité par Conymore 30 avril 2015 à 0:00:35

    • Partager sur Facebook
    • Partager sur Twitter
      22 mai 2015 à 18:07:33

      salut a  toi :)

      je debute en prog et je realise mon projet pour l'isn mais j'ai un petit probleme.Je cherche une fonction pour la detection match nul donc je suis tomber sur ton programme mais je n'arrive pas le faire fonctionner avec mon programme?

      def VerificationMatchnul(tab):  # On définit la fonction en cas de match nul -- Bastien
          matchnul = 0
          compzero = 0
       
          for i in range(3):
              for j in range(3):
                  if tab[i][j] == 0:          #Si on ne peut plus remplir aucune case et si personne n'a gagné
                      compzero = compzero + 1
       
          if compzero == 0:                   #On obtient alors un match nul
              matchnul = 1
          else:
              matchnul = 0                    #Si non, pas de match nul
          return matchnul

      ce morçeau de code

      • Partager sur Facebook
      • Partager sur Twitter

      Projet ISN : IA Morpion

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown