La sérialisation
PROBLÉMATIQUE
Je souhaiterais ajouter à mon jeu, un tableau des 5 meilleurs scores et pour faire cela rien de tel que d'utiliser la sérialisation des données qui me permettront de rendre persistant mes scores dans le temps.
Le principe est simple, vous avez une variable python (une liste par exemple) et voulez là garder en mémoire pour là réutiliser plus tard (par exemple au redémarrage du jeu)
Quels outils utiliser avec le langage Python ?
Un seul, on va utiliser le module pickle...
Nous utiliserons le protocole 4, le dernier mise à jour et optimisé pour la version python (>= 3.4)
Création de nos joueurs
Pour avoir un tableau de scores, il nous faut des joueurs et leur score. Pour cela on va créer une liste de scores dont les noms des joueurs sont inconnus et les scores sont nuls.
Code:
from collections import namedtuple
PLAYER_MAX = 5
Player = namedtuple('Player', ['name', 'score'])
def PlayersInit():
players = []
for i in range(PLAYER_MAX):
p = Player(name='', score=0) # initialisation des joueurs au score 0
players.append(p)
return players
Ne vous inquiétez pas trop si vous ne connaissez pas, c'est plus pour vous donner une idée de conception si vous voulez fabriquer un tableau de scores, mais l'enjeu ici est d'expliquer comment sauvegarder et réutiliser ce tableau plus tard, lors d'un redémarrage du jeu par exemple...
Ajout d'un nom de joueur et son score
C'est une mise à jour du tableau, je vais l'appeler update !
Code:
def update(listPlayers, me):
'''
listPlayers est la liste des joueurs enregistrée
me est un joueur, donc un objet de type Player
'''
for idx, player in enumerate(listPlayers):
n, s = player.name, player.score
if me.score > s: # si mon score dépasse l'ancien
newList = [] # création de la liste updatée
rightList = listPlayers[idx:]
del rightList[-1] # suppression du dernier score à droite
leftList = listPlayers[:idx] # récup des scores avant le score courant
newList.extend(leftList) # ajout scores avant score courant
newList.append(me) # ajout score courant
newList.extend(rightList) # ajout scores après score courant
listPlayers = newList[:] # copie dans listPlayers
break # on quitte la boucle
return listPlayers
Création de nouveaux joueurs
Bon là j'ai pas cherché loin, j'ai ajouté 3 joueurs
Code:
Fred = Player(name='Fred', score=50) # Création d'un joueur + score pour test
Dreamus = Player(name='Dreamus', score=35)
Sakarov = Player(name='Sakarov', score=40)
Enregistrement dans le tableau
Code:
listPlayers = update(listPlayers, Fred) # Mise à jour du tableau de scores
listPlayers = update(listPlayers, Dreamus)
listPlayers = update(listPlayers, Sakarov) # on va voir si ça se met bien dans l'ordre décroissant
Oui vous le souhaitiez tellement fort que j'ai dû éviter des détails lors de l'écriture de ce tutoriel.
On va utiliser le module pickle et ouvrir un fichier, s'il n'existe pas, le fichier sera créé automatiquement.
Le principe ici, est la sauvegarde !
Code:
import pickle
# ... suite du code
def save(path):
''' path est le chemin du fichier '''
with open(path, "wb") as f: # création + ouverture du fichier en mode binaire
pickle.dump(listPlayers, f, 4) # sauvegarde de l'objet listPlayers dans le fichier f
Non mais tu déconnes Fred, ça peut pas être aussi simple ? Eh bien si, rien de plus simple, on vient de sauvegarder dans le fichier avec le chemin absolu path, le tableau de scores...
Ce qui rend le fichier très moche à lire
fichier.jpg
C'est bien si vous avez des mots de passe à enregistrer, mieux vaut que ça ne soit pas lisibles, n'est-ce pas ? ;)
C'est bien beau mais je fais quoi avec ce fichier maintenant ? On y arrive !
Chargement du tableau de scores au démarrage du jeu
Rien de compliquer, regardez !
Code:
def load(path):
''' path est le chemin du fichier '''
var = None
if os.path.exists(path): # Si le chemin existe
try:
with open(path, 'rb') as f: # on essaye d'ouvrir le fichier
var = pickle.load(f) # on charge notre liste dans la variable var
except: pass # Sinon on fait rien, la valeur de var vaut None
return var
Je l'appelle simplement de cette manière
Code:
listPlayers = load(".../sauvegarde.txt") # chargement des scores
Pour faire beau, niveau affichage, nous allons créer une forme joueur -> score
Code:
def displayScores():
pattern = "{name} -> {score}" # format de l'affichage
for player in listPlayers:
name, score = player
if name: # S'il y a un nom
print(pattern.format(name=name, score=score)) # on affiche le score
Le code en entier
Voilà c'est terminé, le code en entier vous permettra de tester et vérifier, n'hésitez pas à me prévenir si vous voyez des erreurs ;)
Code:
from collections import namedtuple
import pickle
import os.path
PLAYER_MAX = 5
Player = namedtuple('Player', ['name', 'score'])
def PlayersInit():
players = []
for i in range(PLAYER_MAX):
p = Player(name='', score=0) # initialisation des joueurs au score 0
players.append(p)
return players
def update(listPlayers, me):
'''
listPlayers est la liste des objets Player enregistrée
me est un joueur, donc un objet de type Player
'''
for idx, player in enumerate(listPlayers):
n, s = player.name, player.score
if me.score > s: # si mon score dépasse l'ancien
newList = [] # création de la liste updatée
rightList = listPlayers[idx:]
del rightList[-1] # suppression du dernier score à droite
leftList = listPlayers[:idx] # récup des scores avant le score courant
newList.extend(leftList) # ajout scores avant score courant
newList.append(me) # ajout score courant
newList.extend(rightList) # ajout scores après score courant
listPlayers = newList[:] # copie dans listPlayers
break # on quitte la boucle
return listPlayers
def save(path):
''' path est le chemin du fichier '''
with open(path, "wb") as f: # création + ouverture du fichier en mode binaire
pickle.dump(listPlayers, f, 4) # sauvegarde de l'objet listPlayers dans le fichier f
def load(path):
''' path est le chemin du fichier '''
var = None
if os.path.exists(path): # Si le chemin existe
try:
with open(path, 'rb') as f: # on essaye d'ouvrir le fichier
var = pickle.load(f) # on charge notre liste dans la variable var
except: pass # Sinon on fait rien, la valeur de var vaut None
return var
def displayScores():
pattern = "{name} -> {score}" # format de l'affichage
for player in listPlayers:
name, score = player
if name: # S'il y a un nom
print(pattern.format(name=name, score=score)) # on affiche le score
listPlayers = PlayersInit() # Initialisation du tableau de scores
# Ajout des nouveaux scores
# -------------------------
Fred = Player(name='Fred', score=50) # Création d'un joueur + score pour test
Dreamus = Player(name='Dreamus', score=35)
Sakarov = Player(name='Sakarov', score=40)
listPlayers = update(listPlayers, Fred) # Mise à jour du tableau de scores
listPlayers = update(listPlayers, Dreamus)
listPlayers = update(listPlayers, Sakarov) # on va voir si ça se met bien dans l'ordre décroissant
save("/home/fred1599/Bureau/sauvegarde.txt") # sauvegarde des scores
listPlayers = load("/home/fred1599/Bureau/sauvegarde.txt") # chargement des scores
print(listPlayers) # Affichage de la liste des scores
# [Player(name='Fred', score=50), Player(name='Sakarov', score=40), Player(name='Dreamus', score=35), Player(name='', score=0), Player(name='', score=0)]
displayScores() # bel affichage des scores
# Fred -> 50
# Sakarov -> 40
# Dreamus -> 35
from Hackademics : Forum de hacking hackers white hat cours de securite informatique, apprendre langage python, tutoriels de reverse engineering http://ift.tt/1CLfoHq
via IFTTT
Aucun commentaire:
Enregistrer un commentaire