ajout representation construits

This commit is contained in:
2021-11-15 16:41:55 +01:00
parent 2d8c726977
commit 779024ea47
58 changed files with 7068 additions and 143 deletions

View File

@@ -0,0 +1,139 @@
# Projet - Désamorceur de bombes
![bombe](./assets/bomb.png)
## 1. Contexte
Ce jeu est une adaptation du jeu ___[Keep Talking and nobody explodes](https://keeptalkinggame.com/)___, de l'éditeur steelcrategames.com où l'objectif est de désamorcer une bombe en coupant le bon fil.
Cette adaptation a pour but de mettre en oeuvre les connaissances acquises en python, notamment les types construits, les boucles, les structures conditionnelles et les fonctions.
## 2. Description
### 2.1. Règles
- Une bombe peut contenir entre 3 et 6 fils.
- Seul un fil a besoin d'être coupé pour désarmer la bombe.
- Les fils sont ordonnés de haut en bas.
- A l'armement de la bombe, l'utilisateur est invité à indiquer l'indice du fil qu'il souhaite couper.
Les règles complètes de désamorçage sont décrites en annexe. Pour __3 fils__, les règles sont les suivantes
```txt
S'il n'y a pas de fil rouge, couper le deuxième fil.
Sinon, si le dernier fil est blanc, couper le dernier fil.
Sinon, s'il y a plus d'un fil bleu, couper le dernier fil bleu.
Sinon, couper le dernier fil.
```
### 2.2. Exemples
| Exemple | Explication |
| :--: | :-- |
| ![](./assets/exemple_1.png) | Le fil à couper est celui à l'indice 1, soit le deuxième fil.<br />La règle qui le justifie : il n'y a pas de fil rouge. |
| ![](./assets/exemple_2.png) | Le fil à couper est celui à l'indice 2, soit le dernier fil.<br />La règle qui le justifie : Toutes les règles ne sont pas satisfaites, c'est le dernier sinon qui s'applique. |
## 3. Consignes
Vous devez créer un module `desamorceur` qui va permettre de :
- créer une combinaison aléatoire de couleur pour $`n`$ fils,
- créer une bombe de $`n`$ fils,
- afficher une bombe,
- créer un numéro de série sur 8 chiffres,
- déterminer si le fil choisi désarme la bombe ou non,
- ... ainsi que d'autres fonctions nécessaires à l'implantation du jeu (Cf. Partie "Petit manuel du désamorceur de bombes").
L'algorithme principal est le suivant :
```python
bombe = creer_bombe(creer_combinaison(combinaison))
numero_serie = creer_numero_serie()
print(f"n°{numero_serie}")
afficher_bombe(bombe)
indice = input('Indice du fils à couper : ')
if est_bon_fil_a_couper(bombe, int(indice), numero_serie):
print('Sauvé !!!')
else:
print('Perdu, la bombe a explosé')
```
***N.B : Vous devez, pour chaque fonction y adjoindre les docstrings et doctests nécessaires***
Le module sera exécutable de la manière suivante :
> python3 desamorceur.py 4
où le 2ème paramètres correspond au nombre de fils de la bombe
## 4. Matériel fourni
Le module `paint` dispose de :
- 5 variables : `ROUGE, VERT, JAUNE, BLEU, BLANC`, qui permettent de matérialiser les couleurs des fils,
- d'une méthode `dessiner` qui permet d'afficher une matrice passée en paramètre.
<figure>
<center><img src='./assets/utilisation_paint.png'/></center>
<figcaption style='text-align:center;'>Fig 2. Exemple d'utilisation du module paint</figcaption>
</figure>
## 5. Rendu
- un script `desamorceur.py`,
- un fichier `README.md` qui présente vos choix de structures de données, les autres fonctions implantées..., ainsi qu'un extrait de codes ou le decriptif d'un problème rencontré et la solution mise en place.
## 6. Annexe - Petit manuel du désamorceur de bombes
Voici les règles pour désamorcer la bombe :
__3 fils__ :
S'il n'y a pas de fil rouge, couper le deuxième fil.
Sinon, si le dernier fil est blanc, couper le dernier fil.
Sinon, s'il y a plus d'un fil bleu, couper le dernier fil bleu.
Sinon, couper le dernier fil.
__4 fils__ :
S'il y a plus d'un fil rouge et si le dernier chiffre du numéro de série est impair, couper le dernier fil rouge.
Sinon, si le dernier fil est jaune et s'il n'y a pas de fil rouge, couper le premier fil.
Sinon, s'il y a exactement un fil bleu, couper le premier fil.
Sinon, s'il y a plus d'un fil jaune, couper le dernier fil.
Sinon, couper le deuxième fil.
__5 fils__ :
Si le dernier fil est vert et si le dernier chiffre du numéro de série est impair, couper le quatrième fil.
Sinon, s'il y a exactement un fil rouge et plus d'un fil jaune, couper le premier fil.
Sinon, s'il n'y a pas de fil vert, couper le deuxième fil.
Sinon, couper le premier fil.
__6 fils__ :
S'il n'y a pas de fil jaune et si le dernier chiffre du numéro de série est impair, couper le troisième fil.
Sinon, s'il y a exactement un fil jaune et plus d'un fil blanc, couper le quatrième fil.
Sinon, s'il n'y a pas de fil rouge, couper le dernier fil.
Sinon, couper le quatrième fil.
## 7. Pour aller plus loin
Dans le cas où les éléments du projet sont finalisés, vous pouvez le compléter avec les éléments suivants :
- En cas d'explosion de la bombe, afficher à l'utilisateur l'indice du fil qu'il fallait couper pour désarmer la bombe,
- Mettre en place un numéro de série alphanumérique, qui comporte au moins 1 chiffre qui n'est pas forcément en dernière position,
- Doter le projet d'une interface graphique, via le module `pygame`.

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,161 @@
#! /usr/bin/env python3
# -*- coding : utf-8 -*-
# Author : Philippe BODDAERT
# Date : 01/08/2021
# License : CC-BY-NC-SA
import random, sys
from paint import dessiner, ROUGE, JAUNE, BLANC, BLEU, VERT
def creer_fils(couleur, longueur = 10):
'''
Créé un fils d'une longueur donnée
:param couleur: (int) la couleur du fils
:param longueur: (int) la longueur du fils
:return: (list) Un fils sous la forme d'un tableau
'''
return [couleur] * longueur
def creer_bombe(couleurs):
'''
Créé une bombe de fils
:param couleurs: (list) les couleurs des fils
:return: (list) Un tableau de fils
'''
bombe = []
for c in couleurs:
bombe.append(creer_fils(c, 20))
return bombe
def creer_combinaison(longueur):
'''
Créé une combinaison de couleurs de fils
:param longueur: (int) le nombre de fils
:return: (list) Un tableau de couleurs
'''
return [ random.choice([ROUGE, VERT, JAUNE, BLEU, BLANC]) for _ in range(longueur)]
def creer_numero_serie(longueur = 8):
'''
Créé un numéro de série d'une longueur donnée
:param longueur: (int) longueur du numéro
:return: (str) un numéro de longueurdonnée
'''
return str(random.randrange(0, 10**longueur)).zfill(8)
def afficher_bombe(bombe):
'''
Affiche une bombe de fils
:param bombe: (list) une bombe de fils
'''
dessiner(bombe)
def couleur_fils(fils):
'''
Obtient la couleur d'un fils
:param fils: (list) Un fil
:return: (int) la couleur du fil
'''
return fils[0]
def compter_fils(bombe, couleur):
'''
Compte le nombre de fils de la couleur donnée
:param bombe: (list) un tableau de fils
:pram couleur: (int) une couleur
:return: (int) Le nombre de fils de la couleur donnée
'''
nb = 0
for fils in bombe:
if couleur_fils(fils) == couleur:
nb += 1
return nb
def indice_dernier_fils(bombe, couleur):
'''
Détermine le dernier indice du fils de la couleur donnée
:param bombe: (list) une bombe de fils
:param couleur: (int) une couleur
:return: (int) l'indice du fils, -1 sinon
'''
i = len(bombe) - 1
while i >= 0 and couleur_fils(bombe[i]) != couleur:
i -= 1
return i
def est_dernier_chiffre_impair(numero):
'''
Détermine si le dernier chiffre du numéro de série est impair
:param numero: (str) un numéro de série
:return: (bool) True si le dernier chiffre est impair, False sinon
'''
return int(numero) % 2 == 1
def est_bon_fil_a_couper(bombe, indice, numero_serie=None):
'''
Détermine si le fil à l'indice donné est celui à couper
:param bombe: (list) une bombe de fils
:param indice: (int) l'indice du fils à couper
:return: (bool) True si le fils est le bon, False sinon
'''
n = len(bombe)
if n == 3:
if compter_fils(bombe, ROUGE) == 0:
return indice == 1
elif couleur_fils(bombe[n - 1]) == BLANC:
return indice == n - 1
elif compter_fils(bombe, BLEU) > 1:
return indice == indice_dernier_fils(bombe, BLEU)
else:
return indice == n - 1
elif n == 4:
if compter_fils(bombe, ROUGE) > 1 and est_dernier_chiffre_impair(numero_serie):
return indice == indice_dernier_fils(bombe, ROUGE)
elif couleur_fils(bombe[n - 1]) == JAUNE and compter_fils(bombe, ROUGE) == 0:
return indice == 0
elif compter_fils(bombe, BLEU) == 1:
return indice == 0
elif compter_fils(bombe, JAUNE) > 1:
return indice == n - 1
else:
return indice == 1
elif n == 5:
if couleur_fils(bombe[n - 1]) == VERT and est_dernier_chiffre_impair(numero_serie):
return indice == 3
elif compter_fils(bombe, ROUGE) == 1 and compter_fils(bombe, JAUNE) > 1:
return indice == 0
elif compter_fils(bombe, VERT) == 0:
return indice == 1
else:
return indice == 0
else:
if compter_fils(bombe, JAUNE) == 0 and est_dernier_chiffre_impair(numero_serie):
return indice == 2
elif compter_fils(bombe, JAUNE) == 1 and compter_fils(bombe, BLANC) > 1:
return indice == 3
elif compter_fils(bombe, ROUGE) == 0:
return indice == n - 1
else:
return indice == 3
if __name__ == '__main__':
combinaison = 3
numero_serie = None
if len(sys.argv) > 1:
combinaison = int(sys.argv[1])
if combinaison > 3:
numero_serie = creer_numero_serie()
bombe = creer_bombe(creer_combinaison(combinaison))
if numero_serie is not None:
print(f"{numero_serie}")
afficher_bombe(bombe)
indice = input('Indice du fils à couper : ')
if est_bon_fil_a_couper(bombe, int(indice), numero_serie):
print('Sauvé !!!')
else:
print('Perdu, la bombe a explosé')

View File

@@ -0,0 +1,44 @@
#! /usr/bin/env python3
# -*- coding : utf-8 -*-
# Author : Philippe BODDAERT
# Date : 28/12/2020
# License : CC-BY-NC-SA
''' Affichage en couleur '''
NOIR = 0
ROUGE = 1
VERT = 2
JAUNE = 3
BLEU = 4
MAGENTA = 5
CYAN = 6
BLANC = 7
def case_couleur(back = 9):
'''
Renvoi le texte d'un espace dont la couleur de fond est celle donnée
:param back: (int) le code couleur du fond du texte
'''
return couleur(' ', back)
def couleur(texte, back = 9, fore = 9):
'''
Renvoi le texte dans la couleur donnée
:param fore: (int) le code couleur du texte
:param back: (int) le code couleur de fond du texte
:param texte: (str) texte à mettre en couleur
:return: (str) le texte mis en couleur pour affichage
'''
return f'\033[3{fore}m\033[4{back}m{texte}\033[39m\033[49m'
def dessiner(matrice):
'''
Affiche le contenu de la matrice sous la forme de cases colorées
:param matrice: (list) un tableau de tableaux
:return: None
:CU: les valeurs de la matrice doivent être comprises entre 0 et 7 inclus
'''
for ligne in matrice:
for colonne in ligne:
print(case_couleur(colonne), sep = '', end = '')
print('')