Aller au contenu

Projet : Constructeur de niveaux Mario

Ce projet vise à asseoir les notions de programmation vues à date et à faire nos premiers pas dans la définition de fonctions et l’utilisation de modules offerts par Python comme random.

Tu vas concevoir un programme interactif qui permet à un utilisateur de construire un niveau Mario à l’aide de blocs prédéfinis. Le niveau construit pourra être testé avec la plateforme web Mario Runner qui permet de simuler (visuellement) la traversée du niveau.


Au lancement, le programme demande un niveau de difficulté (1, 2 ou 3) :

Constructeur de niveaux Mario
═════════════════════════════════
Difficulté (1 = facile, 2 = moyen, 3 = difficile) : 2

L’utilisateur voit un menu et choisit des blocs à ajouter à la ligne courante. Après chaque choix, l’état du niveau est affiché :

──────────────────────────────────────────────────
[#][#] [#] [#][#] [#] [#] (3)
[#][#][#][#][#][#][<][#][#][#][^][#] (2)
→ [#][#][^][#][#] (1)
[?] aléatoires : 0 / 1 minimum
──────────────────────────────────────────────────
A) [#] Bloc B) [ ] Vide C) [^] Trampoline
D) [>] Accélérer E) [<] Décélérer F) [?] Aléatoire
NL) Nouvelle ligne FIN) Terminer
Bloc : F
Nombre : 2

Quand l’utilisateur choisit FIN, si tout est valide (assez de blocs aléatoires, ligne non vide), le niveau est sauvegardé dans niveau.txt. Le score de complexité est affiché juste avant la sauvegarde.

Score de complexité : 42
Niveau sauvegardé dans « niveau.txt »
Glisse ce fichier dans le Mario Runner !

OptionBlocEffet sur Mario
A[#]Bloc régulier — Mario marche dessus
B[ ]Bloc vide — Mario tombe !
C[^]Trampoline — Mario saute de +2 blocs de hauteur
D[>]Accélérateur — Mario avance de 2 colonnes
E[<]Décélérateur — Mario revient à vitesse normale
F[?]Aléatoire — résolu immédiatement selon la difficulté
CommandeEffet
NLTermine la ligne courante, commence une nouvelle au-dessus
FINAffiche le score, sauvegarde dans niveau.txt

Chaque ligne doit contenir un nombre minimum de blocs aléatoires (option F). Ce minimum augmente d’au moins 1 après chaque ligne : ligne 1 → au moins 1, ligne 2 → au moins 2, etc.

Le programme refuse NL et FIN si le minimum n’est pas atteint.


Le niveau doit respecter les limites suivantes :

ContrainteMinimumMaximum
Colonnes par ligne (largeur)540
Nombre de lignes (hauteur)18
Blocs par ajout110

Le programme doit refuser :

  • NL si la ligne courante contient moins de 5 blocs
  • Un ajout de blocs qui ferait dépasser 40 colonnes sur la ligne
  • NL si le niveau a déjà atteint 8 lignes

Voici le flux général du programme en pseudo-code.

DÉBUT DU PROGRAMME
1. Afficher le titre
2. Demander la difficulté (1, 2 ou 3)
- Tant que la réponse n'est pas valide, redemander
3. Préparer les variables :
4. Tant que PAS fini :
a. Afficher l'état du niveau (lignes complétées + ligne en cours)
b. Afficher le menu (A, B, C, D, E, F, NL, FIN)
c. Lire et valider le choix de l'utilisateur
d. Si valide
- Effectuer traitement requis pour le bloc ou la commande choisie
3. Sinon :
- Afficher un message d'erreur
FIN DU PROGRAMME

Le travail se découpe en paliers progressifs. Chaque palier inclut les critères des paliers précédents.


À faire : La boucle while principale avec le menu, les options A et B, les commandes NL et FIN, et la saisie de la difficulté.

Critères :

#Critère
1Le programme tourne sans erreur
2La difficulté (1-3) est demandée au début
3La difficulté est validée (1, 2 ou 3 seulement)
4Le programme continue jusqu’à l’entrée de FIN
5Lecture du choix de bloc avec input()
6A ajoute [#], B ajoute [ ] à la ligne courante
7NL commence une nouvelle ligne au-dessus
8FIN sauvegarde dans niveau.txt
9L’état du niveau est affiché après chaque choix

À faire : Ajouter les options C, D, E et demander combien de blocs (1 à 10) après chaque choix A-E.

Critères (en plus du Palier 1) :

#Critère
10Les options C, D, E fonctionnent
11Le programme demande combien (1 à 10) après chaque choix
12La quantité est validée (refus si hors 1-10)

À faire : Ajouter l’option F, compter les blocs aléatoires placés, empêcher NL/FIN si le minimum n’est pas atteint.

Tu dois écrire deux fonctions :

  1. calculer_min_aleatoires(num_ligne) — retourne le minimum de blocs aléatoires requis
  2. resoudre_aleatoire(difficulte) — retourne un bloc concret au hasard

Critères (en plus du Palier 2) :

#Critère
13L’option F résout un bloc aléatoire et l’ajoute à la ligne
14Le compteur de blocs aléatoires est affiché
15NL et FIN sont refusés si pas assez d’aléatoires
16calculer_min_aleatoires() est une fonction (def)
17resoudre_aleatoire() est une fonction (def)
18La difficulté change les probabilités
19Un commentaire explique ta logique de probabilités

La fonction resoudre_aleatoire :

C’est à toi de concevoir les probabilités. La fonction reçoit la difficulté (1, 2 ou 3) et retourne un bloc parmi [#], [ ], [^], [>], [<].

Exemples de logiques possibles (choisis et justifie la tienne) :

  • Plus la difficulté est haute, plus il y a de [ ] (trous) → niveau dangereux
  • Plus la difficulté est haute, plus il y a de [>] (sprints) → Mario va trop vite
  • Difficulté 1 : que des [#] ; difficulté 3 : tous les types équiprobables
  • La difficulté change la proportion de blocs solides vs dangereux

À faire : Calculer et afficher un score de complexité du niveau et valider les entrées robustement.

Critères (en plus du Palier 3) :

#Critère
20Le score de complexité est affiché avant la sauvegarde
21Le score dépend d’au moins 3 facteurs
22Un commentaire explique ta formule
23Choix invalide → message d’erreur (pas de crash)
24Ligne vide → NL refusé

Calcul du score :

C’est à toi de concevoir la formule ! Elle doit tenir compte d’au moins 3 des facteurs suivants :

FacteurPertinence
Blocs aléatoiresPlus d’aléatoire = imprévisible
Blocs vides [ ]Trous = dangereux
Nombre de lignesPlus haut = sauts risqués
DifficultéDiff 3 = blocs plus dangereux
Largeur du niveauPlus long = plus d’obstacles

Rédige un rapport expliquant le flux général de ton programme, ses particularités, et réponds aux questions suivantes :

  1. Combien de tours ta boucle a-t-elle effectués pour construire un niveau de 3 lignes de 10 blocs ?
  2. Le nombre de tours dépend-il de la taille du niveau ou du nombre de choix de l’utilisateur ?
  3. Explique ta logique : comment la difficulté influence-t-elle les probabilités dans resoudre_aleatoire() ?
  4. Pourquoi tes choix de probabilités rendent-ils le niveau plus difficile pour Mario ?
  5. Explique ta formule de score : quels facteurs as-tu choisis et pourquoi ?
  6. Un niveau avec un score significativement plus élevé est-il toujours plus dur qu’un niveau avec un score plus bas ? Pourquoi ?

  1. Exécute ton programme dans IDLE
  2. Ouvre le Mario Runner sur le site du cours
  3. Glisse ton fichier niveau.txt dans la zone de dépôt (ou copie-colle le contenu)
  4. Clique ▶ Animer pour voir Mario parcourir ton niveau

Le Runner affiche :

  • Ton niveau en blocs graphiques avec couleurs par type
  • Mario animé qui se déplace pas à pas
  • La trace de chaque action (marche, monte, descend, sprint, trou, mur)
  • Un résumé du niveau (hauteurs distinctes, montées, sprints, trous)

La remise doit être faite sur Léa au plus tard le dimanche 22 mars. Il faut remettre :

  1. Le programme Python Mario_Bloc_PrenomNom.py
  2. Le rapport en PDF Rapport_PrenomNom.pdf