Sokoban

Fermé
Helpmepls - 14 mai 2015 à 11:18
 helpmepls - 14 mai 2015 à 17:09
Bonjour,

J'ai choisis la spécialité ISN en terminale S et pour le BAC nous devons présenter un projet en python. Le sujet est libre et j'ai choisis le jeu SOKOBAN (une sorte de casse tête). La présentation sera le 29mai.
J'aimerai avoir une idée de mon programme : erreurs/optimisation du code (la je pense qu'il y a du travail)/ amélioration pour le jeu. Voici mon code :
import pygame,time,pickle
from pygame.locals import *


def ouverture_niveau(nom_fichier,num_niveau):
with open('Rcoupniv'+str(num_niveau)+'.txt', 'rb') as f:
nb_coup_record = pickle.load(f)

with open('Rtempsniv'+str(num_niveau)+'.txt', 'rb') as f:
temps_record = pickle.load(f)

with open(nom_fichier, "r") as fichier:
structure_niveau = []
for ligne in fichier:
ligne_niveau = []
for nombre in ligne :
if nombre != '\n':
ligne_niveau.append(nombre)
structure_niveau.append(ligne_niveau)
t2 = time.clock()
return structure_niveau,t2,nb_coup_record,temps_record


def affichage_niveau(structure_niveau,mur,perso,vide,boule,coffre,coffreplein,parchemin,nb_coup,nb_coup_record,temps_record,num_niveau):
num_ligne = 0
for ligne in structure_niveau :
num_case = 0
for nombre in ligne:

abscisse = num_case * 50
ordonnee = num_ligne * 50

if nombre == '0':
fenetre.blit(vide, (abscisse,ordonnee))
elif nombre == '1':
fenetre.blit(mur, (abscisse,ordonnee))
elif nombre == '2':
fenetre.blit(boule, (abscisse,ordonnee))
elif nombre == '3':
fenetre.blit(perso, (abscisse,ordonnee))
x = num_case
y = num_ligne
elif nombre == '4' :
fenetre.blit(coffre, (abscisse,ordonnee))
elif nombre == '5' :
fenetre.blit(coffreplein, (abscisse,ordonnee))

num_case += 1
num_ligne += 1
fenetre.blit(parchemin, (500,0))
font = pygame.font.Font(None, 23)
text = font.render('Niveau : '+str(num_niveau), 1, (88, 41, 0))
fenetre.blit(text, (615,60))

text = font.render('Déplacements actuels : '+str(nb_coup), 1, (133, 109, 77))
fenetre.blit(text, (555,100))
text = font.render('Déplacements record : '+str(nb_coup_record), 1, (133, 109, 77))
fenetre.blit(text, (555,140))
text = font.render('Temps record : '+str(temps_record), 1, (133, 109, 77))
fenetre.blit(text, (555,180))
pygame.display.flip()
return x,y

def verification_victoire(structure_niveau) :
victoire = True
for ligne in structure_niveau :
for nombre in ligne :
if nombre == '4' :
victoire = False
return victoire

def record_temps(temps,temps_record,num_niveau) :
fichier_a_ouvrir ='Rtempsniv'+str(num_niveau)+'.txt'
with open(fichier_a_ouvrir, 'wb') as f :
pickle.dump(temps,f)

def coup_record(nb_coup,nb_coup_record,num_niveau):
with open('Rcoupniv'+str(num_niveau)+'.txt', 'wb') as f :
pickle.dump(nb_coup,f)







pygame.init()
num_niveau = 1
nom_fichier = 'niveau'+str(num_niveau)+'.txt'
structure_niveau,t2,nb_coup_record,temps_record = ouverture_niveau(nom_fichier,num_niveau)


fenetre = pygame.display.set_mode((800,500))

#Chargement des images
parchemin = pygame.image.load("parchemin.png").convert()
mur = pygame.image.load("wall.png").convert()
perso = pygame.image.load("perso.png").convert()
vide = pygame.image.load("vide.png").convert()
boule = pygame.image.load("piece.png").convert()
coffre = pygame.image.load("coffre.png").convert()
coffreplein = pygame.image.load("coffreplein.png").convert()

nb_coup = 0
x,y = affichage_niveau(structure_niveau,mur,perso,vide,boule,coffre,coffreplein,parchemin,nb_coup,nb_coup_record,temps_record,num_niveau)

pygame.display.flip()
pygame.key.set_repeat(500,200)
continuer = 1

while continuer:
for event in pygame.event.get():
if event.type == KEYDOWN:

if event.key == K_DOWN : #Si "flèche bas"
if structure_niveau[y+1][x] == '2' and structure_niveau[y+2][x] == '4' : # si coffre a gauche de la pièce
structure_niveau[y][x] = '0'
structure_niveau[y+1][x] = '3'
structure_niveau[y+2][x] = '5'

if structure_niveau[y+1][x] == '2' and structure_niveau[y+2][x] == '0': # vide a gauche de la pièce
structure_niveau[y][x] = '0'
structure_niveau[y+1][x] = '3'
structure_niveau[y+2][x] = '2'

if structure_niveau[y+1][x] == '0': #vide a gauche
structure_niveau[y][x] = '0'
structure_niveau[y+1][x] = '3'

if structure_niveau[y][x] != '3' :
y += 1
nb_coup += 1


if event.key == K_UP : #Si "flèche haut"
if structure_niveau[y-1][x] == '2' and structure_niveau[y-2][x] == '4' : # si coffre a gauche de la pièce
structure_niveau[y][x] = '0'
structure_niveau[y-1][x] = '3'
structure_niveau[y-2][x] = '5'

if structure_niveau[y-1][x] == '2' and structure_niveau[y-2][x] == '0': # vide a gauche de la pièce
structure_niveau[y][x] = '0'
structure_niveau[y-1][x] = '3'
structure_niveau[y-2][x] = '2'


if structure_niveau[y-1][x] == '0': #vide a gauche
structure_niveau[y][x] = '0'
structure_niveau[y-1][x] = '3'

if structure_niveau[y][x] != '3' :
y -= 1
nb_coup += 1

if event.key == K_LEFT : #Si "flèche gauche"
if structure_niveau[y][x-1] == '2' and structure_niveau[y][x-2] == '4' : # si coffre a gauche de la pièce
structure_niveau[y][x] = '0'
structure_niveau[y][x-1] = '3'
structure_niveau[y][x-2] = '5'

if structure_niveau[y][x-1] == '2' and structure_niveau[y][x-2] == '0': # vide a gauche de la pièce
structure_niveau[y][x] = '0'
structure_niveau[y][x-1] = '3'
structure_niveau[y][x-2] = '2'

if structure_niveau[y][x-1] == '0': #vide a gauche
structure_niveau[y][x] = '0'
structure_niveau[y][x-1] = '3'

if structure_niveau[y][x] != '3' :
x -= 1
nb_coup += 1

if event.key == K_RIGHT : #Si "flèche droite"
if structure_niveau[y][x+1] == '2' and structure_niveau[y][x+2] == '4' : # si coffre a droite de la pièce
structure_niveau[y][x] = '0'
structure_niveau[y][x+1] = '3'
structure_niveau[y][x+2] = '5'

if structure_niveau[y][x+1] == '2' and structure_niveau[y][x+2] == '0': # vide a droite de la pièce
structure_niveau[y][x] = '0'
structure_niveau[y][x+1] = '3'
structure_niveau[y][x+2] = '2'

if structure_niveau[y][x+1] == '0': #vide a droite
structure_niveau[y][x] = '0'
structure_niveau[y][x+1] = '3'

if structure_niveau[y][x] != '3' :
x += 1
nb_coup += 1

if event.key == K_SPACE :
nb_coup = 0
structure_niveau,t2,nb_coup_record,temps_record = ouverture_niveau(nom_fichier,num_niveau)
x,y = affichage_niveau(structure_niveau,mur,perso,vide,boule,coffre,coffreplein,parchemin,nb_coup,nb_coup_record,temps_record,num_niveau)

if event.key == K_ESCAPE:
continuer = 0


affichage_niveau(structure_niveau,mur,perso,vide,boule,coffre,coffreplein,parchemin,nb_coup,nb_coup_record,temps_record,num_niveau)
victoire = verification_victoire(structure_niveau)
pygame.display.flip()
if victoire == True :
t1 = time.clock()

temps = int(t1-t2)
#
fenetre.blit(parchemin, (500,247))
font = pygame.font.Font(None, 23)
text = font.render('Bravo ! ', 1, (88, 41, 0))
fenetre.blit(text, (615,300))
text = font.render('Voici le niveau suivant -->', 1, (88, 41, 0))
fenetre.blit(text, (560,455))
text = font.render('Scores :', 1, (88, 41, 0))
fenetre.blit(text, (555,330))
text = font.render('Déplacements : '+str(nb_coup), 1, (133, 109, 77))
fenetre.blit(text, (555,360))
text = font.render('Temps : '+str(temps), 1, (133, 109, 77))
fenetre.blit(text, (555,390))


if temps < temps_record :
record_temps(temps,temps_record,num_niveau)

if nb_coup < nb_coup_record :
coup_record(nb_coup,nb_coup_record,num_niveau)
nb_coup = 0
if num_niveau < 3 :
num_niveau += 1
nom_fichier = 'niveau'+str(num_niveau)+'.txt'
structure_niveau,t2,nb_coup_record,temps_record = ouverture_niveau(nom_fichier,num_niveau)
x,y = affichage_niveau(structure_niveau,mur,perso,vide,boule,coffre,coffreplein,parchemin,nb_coup,nb_coup_record,temps_record,num_niveau)
victoire = False
pygame.display.flip()



Je vous remercie d'avance :)
Il faut savoir que le niveau demandé n'est pas élevé (j'ai surement l'un des plus dur programme de la classe) donc je ne demande pas un travail de pro ^^.
Mon problème serai aussi d'enlever le gros bloc de "if" pour les déplacements, je ne sais pas comment le faire autrement (on programme en 3.4, la fonction switch() est de ce fait absente)

Merci de vos réponses ;) je réponds evidemment aux questions et je peux envoyé des screens/images a volonté =)

1 réponse

Je n'ai pas trouvé comment modifié mon message précédent, je double-post donc dsl :/
Voici mon nouveau code :
import pygame,time,pickle
from pygame.locals import *


def ouverture_niveau(nom_fichier,num_niveau):
with open('Rcoupniv'+str(num_niveau)+'.txt', 'rb') as f:
nb_coup_record = pickle.load(f)

with open('Rtempsniv'+str(num_niveau)+'.txt', 'rb') as f:
temps_record = pickle.load(f)

with open(nom_fichier, "r") as fichier:
s_niv = []
for ligne in fichier:
ligne_niveau = []
for nombre in ligne :
if nombre != '\n':
ligne_niveau.append(nombre)
s_niv.append(ligne_niveau)
t2 = time.clock()
return s_niv,t2,nb_coup_record,temps_record


def affichage_niveau(s_niv,mur,perso,vide,boule,coffre,coffreplein):
num_ligne = 0
for ligne in s_niv :
num_case = 0
for nombre in ligne:

abscisse = num_case * 50
ordonnee = num_ligne * 50

if nombre == '0':
fenetre.blit(vide, (abscisse,ordonnee))
elif nombre == '1':
fenetre.blit(mur, (abscisse,ordonnee))
elif nombre == '2':
fenetre.blit(boule, (abscisse,ordonnee))
elif nombre == '3':
fenetre.blit(perso, (abscisse,ordonnee))
x = num_case
y = num_ligne
elif nombre == '4' :
fenetre.blit(coffre, (abscisse,ordonnee))
elif nombre == '5' :
fenetre.blit(coffreplein, (abscisse,ordonnee))

num_case += 1
num_ligne += 1
return x,y

def affichage_p_haut(parchemin,nb_coup,nb_coup_record,temps_record,num_niveau) :
fenetre.blit(parchemin, (500,0))
font = pygame.font.Font(None, 23)
text = font.render('Niveau : '+str(num_niveau), 1, (88, 41, 0))
fenetre.blit(text, (615,60))

text = font.render('Déplacements actuels : '+str(nb_coup), 1, (133, 109, 77))
fenetre.blit(text, (555,100))
text = font.render('Déplacements record : '+str(nb_coup_record), 1, (133, 109, 77))
fenetre.blit(text, (555,140))
text = font.render('Temps record : '+str(temps_record), 1, (133, 109, 77))
fenetre.blit(text, (555,180))
pygame.display.flip()

def affichage_p_bas(parchemin,nb_coup,temps):
fenetre.blit(parchemin, (500,247))
font = pygame.font.Font(None, 23)
text = font.render('Bravo ! ', 1, (88, 41, 0))
fenetre.blit(text, (615,300))
text = font.render('Voici le niveau suivant -->', 1, (88, 41, 0))
fenetre.blit(text, (560,455))
text = font.render('Scores :', 1, (88, 41, 0))
fenetre.blit(text, (555,330))
text = font.render('Déplacements : '+str(nb_coup), 1, (133, 109, 77))
fenetre.blit(text, (555,360))
text = font.render('Temps : '+str(temps), 1, (133, 109, 77))
fenetre.blit(text, (555,390))

def deplacement(s_niv,x,y,mvmt_x,mvmt_y,nb_coup) :
bloc_1 = s_niv[mvmt_y+y][mvmt_x+x]
bloc_0 = s_niv[y][x]
x1 = x
y1 = y
if bloc_1 == '0' or (bloc_1 == '2' and (s_niv[2*mvmt_y + y][2*mvmt_x + x] == '0' or s_niv[2*mvmt_y + y][2*mvmt_x + x] == '4')):
bloc_2 = s_niv[2*mvmt_y + y][2*mvmt_x + x]
if bloc_1 == '2' :
if bloc_2 == '4':
bloc_2 = '5'
else :
bloc_2 ='2'

bloc_1 = '3'
bloc_0 = '0'
x1 += mvmt_x
y1 += mvmt_y

s_niv[mvmt_y+y][mvmt_x+x] = bloc_1
s_niv[mvmt_y+mvmt_y+y][mvmt_x+mvmt_x+x] = bloc_2
nb_coup += 1

s_niv[y][x] = bloc_0

return s_niv,x1,y1,nb_coup



def verification_victoire(s_niv) :
victoire = True
for ligne in s_niv :
for nombre in ligne :
if nombre == '4' :
victoire = False
return victoire

def record_temps(temps,temps_record,num_niveau) :
fichier_a_ouvrir ='Rtempsniv'+str(num_niveau)+'.txt'
with open(fichier_a_ouvrir, 'wb') as f :
pickle.dump(temps,f)

def coup_record(nb_coup,nb_coup_record,num_niveau):
with open('Rcoupniv'+str(num_niveau)+'.txt', 'wb') as f :
pickle.dump(nb_coup,f)







pygame.init()
fenetre = pygame.display.set_mode((800,500))

#Initialisation variables
num_niveau = 1
nb_coup = 0
continuer = 1
nom_fichier = 'niveau'+str(num_niveau)+'.txt'

#Chargement des images
parchemin = pygame.image.load("parchemin.png").convert()
mur = pygame.image.load("wall.png").convert()
perso = pygame.image.load("perso.png").convert()
vide = pygame.image.load("vide.png").convert()
boule = pygame.image.load("piece.png").convert()
coffre = pygame.image.load("coffre.png").convert()
coffreplein = pygame.image.load("coffreplein.png").convert()

#Lecture du fichier
s_niv,t2,nb_coup_record,temps_record = ouverture_niveau(nom_fichier,num_niveau)

#Affichage
x,y = affichage_niveau(s_niv,mur,perso,vide,boule,coffre,coffreplein)
affichage_p_haut(parchemin,nb_coup,nb_coup_record,temps_record,num_niveau)


pygame.key.set_repeat(500,200)

while continuer:
for event in pygame.event.get():
if event.type == KEYDOWN:

if event.key == K_DOWN : #Si "flèche bas"
mvmt_y = 1
mvmt_x = 0
s_niv,x,y,nb_coup = deplacement(s_niv,x,y,mvmt_x,mvmt_y,nb_coup)

if event.key == K_UP : #Si "flèche haut"
mvmt_y = -1
mvmt_x = 0
s_niv,x,y,nb_coup = deplacement(s_niv,x,y,mvmt_x,mvmt_y,nb_coup)

if event.key == K_LEFT : #Si "flèche gauche"
mvmt_y = 0
mvmt_x = -1
s_niv,x,y,nb_coup = deplacement(s_niv,x,y,mvmt_x,mvmt_y,nb_coup)

if event.key == K_RIGHT : #Si "flèche droite"
mvmt_y = 0
mvmt_x = 1
s_niv,x,y,nb_coup = deplacement(s_niv,x,y,mvmt_x,mvmt_y,nb_coup)

if event.key == K_SPACE :
nb_coup = 0
s_niv,t2,nb_coup_record,temps_record = ouverture_niveau(nom_fichier,num_niveau)
x,y = affichage_niveau(s_niv,mur,perso,vide,boule,coffre,coffreplein)

if event.key == K_ESCAPE:
continuer = 0
if event.key == K_PLUS :
temps_depart -= 100
vitesse_repetition -= 40



affichage_niveau(s_niv,mur,perso,vide,boule,coffre,coffreplein)
affichage_p_haut(parchemin,nb_coup,nb_coup_record,temps_record,num_niveau)
victoire = verification_victoire(s_niv)

if victoire == True :
t1 = time.clock()

temps = int(t1-t2)
affichage_p_bas(parchemin,nb_coup,temps)

if temps < temps_record :
record_temps(temps,temps_record,num_niveau)

if nb_coup < nb_coup_record :
coup_record(nb_coup,nb_coup_record,num_niveau)
nb_coup = 0
if num_niveau < 3 :
num_niveau += 1
nom_fichier = 'niveau'+str(num_niveau)+'.txt'
s_niv,t2,nb_coup_record,temps_record = ouverture_niveau(nom_fichier,num_niveau)
x,y = affichage_niveau(s_niv,mur,perso,vide,boule,coffre,coffreplein)
victoire = False
pygame.display.flip()
0