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
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
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.