Bonsoir ou Bonjour ça dépend à quel heure vous lisez ce message…
Bref, j’ai commencé récemment le codage python et je voulais codez des jeux simples pour commencer.
Mais il s’avère qu’il faut utiliser pygame ou tkinter (ou d’autres que je ne connais pas peut-être) pour coder des jeux et qu’une page s’ouvre. J’ai alors regarder ce que je peux trouver sur le net pour m’informer et je suis tomber sur un code un peu complexe ou il y a quelques fonctions que je ne comprend pas. Je vous met le code ci-dessous. J’indique dans le code ce que je n’ai pas compris si quelqu’un pourrait m’expliquer merci!!!
import pygame
from pygame.locals import *
import numpy as np
import pickle ##pour enregistrer les solutions connues
class Jeu(object):
###ICI ON INITIALISE ???
def init(self, largeur=1200, hauteur=800, fps=60):
« »« Initialiser pygame, fenêtre, arrière-plan, police,…
arguments par défaut
« » »
pygame.init()
pygame.display.set_caption(« Le jeu du casse tête »)
self.largeur = largeur
self.hauteur = hauteur
self.screen = pygame.display.set_mode((self.largeur, self.hauteur), pygame.DOUBLEBUF)
self.background = pygame.Surface(self.screen.get_size()).convert()
self.background.fill((255,255,255)) # arrière plan blanc
self.clock = pygame.time.Clock()
self.fps = fps
self.playtime = 0.0
self.font = pygame.font.SysFont(‹ mono ›, 24, bold=True)
self.initialMat = np.zeros((8,8)).astype(int)
# ------------- création des boutons initiaux ----------
button = self.font.render(‹ Solve ›, True, (0,255,0), (0,0,128))#nous n’avons malheuresement pas réussi cette fonction qui permettrait de résoudre automatiquement le jeu
buttonRect = button.get_rect()
buttonRect.center = (500,500)
self.background.blit(button,buttonRect)
for num in range(4,9):
numButton = self.font.render(’ '+ str(num) + ’ ',True,(0,255,0), (0,0,128))
numButtonRect = numButton.get_rect()
numButtonRect.center = (-150 + 50*num, 500)
self.background.blit(numButton,numButtonRect)
mess = self.font.render(‹ Choisir la taille ›, True, (0,0,0), (255,255,255))
messRect = mess.get_rect()
messRect.center = (150,470)
self.background.blit(mess,messRect)
randButton = self.font.render(‹ Random ›, True, (0,255,0),(0,0,128))
randRect = randButton.get_rect()
randRect.center = (340,500)
self.background.blit(randButton,randRect)
setupButton = self.font.render(‹ START ›, True, (0,255,255), (250,0,250))
setupRect = setupButton.get_rect()
setupRect.center = (425,500)
self.background.blit(setupButton,setupRect)
def verification(self,Mat = np.zeros((5,5))):
##Vérifie si le jeu peut être résolue
size = np.sqrt(len(Mat))
if size == 4:
verif1 = np.array([1,0,0,0, 1,1,0,0, 1,0,1,0, 0,1,1,1])
verif2 = np.array([0,0,0,1, 0,0,1,1, 0,1,0,1, 1,1,1,0])
verif3 = np.array([0,1,0,0, 1,1,1,0, 0,0,0,1, 1,1,0,1])
verif4 = np.array([0,0,1,0, 0,1,1,1, 1,0,0,0, 1,0,1,1])
if np.dot(Mat,verif1)%2>0 or np.dot(Mat,verif2)%2>0 or np.dot(Mat,verif3)%2>0 or np.dot(Mat,verif4)%2>0:
return False
else:
return True
elif size == 5:
verif1 = np.array([0,1,1,1,0, 1,0,1,0,1, 1,1,0,1,1, 1,0,1,0,1, 0,1,1,1,0])
verif2 = np.array([1,0,1,0,1, 1,0,1,0,1, 0,0,0,0,0, 1,0,1,0,1, 1,0,1,0,1])
if np.dot(Mat,verif1)%2>0 or np.dot(Mat,verif2)%2>0:
return False
else:
return True
else:
return True
def Choisir(self,sz = 5):
##Pas tout les puzzles ne sont solubles, alors choisir seulement un qui l'est##
randMat = np.random.randint(2,size=sz*sz)
while self.verification(Mat = randMat) == False:
randMat = np.random.randint(2,size=sz*sz)
randMat = randMat.reshape((sz,sz))
return randMat
ICI JE COMPREND PAS L’ARGUMENT PRIS EN COMPTE PAR EXEMPLE ET QUE FAIT LE CODE?
def verif_victoire(self, flag, Mat = np.ones((5,5))):
size = len(Mat)
if flag == True:
for i in range(size):
if flag == True:
for j in range(size):
if Mat[i,j]==1:
flag = False
break
return flag
ENFIN CES TROIS METHODES paintInit, paintPuz, paint JE NE COMPREND PAS CE QU’ELLES FONT
def paintInit(self, Mat = np.ones((5,5)), sM = np.zeros((5,5))):
‹ ›‹ peindre les cases initiales ›’’
size = len(Mat)
shift = size + 2
for ligne in range(size):
for col in range(size):
mycell = Cell(col=col, ligne=ligne, color=(0,255Mat[ligne,col],255),
background=self.background)
mycell.blit(self.background)
solcell = Cell(col=col+shift, ligne=ligne, color=(255sM[ligne,col],0,255),
background=self.background)
solcell.blit(self.background)
def paintPuz(self,Mat = np.ones((5,5))):
'''peindre le puzzle'''
size = len(Mat)
for ligne in range(size):
for col in range(size):
mycell = Cell(col=col, ligne=ligne,
color=(255*Mat[ligne,col],255*Mat[ligne,col],255*(1-Mat[ligne,col])),
background=self.background)
mycell.blit(self.background)
def paint(self,col=0, ligne=0, color=(0,0,255)):
"""mettre à jour une seule cellule"""
#------- Test de fonctions trouver sur internet --------
# pygame.draw.line(Surface, color, start, end, width)
# pygame.draw.rect(Surface, color, Rect, width=0): return Rect
#pygame.draw.rect(self.background, (0,255,0), (50,50,100,25)) # rect: (x1, y1, width, height)
# pygame.draw.circle(Surface, color, pos, radius, width=0): return Rect
# pygame.draw.polygon(Surface, color, pointlist, width=0): return Rect
# pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width=1): return Rect
# ------------------- blitting a cell --------------
mycell = Cell(col=col,ligne=ligne,color=color,background=self.background)
mycell.blit(self.background)
def cliquable(self, ligne, col, M = np.ones((5,5)),sM = np.zeros((5,5))):
size = len(M)
shift = size + 2
if ligne>=size or col >=size:
pass
else:
for i in range(size):
for j in range(size):
if (np.abs(ligne-i)<2 and col==j) or (ligne==i and np.abs(col-j)<2):
M[i,j] = (M[i,j]+1)%2 ##toggle light and adjacent lights
self.paint(ligne=i,col=j,color=(0,255*M[i,j],255))
sM[ligne,col] = sM[ligne,col]+1
##peindre la cellule sur laquelle vous avez cliqué dans la solution
self.paint(col=col+shift,ligne=ligne,color=(255*(sM[ligne,col]%2),0,255))
return M, sM
def alterne(self, ligne, col, M = np.ones((5,5))):
size = len(M)
if ligne>=size or col >=size:
pass
else:
M[ligne,col] = (M[ligne,col]+1)%2 ##alterne la lumière
self.paint(ligne=ligne,col=col,color=(0,255*M[ligne,col],255))
return M
def dernière_ligne(self, M=np.ones((5,5))):
##création d'une chaîne dans la dernière colonne
size = len(M)
arr = ''
for j in range(size):
arr = arr + str(M[-1,j])
return arr
def iterate(self, i, j, step2, size):
if j<size-1:
j += 1
elif step2 == True:
j = 0
step2 = False
else:
i += 1
j = 0
if i == size-1:
step2 = True
return i, j, step2
Modifiez ceci pour exécuter une étape de l’algorithme de résolution de chaque image
def execute(self):
"""la boucle principale"""
#matrix = self.ChooseInitBoard(sz=8)
initMat = np.zeros((8,8))
matrix = np.zeros((8,8))
size = matrix.shape[0]
solMatrix = np.zeros((size,size)) ## garder une trace des boutons enfoncés dans le travail pour résoudre
self.paintInit(Mat=matrix, sM=solMatrix)
running = True
setup = True ##False lorsque l'utilisateur a terminer l'installation
stop = False ##True lorsque le chrono doit s'arrêter
solving = False ##True lorsque le processus de résolution est en cours d'execution
step2 = False ##True pour signifier l’étape 2 du processus de résolution
errorMes = False ##True lorsque le message d’erreur est visible
finalRow = ''
attempt = '' ##tentative de solution si la solution est inconnue
while running:
ligne = -1
col = -1
pos = []
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.type == pygame.MOUSEBUTTONUP:
errorMes = False
pos = pygame.mouse.get_pos()
#print(pos)
if 5<=pos[0]%55 and 5<=pos[1]%55: ##assurez-vous que le clic n’est pas sur une limite
ligne = pos[1]//55
col = pos[0]//55
if setup == True and len(pos)>0:
if pos[1]<450: ##il pourrait être sur une cellule
matrix = self.alterne(ligne,col,matrix)
elif 485<=pos[1]<=515: ##il pourrait être sur un boutton
if 300<=pos[0]<=385: ##c'est le bouton "aléatoire"
matrix = self.Choisirlatailleinitiale(sz=size)
self.paintInit(Mat = matrix, sM = solMatrix)
elif 390<=pos[0]<=460: ##c'est le bouton "commencer"
if self.verification(Mat=matrix.reshape(matrix.size,)):
setup = False
print('Out of Setup Mode')
initMat = matrix.astype(int)
matrix = matrix.astype(int)
self.clock = pygame.time.Clock()
stop = False ##Commencer le temps
else: ##ne permettent pas à l’utilisateur de définir un modèle insoluble
errorMes = True
else: #s'assurer si on clique bien sur un nombre
for num in range(4,9):
if -170+50*num<=pos[0]<=-130+50*num:
size = num
matrix = np.zeros((num,num))
solMatrix = np.zeros((num,num))
whitescreen = pygame.draw.rect(self.background, (255,255,255), (0,0,1000,450))
self.paintInit(Mat = matrix, sM = solMatrix)
break ##peut juste cliquer sur un bouton à la fois
elif solving == False and len(pos)>0:
##n’autorise pas le clic pendant qu’il est en cours de résolution##
if 460<=pos[0]<=540 and 485<=pos[1]<=515: ##puis on clique sur le bouton résoudre
solving = True
#définir la position initiale de l’algorithme de résolution#
i=0
j=0
elif ligne>=0 and col>=0:
#print(ligne,col)
matrix, solMatrix = self.cliquable(ligne, col, matrix, solMatrix)
if solving == True:
##passer par l’étape suivante du processus de résolution##
if i == 0 and step2 == True:
if attempt[j]=='1':
matrix, solMatrix = self.cliquable(ligne=i,col=j,M=matrix, sM=solMatrix)
elif i<size-1: ##ensuite, nous exécutant la première partie de l’algorithme
##si une lumière est allumée, utilisez la ligne suivante vers le bas pour l’effacer
if matrix[i,j] == 1:
matrix, solMatrix = self.cliquable(ligne=i+1,col=j,M=matrix, sM=solMatrix)
elif i == size-1:
##lorsque vous atteignez la dernière ligne, obtenez une chaîne pour l’arrangement
temp = self.dernière_ligne(M = matrix)
if '1' in temp: ##si nous n’avons pas encore fini de résoudre
if len(finalRow) == len(temp):
diff = '' ##mesurer la différence entre la dernière ligne précédente et la nouvelle
for ch in range(len(finalRow)):
diff = diff + str((int(temp[ch]) - int(finalRow[ch]))%2)
if diff not in KnownSols:
KnownSols[diff] = attempt
## enregistrer les solutions connus ##
with open('KS.p', 'wb') as fp:
pickle.dump(KnownSols, fp, protocol=pickle.HIGHEST_PROTOCOL)
finalRow = temp
print('Dernière ligne: ', finalRow)
if finalRow in KnownSols:
attempt = KnownSols[finalRow]
else: ##choisissez une sélection aléatoire de boutons à appuyer dans la ligne supérieure
attempt = ''
while '1' not in attempt and attempt not in KnownSols.values():
attempt = ''
for i in range(size):
attempt = attempt + str(np.random.randint(0,2))
step2 = True
i=0
j=-1
print('Attempt: ', attempt)
else: ##si nous avons terminé, ajoutez les informations au dictionnaire si elles sont manquantes
résoudre = False
if finalRow not in KnownSols:
KnownSols[finalRow] = attempt
## enregistrer les solution connu##
with open('KS.p', 'wb') as fp:
pickle.dump(KnownSols, fp, protocol=pickle.HIGHEST_PROTOCOL)
i,j,step2 = self.iterate(i,j,step2,size)
if stop == False:
if self.verif_victoire(True, Mat = matrix): #checkflag == True:
print('Victoire!!')
stop = True
if self.playtime != 0: ##si le jeu a réellement commencer
setup = True
self.paintPuz(Mat = initMat)
else:
#CREATION D'UN CHRONOMETRE (perso)
milliseconds = self.clock.tick(self.fps)
self.playtime += milliseconds / 1000.0
self.draw_text("Cliques: {:6.4}{}TEMPS DE JEU: {:6.4} SECONDES".format(np.sum(solMatrix), " "*5, self.playtime))
self.draw_text("Cliques Min: {:6.3}".format(np.sum(solMatrix%2)), loc=(50,570))
self.draw_text("Cases initialement cliqué", loc=((2.7*size/2)*55,(size+0.5)*55))
if errorMes == True:
self.draw_text("Error: Modèle insoluble", loc = (50,520), color = (255,0,0))
pygame.display.flip()
self.screen.blit(self.background, (0, 0))
pygame.quit()
def draw_text(self, text,loc=(50,550), color=(0,0,0)):
"""Centrer le texte dans la fenêtre
"""
fw, fh = self.font.size(text)
surface = self.font.render(text, True, color)
self.screen.blit(surface, loc)
class Cell(object):
« »« Ceci est censé être une méthode pour créer une seule cellule »""
def init(self, length = 50, col = 0, ligne = 0, color=(0,0,255),
background = pygame.Surface((600,600))):
self.length = length
self.x = col55
self.y = ligne55
self.color = color
self.surface = background
##création de l’arrière-plan de la cellule##
pygame.draw.rect(self.surface, (0,0,1), (self.x,self.y,self.length+10, self.length+10))
## création de la cellule##
pygame.draw.rect(self.surface, self.color, (self.x+5, self.y+5, self.length, self.length))
self.surface = self.surface.convert()
def blit(self,background):#dessine une image sur une autre
background.blit(self.surface, (0,0))##dessine une surface source sur cette surface
class Victoire():
« »"
Documentation :
Description : La classe Victoire affiche une fenêtre popup lorsque le joueur arrive à gagner la partie
Méthodes :
-__init__() : initialisation de la fenêtre (méthode de base) : crée une popup qui nous affiche un message de victoire et le nombre de click total
Arguments :
Aucun argument nécessaire
"""
def init(self):
global nb_clicks
Tk().wm_withdraw() # to hide the main window
messagebox.showinfo(‹ Bravo ! › , ‹ Félicitations, vous avez gagné la partie avec › + str(nb_clicks) + ‹ clicks ! › )
if name == ‹ main ›:
# appel avec largeur de fenêtre et fps
Le_Jeu().execute()