Merge branch 'roboc'
This commit is contained in:
commit
c594fa75b7
|
@ -0,0 +1,11 @@
|
|||
OOOOOOOOOO
|
||||
O O O O
|
||||
O . OO O
|
||||
O O O XO
|
||||
O OOOO O.O
|
||||
O O O U
|
||||
O OOOOOO.O
|
||||
O O O
|
||||
O O OOOOOO
|
||||
O . O O
|
||||
OOOOOOOOOO
|
|
@ -0,0 +1,11 @@
|
|||
OOOOOOOOOOOOOOOOO
|
||||
OXO O O O
|
||||
O . O OOO OO O O
|
||||
O O O . O O O O
|
||||
O O O O O O OO.O
|
||||
O O OOOO O O U
|
||||
O . . O OOO OO.O
|
||||
O O O O OO OO O
|
||||
O O OO OO O OO O
|
||||
O O O O
|
||||
OOOOOOOOOOOOOOOOO
|
|
@ -0,0 +1,3 @@
|
|||
OOO
|
||||
OXU
|
||||
OOO
|
|
@ -0,0 +1,20 @@
|
|||
OOOOOOOOOOOOOOOOOOOO
|
||||
OXO . O O . O
|
||||
O.O O O O O O
|
||||
O O O O O O O
|
||||
O.O O . O O O
|
||||
O O O OOOOOO O O
|
||||
O O O O O
|
||||
O O OOOOOOOOOO O
|
||||
O.O . O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O.O O O
|
||||
O.O . O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O.O O O O
|
||||
O O O U
|
||||
OOOOOOOOOOOOOOOOOOOO
|
|
@ -0,0 +1,26 @@
|
|||
OOOOOOOOOOOOOOOOOOOO
|
||||
OXO . O O . O
|
||||
O.O O O O O O
|
||||
O O O O O O O
|
||||
O.O O . O O O
|
||||
O O O OOOOOO O O
|
||||
O O O O O
|
||||
O O OOOOOOOOOO O
|
||||
O.O . O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O.O O O
|
||||
O.O . O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O O O O O
|
||||
O.O O O O
|
||||
O O O U
|
||||
OOOOOOOOOOOOOOOOOOOO
|
|
@ -0,0 +1,11 @@
|
|||
OOOOOOOOOO
|
||||
O O O O
|
||||
O . OO O
|
||||
O O O O
|
||||
O OOOO O.O
|
||||
O O O U
|
||||
O OOOOOO.O
|
||||
O O O
|
||||
O O OOOOOO
|
||||
O . O O
|
||||
OOOOOOOOOO
|
|
@ -0,0 +1,2 @@
|
|||
12
|
||||
34
|
|
@ -0,0 +1,161 @@
|
|||
"""
|
||||
Author: freezed <freezed@users.noreply.github.com> 2018-02-11
|
||||
Version: 0.1
|
||||
Licence: `GNU GPL v3` GNU GPL v3: http://www.gnu.org/licenses/
|
||||
|
||||
Ce fichier fait partie du projet `roboc`
|
||||
|
||||
"""
|
||||
|
||||
# CONFIGURATION
|
||||
# fichier de sauvegarde
|
||||
BACKUP_FILE = '.backup'
|
||||
# Commandes de refus/acceptation
|
||||
MSG_NO_YES = ['non', 'oui']
|
||||
|
||||
# Commandes
|
||||
# Le code utilise l'index des listes `COMMANDS` & `COMMANDS_LABEL`
|
||||
# pour faire le lien entre les 2.
|
||||
# Ici vous pouvez ajouter de nouvelles commandes de jeu, elle seront
|
||||
# ajoutees a l'aide automatiquement. Mais il faudra ajouter le code
|
||||
# leur correspondant dans la condition de traitement du mouvement.
|
||||
COMMANDS = ['Q', 'H']
|
||||
# Libelle des commandes d'interuption, conserver l'ordre
|
||||
COMMANDS_LABEL = ['Sauvegarder & quitter', 'Aide']
|
||||
# Commandes clavier de deplacement
|
||||
DIRECTIONS = ['N', 'S', 'E', 'O']
|
||||
# Étiquette des commandes clavier des de deplacements pour l'affichage
|
||||
# de l'aide. Garder la correspondance
|
||||
DIRECTIONS_LABEL = ['nord',
|
||||
'sud',
|
||||
'est',
|
||||
'ouest']
|
||||
|
||||
# Pepertoire des fichiers carte
|
||||
MAP_DIRECTORY = 'cartes/'
|
||||
# Extention des fichiers carte
|
||||
MAP_EXTENTION = '.txt'
|
||||
# Elements dispo dans le labyrinthe
|
||||
MAZE_ELEMENTS = {'wall': 'O',
|
||||
'door': '.',
|
||||
'exit': 'U',
|
||||
'robo': 'X',
|
||||
'void': ' '}
|
||||
# Issue possible d'un mouvement, garder le OK toujours en fin de liste
|
||||
MOVE_STATUS = ['bad', 'wall', 'exit', 'door', 'ok']
|
||||
MOVE_STATUS_MSG = {
|
||||
'bad': "Le déplacement «{}» n'est pas autorisé.",
|
||||
'wall': "Le déplacement est stoppé par un mur.",
|
||||
'exit': "Vous êtes sortit du labyrinte",
|
||||
'door': "Vous passez une porte",
|
||||
'ok': "Jusqu'ici, tout va bien…"
|
||||
}
|
||||
|
||||
# Messages d'erreurs
|
||||
ERR_ = "#!@?# Oups… "
|
||||
ERR_MAP_FILE = ERR_ + "carte «{}» inaccessible!"
|
||||
ERR_MAP_SIZE = ERR_ + "carte «{}», dimensions incorrecte: «{} x {}»"
|
||||
ERR_MAP_ROBO = ERR_ + "robo est introuvable sur la carte «{}»!"
|
||||
ERR_PLAGE = ERR_ + "saisir un nombre dans la plage indiquée! "
|
||||
ERR_SAISIE = ERR_ + "saisir un nombre! "
|
||||
ERR_UNKNOW = ERR_ + "personne n'est censé arriver ici…"
|
||||
|
||||
MIN_MAP_SIDE = 3
|
||||
|
||||
MSG_DISCLAMER = "Bienvenue dans Roboc."
|
||||
MSG_AVAIBLE_BACKUP = "Sauvegarde dispo, voulez-vous la charger? ({}/{}) "
|
||||
MSG_AVAIBLE_MAP = "Cartes disponible: "
|
||||
MSG_BACKUP_DONE = "La partie a été sauvegardée."
|
||||
MSG_BACKUP_GAME = "Partie sauvegardé chargée"
|
||||
MSG_CHOOSE_MAP = "Choississez un numéro de carte: "
|
||||
MSG_CHOOSE_MOVE = "Votre deplacement ({}:{}): "
|
||||
MSG_START_GAME = "Votre partie commence"
|
||||
MSG_END_GAME = "Fin du jeu."
|
||||
# Recapitulatif des commandes
|
||||
MSG_HELP = "Voici les commandes disponibles:\n"
|
||||
MSG_SELECTED_MAP = "Vous avez fait le choix #{}, la carte «{}»."
|
||||
|
||||
# VARIABLES
|
||||
maps_name_list = list() # liste des maps proposees a l'utilisateur
|
||||
user_select_backup = str() # choix utilisateur: la sauvegarde
|
||||
|
||||
# FONCTIONS
|
||||
|
||||
|
||||
def cls():
|
||||
""" Efface l'historique de la console """
|
||||
import os
|
||||
os.system('clear')
|
||||
return
|
||||
|
||||
|
||||
def choose_maps_menu():
|
||||
"""
|
||||
Affiche le menu de selection des cartes
|
||||
|
||||
Recupere les cartes dans un repertoire, demande a l'utilisateur,
|
||||
de choisir et effectue quelques tests sur la carte jouee avant de
|
||||
creer
|
||||
"""
|
||||
from map import Map
|
||||
|
||||
# VARIABLES
|
||||
user_select_map_id = -1 # choix utilisateur: une carte
|
||||
|
||||
print(MSG_AVAIBLE_MAP)
|
||||
i = 0
|
||||
for maps_name in maps_name_list:
|
||||
print("\t[{}] - {}".format(i, maps_name))
|
||||
i += 1
|
||||
|
||||
# Choix de la carte par l'utilisateur
|
||||
while user_select_map_id > len(maps_name_list) or user_select_map_id < 0:
|
||||
user_select_map_id = input(MSG_CHOOSE_MAP)
|
||||
try:
|
||||
user_select_map_id = int(user_select_map_id)
|
||||
# ? if user_select_map_id is int(): ?
|
||||
except ValueError:
|
||||
user_select_map_id = -1
|
||||
continue
|
||||
|
||||
if user_select_map_id > len(maps_name_list) or \
|
||||
user_select_map_id < 0:
|
||||
print(ERR_PLAGE)
|
||||
|
||||
cls() # vide l'ecran de la console
|
||||
print(MSG_SELECTED_MAP.format(
|
||||
user_select_map_id,
|
||||
maps_name_list[user_select_map_id]
|
||||
))
|
||||
|
||||
# Fichier carte a recuperer
|
||||
map_file = MAP_DIRECTORY + \
|
||||
maps_name_list[user_select_map_id] + \
|
||||
MAP_EXTENTION
|
||||
|
||||
# instenciation de la carte choisie
|
||||
return Map(map_file)
|
||||
|
||||
|
||||
def get_msg_list(command, label):
|
||||
"""
|
||||
Formate une chaine pour afficher les commandes et leurs descriptifs
|
||||
|
||||
:type key: lst()
|
||||
:param key: liste de commande
|
||||
:type label: lst()
|
||||
:param label: Texte descriptif des commande associee
|
||||
:rtype: str()
|
||||
:return: Chaine formatee assemblant les elements en parametres
|
||||
"""
|
||||
|
||||
# Modele de mise en forme de la liste de chaque element
|
||||
TEMPLATE = "\t- «{}»: {}\n"
|
||||
|
||||
# Variable de setour
|
||||
result = str()
|
||||
|
||||
for key, value in enumerate(command):
|
||||
result += TEMPLATE.format(value, label[key])
|
||||
|
||||
return result
|
|
@ -0,0 +1,243 @@
|
|||
"""
|
||||
Author: freezed <freezed@users.noreply.github.com> 2018-02-06
|
||||
Version: 0.1
|
||||
Licence: `GNU GPL v3` GNU GPL v3: http://www.gnu.org/licenses/
|
||||
|
||||
Ce fichier fait partie du projet `roboc`
|
||||
"""
|
||||
import os
|
||||
from configuration import DIRECTIONS, ERR_MAP_FILE, ERR_MAP_ROBO, \
|
||||
MIN_MAP_SIDE, ERR_MAP_SIZE, ERR_UNKNOW, MAZE_ELEMENTS, MSG_START_GAME
|
||||
|
||||
|
||||
class Map:
|
||||
"""
|
||||
Fourni les moyens necessaire a l'utilisation d'un fichier carte.
|
||||
|
||||
Controle de coherance sur la carte choise, deplace le robo en
|
||||
fonction des commandes du joueur jusqu'en fin de partie.
|
||||
|
||||
Cette docstring contient des
|
||||
[DocTests](http://sametmax.com/les-docstrings/), ça ne fait pas
|
||||
partie du cours, mais c'est un outils facile de test/debug que
|
||||
j'utilise et qui reste transparent.
|
||||
|
||||
Doctests
|
||||
========
|
||||
|
||||
:Example:
|
||||
>>> EasyMap = Map("cartes/facile.txt")
|
||||
>>> MiniMap = Map("cartes/mini.txt")
|
||||
>>> PrisonMap = Map("cartes/prison.txt")
|
||||
>>> EmptyMap = Map("cartes/vide.txt")
|
||||
>>> TooSmallMap = Map("cartes/trop_petite.txt")
|
||||
>>> NoRoboMap = Map("cartes/sans_robo.txt")
|
||||
|
||||
>>> print(EmptyMap.status_message)
|
||||
#!@?# Oups… carte «cartes/vide.txt», dimensions incorrecte: «0 x 0»
|
||||
>>> print(TooSmallMap.status_message)
|
||||
#!@?# Oups… carte «cartes/trop_petite.txt», dimensions incorrecte: «3 x 2»
|
||||
>>> print(NoRoboMap.status_message)
|
||||
#!@?# Oups… robo est introuvable sur la carte «cartes/sans_robo.txt»!
|
||||
|
||||
>>> print("_column_nb: {}".format(EasyMap._column_nb))
|
||||
_column_nb: 11
|
||||
>>> print("_line_nb: {}".format(EasyMap._line_nb))
|
||||
_line_nb: 11
|
||||
|
||||
>>> MiniMap.move_to("O")
|
||||
1
|
||||
>>> MiniMap.move_to("Z1")
|
||||
0
|
||||
>>> MiniMap.move_to("4")
|
||||
0
|
||||
>>> MiniMap.move_to("E1")
|
||||
2
|
||||
>>> MiniMap.map_print()
|
||||
OOO
|
||||
O X
|
||||
OOO
|
||||
"""
|
||||
|
||||
def __init__(self, map_file):
|
||||
"""
|
||||
Initialisation de la carte utilise
|
||||
|
||||
Instancie un objet Map avec les attributs suivant:
|
||||
|
||||
:var int status: Etat de l'objet apres le deplacement
|
||||
:var str status_message: Message relatif au deplacement
|
||||
:var int _column_nb: Nbre de colonne du labyrinte (1ere ligne)
|
||||
:var str _data_text: Contenu du labyrinte
|
||||
:var str _element_under_robo: Element sous le robot
|
||||
:var int _line_nb: Nbre de ligne du labyrinte
|
||||
:var int _robo_position: position du robo dans _data_text
|
||||
|
||||
:param map_file: fichier «carte» avec chemin relatif
|
||||
:rtype map: str()
|
||||
:return: None
|
||||
"""
|
||||
# Chargement du fichier carte choisi
|
||||
if os.path.isfile(map_file) is True:
|
||||
with open(map_file, "r") as map_data:
|
||||
|
||||
# contenu de la carte en texte
|
||||
self._data_text = map_data.read()
|
||||
|
||||
# contenu de la carte ligne a ligne
|
||||
map_data_list = self._data_text.splitlines()
|
||||
|
||||
# nbre de colonne de la 1ere ligne de la carte
|
||||
try:
|
||||
self._column_nb = len(map_data_list[0]) + 1
|
||||
except IndexError:
|
||||
self._column_nb = 0
|
||||
|
||||
# nbre de ligne de la carte
|
||||
try:
|
||||
self._line_nb = len(map_data_list)
|
||||
except IndexError:
|
||||
self._line_nb = 0
|
||||
|
||||
# position du robot
|
||||
self._robo_position = self._data_text.find(
|
||||
MAZE_ELEMENTS['robo']
|
||||
)
|
||||
|
||||
# element «sous» le robo, au depart
|
||||
self._element_under_robo = MAZE_ELEMENTS['void']
|
||||
|
||||
# Quelques controle sur la carte chargee:
|
||||
# dimensions assez grande pour deplacer un robo?
|
||||
if self._column_nb < MIN_MAP_SIDE or \
|
||||
self._line_nb < MIN_MAP_SIDE:
|
||||
self.status = False
|
||||
self.status_message = ERR_MAP_SIZE.format(
|
||||
map_file, self._column_nb, self._line_nb
|
||||
)
|
||||
|
||||
# y a t il un robo?
|
||||
elif self._robo_position == -1:
|
||||
self.status = False
|
||||
self.status_message = ERR_MAP_ROBO.format(map_file)
|
||||
|
||||
# on peu ajouter plein d'autres controles ici
|
||||
|
||||
# carte consideree utilisable
|
||||
else:
|
||||
self.status = True
|
||||
self.status_message = MSG_START_GAME
|
||||
|
||||
# Erreur de chargement du fichier
|
||||
else:
|
||||
self.status = False
|
||||
self.status_message = ERR_MAP_FILE.format(map_file)
|
||||
|
||||
def map_print(self):
|
||||
""" Affiche la carte avec la position de jeu courante """
|
||||
print(self._data_text)
|
||||
|
||||
def move_to(self, move):
|
||||
"""
|
||||
Deplace le robo sur la carte
|
||||
|
||||
:param str move: mouvement souhaite
|
||||
:return int: une cle de la constante MOVE_STATUS
|
||||
"""
|
||||
# decompose le mouvement
|
||||
try: # on recupere le 1er caractere (la direction)
|
||||
direction = move[0]
|
||||
except IndexError:
|
||||
return 0
|
||||
except TypeError:
|
||||
return 0
|
||||
|
||||
if len(move[1:]) > 0: # on recupere les caractere suivants (dist)
|
||||
try:
|
||||
goal = int(move[1:])
|
||||
except ValueError as except_detail:
|
||||
return 0
|
||||
else: # si pas de chiffre, on avance d'une seule unite
|
||||
goal = 1
|
||||
|
||||
steps = 0
|
||||
|
||||
# direction non conforme
|
||||
if direction not in DIRECTIONS:
|
||||
move_status = 0
|
||||
|
||||
# supprime le robo de son emplacement actuel et on replace
|
||||
# l'elements «dessous»
|
||||
else:
|
||||
self._data_text = self._data_text.replace(
|
||||
MAZE_ELEMENTS['robo'],
|
||||
self._element_under_robo
|
||||
)
|
||||
|
||||
# pour chaque pas on recupere la position suivante
|
||||
while steps < goal:
|
||||
steps += 1
|
||||
if direction == DIRECTIONS[0]: # nord
|
||||
next_position = self._robo_position - self._column_nb
|
||||
|
||||
elif direction == DIRECTIONS[1]: # sud
|
||||
next_position = self._robo_position + self._column_nb
|
||||
|
||||
elif direction == DIRECTIONS[2]: # est
|
||||
next_position = self._robo_position + 1
|
||||
|
||||
elif direction == DIRECTIONS[3]: # ouest
|
||||
next_position = self._robo_position - 1
|
||||
|
||||
else: # juste au cas ou
|
||||
raise NotImplementedError(ERR_UNKNOW)
|
||||
|
||||
self._element_under_robo = MAZE_ELEMENTS['void']
|
||||
|
||||
# Traitement en fonction de la case du prochain pas
|
||||
next_char = self._data_text[next_position]
|
||||
if next_char == MAZE_ELEMENTS['wall']:
|
||||
move_status = 1
|
||||
steps = goal
|
||||
|
||||
elif next_char == MAZE_ELEMENTS['exit']:
|
||||
self._robo_position = next_position
|
||||
move_status = 2
|
||||
steps = goal
|
||||
|
||||
elif next_char == MAZE_ELEMENTS['door']:
|
||||
self._robo_position = next_position
|
||||
self._element_under_robo = MAZE_ELEMENTS['door']
|
||||
move_status = 3
|
||||
steps = goal
|
||||
|
||||
else:
|
||||
self._robo_position = next_position
|
||||
move_status = 4
|
||||
|
||||
# place le robo sur sa nouvelle position
|
||||
self.place_element(MAZE_ELEMENTS['robo'])
|
||||
|
||||
return move_status
|
||||
|
||||
def place_element(self, element):
|
||||
"""
|
||||
Place l'element sur la carte.
|
||||
|
||||
La position est celle de l'attribut self._robo_position au
|
||||
moment de l'appel.
|
||||
|
||||
Utilise pour place le robot et remettre les portes.
|
||||
|
||||
:param str element: element a placer sur la carte
|
||||
"""
|
||||
pos = self._robo_position
|
||||
txt = self._data_text
|
||||
self._data_text = txt[:pos] + element + txt[pos + 1:]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
""" Starting doctests """
|
||||
|
||||
import doctest
|
||||
doctest.testmod()
|
|
@ -0,0 +1,68 @@
|
|||
# Roboc
|
||||
|
||||
## Consignes
|
||||
|
||||
> Votre mission est de concevoir et développer un petit jeu permettant de
|
||||
contrôler un robot dans un labyrinthe. Ce jeu devra être développé en
|
||||
console pour des raisons d'accessibilité. Je l'ai appelé... Roboc.
|
||||
|
||||
> Le jeu est un labyrinthe formé d'obstacles: des murs qui sont tout
|
||||
simplement là pour vous ralentir, des portes qui peuvent être traversées
|
||||
et au moins un point par lequel on peut quitter le labyrinthe. Si le
|
||||
robot arrive sur ce point, la partie est considérée comme gagnée.
|
||||
|
||||
Pour les consignes détaillées de l'exercice rendez-vous dans le cours
|
||||
_[Apprenez à programmer en Python](https://openclassrooms.com/courses/apprenez-a-programmer-en-python/exercises/180)_
|
||||
d'**Open Classrooms**.
|
||||
|
||||
## Utilisation
|
||||
|
||||
Je n'ai pas utilisé les éléments de base fourni dans l'exercice. Le
|
||||
script contient 4 fichiers et 1 répertoire:
|
||||
|
||||
- `roboc.py`: fichier à lancer
|
||||
- `configuration.py`: contient les constantes/variables de
|
||||
configuration du script, ainsi que les fonctions.
|
||||
- `map.py`: fourni les moyens necessaire a l'utilisation d'un fichier
|
||||
carte. Controle de coherance sur la carte choise, deplace le robo en
|
||||
fonction des commandes du joueur jusqu'en fin de partie.
|
||||
|
||||
- `readme.md`, que vous êtes en train de lire!
|
||||
- `cartes`: répertoire contenant les cartes de jeu (fichier `.txt`)
|
||||
|
||||
## Contrôle du robot
|
||||
|
||||
Le robot est contrôlable grâce à des commandes entrées au clavier. Il
|
||||
doit exister les commandes suivantes :
|
||||
- Q: sauvegarder et quitter la partie en cours
|
||||
- N: déplacer vers le nord (haut de l'écran)
|
||||
- E: déplacer vers l'est (droite de l'écran)
|
||||
- S: déplacer vers le sud (bas de l'écran)
|
||||
- O: déplacer vers l'ouest (gauche de l'écran)
|
||||
- Chacune des directions ci-dessus suivies d'un nombre permet d'avancer
|
||||
de plusieurs cases (ex. E3: 3 cases vers l'est)
|
||||
|
||||
## Remarques
|
||||
|
||||
Dans les fonctionnalites attendue, la consigne sur la sauvegarde à été
|
||||
décrites dans 2 consignes qui m'ont semblée floue:
|
||||
> Enregistrer automatiquement chaque partie à chaque coup pour permettre
|
||||
de les continuer plus tard
|
||||
|
||||
> Q qui doit permettre de sauvegarder et quitter la partie en cours
|
||||
|
||||
J'ai choisi d'implementer la sauvegarde par tour, qui sera de fait,
|
||||
réalisée quand le joueur quitte. Les 2 fonctionnalitées sont ainsi
|
||||
respectées.
|
||||
|
||||
## Bonus
|
||||
|
||||
Quelques fonctionnalitées en bonus:
|
||||
|
||||
- contrôle/vérification des cartes, avec quelques cartes «de test», qui
|
||||
ne sont pas jouable
|
||||
- affichage du recap des commandes (aide), permettant d'ajouter
|
||||
d'autres commades utilisateur plus tard
|
||||
- la docstring du fichier `map.py` contient des [DocTests](http://sametmax.com/les-docstrings/),
|
||||
ça ne fait pas partie du cours, mais c'est un outils facile de
|
||||
test/debug que j'utilise et qui reste transparent.
|
|
@ -0,0 +1,122 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Author: freezed <freezed@users.noreply.github.com> 2018-02-06
|
||||
Version: 0.1
|
||||
Licence: `GNU GPL v3` GNU GPL v3: http://www.gnu.org/licenses/
|
||||
|
||||
roboc
|
||||
=====
|
||||
|
||||
Jeu permettant de controler un robot dans un labyrinthe.
|
||||
|
||||
Voir readme.md
|
||||
"""
|
||||
|
||||
import os
|
||||
import pickle
|
||||
from configuration import BACKUP_FILE, choose_maps_menu, cls, COMMANDS, \
|
||||
COMMANDS_LABEL, DIRECTIONS, DIRECTIONS_LABEL, get_msg_list, \
|
||||
MAP_DIRECTORY, MAP_EXTENTION, maps_name_list, MOVE_STATUS, \
|
||||
MOVE_STATUS_MSG, MSG_AVAIBLE_BACKUP, MSG_BACKUP_DONE, MSG_BACKUP_GAME, \
|
||||
MSG_CHOOSE_MOVE, MSG_DISCLAMER, MSG_END_GAME, MSG_HELP, MSG_NO_YES, \
|
||||
MSG_START_GAME, user_select_backup
|
||||
|
||||
# DEBUT DU JEU
|
||||
|
||||
# Recuperation de la liste des cartes
|
||||
try:
|
||||
maps_avaiable = os.listdir(MAP_DIRECTORY)
|
||||
except FileNotFoundError as except_detail:
|
||||
print("FileNotFoundError: «{}»".format(except_detail))
|
||||
else:
|
||||
for map_file in maps_avaiable:
|
||||
filename_len = len(map_file) - len(MAP_EXTENTION)
|
||||
|
||||
# garde les fichiers avec la bonne extention
|
||||
if map_file[filename_len:] == MAP_EXTENTION:
|
||||
maps_name_list.append(map_file[: filename_len])
|
||||
|
||||
# Affichage du debut de partie
|
||||
cls() # vide l'ecran de la console
|
||||
print(MSG_DISCLAMER)
|
||||
|
||||
# Verif si un fichier de sauvegarde est dispo
|
||||
if os.path.isfile(BACKUP_FILE) is True:
|
||||
with open(BACKUP_FILE, 'rb') as backup_file:
|
||||
backup_map = pickle.Unpickler(backup_file).load()
|
||||
|
||||
# On demande si l'utilisateur veut charger la sauvegarde
|
||||
while user_select_backup not in MSG_NO_YES:
|
||||
user_select_backup = input(
|
||||
MSG_AVAIBLE_BACKUP.format(*MSG_NO_YES)
|
||||
).lower()
|
||||
|
||||
# utilisateur veut la sauvegarde
|
||||
if user_select_backup == MSG_NO_YES[1]:
|
||||
current_map = backup_map
|
||||
else:
|
||||
current_map = choose_maps_menu()
|
||||
else:
|
||||
current_map = choose_maps_menu()
|
||||
|
||||
|
||||
# DEBUT DE BOUCLE DE TOUR DE JEU
|
||||
|
||||
# Affichage de la carte tant que status == True
|
||||
while current_map.status:
|
||||
# Affiche la carte et le message
|
||||
current_map.map_print()
|
||||
print(current_map.status_message)
|
||||
|
||||
# Demande a l'utilisateur son choix du deplacement
|
||||
user_move = input(MSG_CHOOSE_MOVE.format(
|
||||
COMMANDS[1], COMMANDS_LABEL[1])
|
||||
).upper()
|
||||
cls() # vide l'ecran de la console
|
||||
|
||||
# Traitement de la commande utilisateur
|
||||
if user_move == COMMANDS[0]: # quitter
|
||||
current_map.status = False
|
||||
|
||||
# Le premier tour n'a pas ete joue, pas de sauvegarde faite
|
||||
if current_map.status_message != MSG_START_GAME:
|
||||
current_map.status_message = MSG_BACKUP_DONE
|
||||
|
||||
else:
|
||||
current_map.status_message = ""
|
||||
|
||||
elif user_move == COMMANDS[1]: # Affiche l'aide
|
||||
current_map.status_message = MSG_HELP
|
||||
# liste les directions
|
||||
current_map.status_message += get_msg_list(
|
||||
DIRECTIONS, DIRECTIONS_LABEL
|
||||
)
|
||||
# liste les commandes
|
||||
current_map.status_message += get_msg_list(COMMANDS, COMMANDS_LABEL)
|
||||
|
||||
else: # Traitement du deplacement
|
||||
status = current_map.move_to(user_move)
|
||||
message = MOVE_STATUS_MSG[MOVE_STATUS[status]].format(user_move)
|
||||
|
||||
# La sortie est atteinte, fin de la boucle
|
||||
if MOVE_STATUS[status] == 'exit':
|
||||
current_map.status = False
|
||||
current_map.status_message = message
|
||||
|
||||
else: # sinon on sauvegarde la partie avant de refaire un tour
|
||||
current_map.status_message = MSG_BACKUP_GAME
|
||||
with open(BACKUP_FILE, 'wb') as backup_file:
|
||||
pickle.Pickler(backup_file).dump(current_map)
|
||||
|
||||
current_map.status_message = message
|
||||
|
||||
# fin de la boucle de tour
|
||||
|
||||
if current_map.status is False:
|
||||
print(current_map.status_message)
|
||||
|
||||
# Fin de partie
|
||||
print(MSG_END_GAME)
|
||||
current_map.map_print()
|
|
@ -0,0 +1,19 @@
|
|||
# TODO list
|
||||
|
||||
Piste d'amelioration du code après avoir vu le corrigé-type et fait la
|
||||
correction des autres élèves.
|
||||
|
||||
- Quand la partie est gagnée, on supprime la sauvegarde
|
||||
- simplification de gestion de fichier avec endswith(), os.path.join()
|
||||
- creer un objet pour traiter la rencontre d'un element, avec des
|
||||
attributs et methodes qui permettront d'ajouter des obstacles simplement
|
||||
dans la conf et sur la carte, plutot que de rajouter une condition dans
|
||||
le script traitant les mouvements et mettre a jour les attributs de laç
|
||||
carte _à la main_
|
||||
- definir dans sa classe les caracteristique d'une carte valide plutôt
|
||||
que dans le script
|
||||
- permettre a un element de ralentir/accelerer la progression du robot
|
||||
- proposer la suppression d'une carte invalide
|
||||
- limiter un mouvement a la dimension max de la carte sur l'axe concerné
|
||||
- Utiliser des cartes aux lignes de longueur variable
|
||||
-
|
Loading…
Reference in New Issue