Compare commits
3 Commits
21e783da88
...
cc553348f6
Author | SHA1 | Date | |
---|---|---|---|
cc553348f6 | |||
38c4a9f847 | |||
ac56c7ecf6 |
153
Pile_file/file.py
Normal file
153
Pile_file/file.py
Normal file
@ -0,0 +1,153 @@
|
||||
class Node:
|
||||
"""La classe ```Node``` sera un noeud (une case, un emplacement, ...) où l'on stockera notre donnée
|
||||
|
||||
Les objets de cette classe ont deux attributs:
|
||||
|
||||
value: qui correspond à la valeur stockée
|
||||
nxt: la référence vers le prochain élément
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, value=None, nxt=None) -> None:
|
||||
"""Initialisation du "node"
|
||||
|
||||
:param value: valeur à stocker dans ce "node"
|
||||
:param nxt: Node du prochain élément
|
||||
|
||||
:consignes: compléter l'initialisation de la classe.
|
||||
|
||||
:example:
|
||||
>>> n1 = Node(1)
|
||||
>>> assert n1.value == 1
|
||||
>>> assert n1.nxt is None
|
||||
>>> n2 = Node(5, n1)
|
||||
>>> assert n2.value == 5
|
||||
>>> assert n2.nxt == n1
|
||||
>>> n3 = Node("a", n2)
|
||||
>>> assert n3.value == "a"
|
||||
>>> assert n3.nxt == n2
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class File:
|
||||
"""
|
||||
La classe ```File``` doit posséder un élément "courant" qui est l'élément sur le dessus de la file.
|
||||
|
||||
Fonctionnement d'une file
|
||||
|
||||
-----------
|
||||
append ----> _ _ _ _ _
|
||||
-----------
|
||||
|
||||
-----------
|
||||
_ _ _ _ _ ----> pop
|
||||
-----------
|
||||
|
||||
Elle doit aussi posséder un entier ```n``` qui compte le nombre d'éléments dans la file
|
||||
|
||||
Cette classe aura donc 2 attributs:
|
||||
- current avec l'élément courant
|
||||
- n avec le nombre d'éléments dans la file
|
||||
|
||||
:consignes: Compléter les méthodes suivantes."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialisation de la File vide
|
||||
|
||||
:example:
|
||||
>>> file = File()
|
||||
>>> assert file.n == 0
|
||||
>>> assert file.current is None
|
||||
"""
|
||||
pass
|
||||
|
||||
def append(self, value):
|
||||
"""Ajoute "value" dans la file
|
||||
|
||||
Comme nous sommes dans une file, l'élément doit être ajouté en dernière position.
|
||||
|
||||
:example:
|
||||
>>> file = File()
|
||||
>>> file.append(1)
|
||||
>>> assert file.n == 1
|
||||
>>> assert file.current.value == 1
|
||||
>>> file.append("a")
|
||||
>>> assert file.n == 2
|
||||
>>> assert file.current.value == 1
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_current(self):
|
||||
"""Renvoie la prochaine valeur sans l'enlever de la file
|
||||
Si la liste est vide, la fonction renvoie None.
|
||||
|
||||
:example:
|
||||
>>> file = File()
|
||||
>>> file.get_current()
|
||||
>>> file.append(3)
|
||||
>>> file.get_current()
|
||||
3
|
||||
>>> file.get_current()
|
||||
3
|
||||
"""
|
||||
pass
|
||||
|
||||
def is_empty(self):
|
||||
"""Vérifie si le file est vide
|
||||
|
||||
:example:
|
||||
>>> file = File()
|
||||
>>> file.is_empty()
|
||||
True
|
||||
>>> file.append(1)
|
||||
>>> file.is_empty()
|
||||
False
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def pop(self):
|
||||
"""Renvoie le prochain élément de la file et l'enlève
|
||||
|
||||
Comme c'est une file, le prochain élément est le premier élément arrivé.
|
||||
|
||||
Si la liste est vide, la fonction renvoie rien
|
||||
|
||||
:example:
|
||||
>>> file = File()
|
||||
>>> file.pop()
|
||||
>>> file.append(2)
|
||||
>>> file.pop()
|
||||
2
|
||||
>>> file.pop()
|
||||
>>> file.append(2)
|
||||
>>> file.append(5)
|
||||
>>> file.append("a")
|
||||
>>> file.pop()
|
||||
2
|
||||
>>> file.pop()
|
||||
5
|
||||
>>> file.pop()
|
||||
'a'
|
||||
>>>
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def empty(self):
|
||||
"""vide la file c'est à dire element tous les elements de cette dernière
|
||||
|
||||
:example:
|
||||
>>> file = File()
|
||||
>>> file.append(3)
|
||||
>>> file.append(5)
|
||||
>>> file.append("a")
|
||||
>>> file.get_current()
|
||||
3
|
||||
>>> assert file.n == 3
|
||||
>>> file.empty()
|
||||
>>> file.get_current()
|
||||
>>> assert file.n == 0
|
||||
"""
|
||||
pass
|
153
Pile_file/pile.py
Normal file
153
Pile_file/pile.py
Normal file
@ -0,0 +1,153 @@
|
||||
class Node:
|
||||
"""La classe ```Node``` sera un noeud (une case, un emplacement, ...) où l'on stockera notre donnée
|
||||
|
||||
Les objets de cette classe ont deux attributs:
|
||||
|
||||
value: qui correspond à la valeur stockée
|
||||
nxt: la référence vers le prochain élément
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, value=None, nxt=None) -> None:
|
||||
"""Initialisation du "node"
|
||||
|
||||
:param value: valeur à stocker dans ce "node"
|
||||
:param nxt: Node du prochain élément
|
||||
|
||||
:consignes: compléter l'initialisation de la classe.
|
||||
|
||||
:example:
|
||||
>>> n1 = Node(1)
|
||||
>>> assert n1.value == 1
|
||||
>>> assert n1.nxt is None
|
||||
>>> n2 = Node(5, n1)
|
||||
>>> assert n2.value == 5
|
||||
>>> assert n2.nxt == n1
|
||||
>>> n3 = Node("a", n2)
|
||||
>>> assert n3.value == "a"
|
||||
>>> assert n3.nxt == n2
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Pile:
|
||||
"""
|
||||
La classe ```Pile``` doit posséder un élément "courant" qui est l'élément sur le dessus de la pile.
|
||||
|
||||
Fonctionnement d'une pile
|
||||
|
||||
-----------
|
||||
_ _ _ _ _ <---- append
|
||||
-----------
|
||||
|
||||
-----------
|
||||
_ _ _ _ _ ----> pop
|
||||
-----------
|
||||
|
||||
|
||||
Elle doit aussi posséder un entier ```n``` qui compte le nombre d'éléments dans la pile
|
||||
|
||||
Cette classe aura donc 2 attributs:
|
||||
- current avec l'élément courant
|
||||
- n avec le nombre d'éléments dans la pile
|
||||
|
||||
:consignes: Compléter les méthodes suivantes.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialisation de la Pile vide
|
||||
|
||||
:example:
|
||||
>>> pile = Pile()
|
||||
>>> assert pile.n == 0
|
||||
>>> assert pile.current is None
|
||||
"""
|
||||
pass
|
||||
|
||||
def append(self, value):
|
||||
"""Ajoute "value" dans la pile
|
||||
|
||||
:example:
|
||||
>>> pile = Pile()
|
||||
>>> pile.append(1)
|
||||
>>> assert pile.n == 1
|
||||
>>> assert pile.current.value == 1
|
||||
>>> pile.append("a")
|
||||
>>> assert pile.n == 2
|
||||
>>> assert pile.current.value == "a"
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_current(self):
|
||||
"""Renvoie la prochaine valeur sans l'enlever de la pile
|
||||
Si la liste est vide, la fonction renvoie None.
|
||||
|
||||
:example:
|
||||
>>> pile = Pile()
|
||||
>>> pile.get_current()
|
||||
>>> pile.append(3)
|
||||
>>> pile.get_current()
|
||||
3
|
||||
>>> pile.get_current()
|
||||
3
|
||||
"""
|
||||
pass
|
||||
|
||||
def is_empty(self):
|
||||
"""Vérifie si le pile est vide
|
||||
|
||||
:example:
|
||||
>>> pile = Pile()
|
||||
>>> pile.is_empty()
|
||||
True
|
||||
>>> pile.append(1)
|
||||
>>> pile.is_empty()
|
||||
False
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def pop(self):
|
||||
"""Renvoie le prochain élément de la pile et l'enlève.
|
||||
|
||||
Comme c'est une pile, le prochain élément est le dernier élément arrivé.
|
||||
|
||||
Si la liste est vide, la fonction renvoie None.
|
||||
|
||||
:example:
|
||||
>>> pile = Pile()
|
||||
>>> pile.pop()
|
||||
>>> pile.append(2)
|
||||
>>> pile.pop()
|
||||
2
|
||||
>>> pile.pop()
|
||||
>>> pile.append(2)
|
||||
>>> pile.append(5)
|
||||
>>> pile.append("a")
|
||||
>>> pile.pop()
|
||||
'a'
|
||||
>>> pile.pop()
|
||||
5
|
||||
>>> pile.pop()
|
||||
2
|
||||
>>>
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def empty(self):
|
||||
"""vide la pile c'est à dire element tous les elements de cette dernière
|
||||
|
||||
:example:
|
||||
>>> pile = Pile()
|
||||
>>> pile.append(3)
|
||||
>>> pile.append(5)
|
||||
>>> pile.append("a")
|
||||
>>> pile.get_current()
|
||||
'a'
|
||||
>>> assert pile.n == 3
|
||||
>>> pile.empty()
|
||||
>>> pile.get_current()
|
||||
>>> assert pile.n == 0
|
||||
"""
|
||||
pass
|
@ -2,58 +2,134 @@
|
||||
Projet jeu de Blackjack
|
||||
=======================
|
||||
|
||||
But du jeu : Après avoir reçu deux cartes, le joueur tire des cartes pour s’approcher de la valeur 21 sans la dépasser. Le but du joueur est de battre le croupier en obtenant un total de points supérieur à celui-ci ou en voyant ce dernier dépasser 21. Chaque joueur joue contre le croupier, qui représente la banque, ou le casino, et non contre les autres joueurs.
|
||||
Objectif du TP
|
||||
--------------
|
||||
|
||||
Une carte sera un tuple (valeur, couleur).
|
||||
L'objectif est de construire une simulation de partie de Blackjack. Pour cela, la structure du programme est donnée. Vous ne pouvez pas la modifier. Des exemples du fonctionnement de chaque fonctions sont donnés et votre implémentation doit correspondre à ces exemples.
|
||||
|
||||
Le croupier sera représenter par un deck de carte c'est à dire une Pile de cartes.
|
||||
Il n'y a pas d'ordre particulier à respecter pour coder ce projet.
|
||||
|
||||
Chaque joueur sera représenter par une main de carte c'est à dire une liste (au sens de Python) de carte.
|
||||
|
||||
L'ensemble des joueurs sera une file de mains. On ne fera pas de différence entre un jour et le croupier.
|
||||
Règles du jeu (depuis Wikipédia):
|
||||
---------------------------------
|
||||
|
||||
La partie oppose individuellement chaque joueur contre la banque. Le but est de battre le croupier sans dépasser 21. Dès qu'un joueur fait plus que 21, on dit qu'il « Brûle » ou qu'il « crève » et il perd sa mise initiale. La valeur des cartes est établie comme suit :
|
||||
|
||||
de 2 à 9 → valeur nominale de la carte
|
||||
chaque figure + le 10 surnommées "bûche" → 10 points
|
||||
l'As → 1 ou 11 (au choix)
|
||||
Un Blackjack est composé d'un As et d'une « buche » (carte ayant pour valeur 10, donc 10, J, Q ou K). Cependant, si le joueur atteint le point 21 en 3 cartes ou plus on compte le point 21 et non pas Blackjack; de même lorsque le joueur sépare deux as et qu'il reçoit une buche pour l'un d'eux.
|
||||
|
||||
Au début de la partie, le croupier distribue une carte face visible à chaque joueur et tire une carte face visible également pour lui. Il tire ensuite pour chacun une seconde carte face visible et tire une seconde carte face cachée pour lui au Blackjack américain. Au blackjack européen, le croupier tire sa seconde carte après le tour de jeu des joueurs.
|
||||
|
||||
Puis, il demande au premier joueur de la table (joueur situé à sa gauche) l'option qu'il désire choisir. Si le joueur veut une carte, il doit l'annoncer en disant « Carte ! ». Le joueur peut demander autant de cartes qu'il le souhaite pour approcher la valeur sans la dépasser. Si après le tirage d'une carte, il a dépassé 21, il perd sa mise et le croupier passe au joueur suivant. S'il décide de s'arrêter, en disant « Je reste », le croupier passe également au joueur suivant.
|
||||
|
||||
Le croupier répète cette opération jusqu'à ce que tous les joueurs soient servis.
|
||||
|
||||
Ensuite, il joue pour lui selon une règle simple et codifiée « la banque tire à 16, reste à 17 ». Ainsi, le croupier tire des cartes jusqu'à atteindre un nombre compris entre 17 et 21 que l'on appelle un point. S'il fait plus de 21, tous les joueurs restants gagnent mais s'il fait son point, seuls gagnent ceux ayant un point supérieur au sien (sans avoir sauté). Dans cette situation, le joueur remporte l'équivalent de sa mise. En cas d'égalité le joueur garde sa mise mais n'empoche rien en plus. À noter que le blackjack (une bûche et un as en deux cartes) est plus fort que 21 fait en ayant tiré plus de deux cartes. Si un joueur fait blackjack et que le banquier fait 21 en 3 cartes ou plus, le joueur fait blackjack et remporte une fois et demi de sa mise. Le banquier lui gagne contre tous les joueurs ayant 20 ou moins. Réciproquement si la banque a un as et une bûche, elle gagne contre tout joueur ayant 21 en ayant tiré plus de deux cartes. Dans ce cas, si un joueur fait également blackjack, il peut récupérer sa mise mais n'est pas payé, le jeu étant à égalité. Un joueur ayant fait blackjack (sauf blackjack à la banque auquel cas il y a égalité) remporte une fois et demi sa mise.
|
||||
|
||||
|
||||
Modélisation
|
||||
------------
|
||||
|
||||
Une carte sera un tuple (valeur, couleur). Toutes les valeurs possibles sont déjà codée dans la variable CARD_VALUES et les couleurs dans CARD_COLORS (voir plus bas).
|
||||
|
||||
Les joueurs et le croupier seront modélisé par la classe Player qui n'est pas à construire et qui est importé depuis NSI_Bertrand.blackjack.
|
||||
|
||||
Ils s'initialisent avec un nom et ont par défaut une main vide.
|
||||
>>> p = Player("nom")
|
||||
>>> p
|
||||
<Player nom: []>
|
||||
|
||||
Ils ont deux attributs
|
||||
- *hand* qui est liste des cartes qu'ils ont en main
|
||||
>>> p.hand
|
||||
[]
|
||||
|
||||
- *score* qui est le score associé à leur main
|
||||
>>> p.score
|
||||
0
|
||||
|
||||
Ils ont une méthode: want_continue qui permet de donner le choix au joueur de continue.
|
||||
>>> p.want_continue([])
|
||||
True
|
||||
|
||||
L'ensemble des joueurs sera une file de mains.
|
||||
|
||||
Aide et vérifications
|
||||
---------------------
|
||||
|
||||
Vous avez deux façons de tester vos programmes:
|
||||
|
||||
- En écrivant votre utilisation du code dans le "if __name__ == __main__:" puis en exécutant votre script.
|
||||
- En utilisant pytest
|
||||
|
||||
pytest --doctest-modules blackjack.py
|
||||
|
||||
|
||||
Les fonctions à compléter ont déjà été programmées. Si vous avez besoin d'une fonction que vous n'avez pas encore programmée vous même, vous pouvez décommanter les lignes contenant "from NSI_Bertrand.blackjack import ...." à la suite de la fonction.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
import random
|
||||
from .pile import Pile
|
||||
from .file import File
|
||||
import itertools
|
||||
|
||||
values = {
|
||||
2: 2,
|
||||
3: 3,
|
||||
4: 4,
|
||||
5: 5,
|
||||
6: 6,
|
||||
7: 7,
|
||||
8: 8,
|
||||
9: 9,
|
||||
"Valet": 10,
|
||||
"Dame": 10,
|
||||
"Roi": 10,
|
||||
"As": 11, # dans la vrai version du BlackJack, l'As peut valoir 1 ou 11 au choix du joueur.
|
||||
}
|
||||
colors = ["Pique", "Coeur", "Trefle", "Carreau"]
|
||||
# Pour que ces deux lignes marchent, il faut que vous ayez copié vos modules pile et file à coté de ce fichier
|
||||
from pile import Pile
|
||||
from file import File
|
||||
|
||||
# CARD_VALUES = {
|
||||
# 2: 2,
|
||||
# 3: 3,
|
||||
# 4: 4,
|
||||
# 5: 5,
|
||||
# 6: 6,
|
||||
# 7: 7,
|
||||
# 8: 8,
|
||||
# 9: 9,
|
||||
# 10: 10,
|
||||
# "Valet": 10,
|
||||
# "Dame": 10,
|
||||
# "Roi": 10,
|
||||
# "As": 11, # dans la vrai version du BlackJack, l'As peut valoir 1 ou 11 au choix du joueur.
|
||||
# }
|
||||
from NSI_Bertrand.blackjack import values as CARD_VALUES
|
||||
|
||||
|
||||
# CARD_COLORS = ["Pique", "Coeur", "Trefle", "Carreau"]
|
||||
from NSI_Bertrand.blackjack import colors as CARD_COLORS
|
||||
|
||||
# Player class
|
||||
# Cette classe modélise un joueur de carte (un joueur mais aussi le croupier)
|
||||
#
|
||||
from NSI_Bertrand.blackjack import Player
|
||||
|
||||
|
||||
def build_deck():
|
||||
"""Construit une pile de 54 cartes mélangés
|
||||
"""Construit une pile de 52 cartes mélangés
|
||||
|
||||
|
||||
Pour mélanger les cartes de façon aléatoire, vous pouvez utiliser la bibliothèque random.
|
||||
|
||||
:return: Une pile de 54 cartes différentes mélangées
|
||||
:return: Une pile de 52 cartes différentes mélangées
|
||||
|
||||
:example:
|
||||
>>> deck = build_deck()
|
||||
>>> deck.is_empty()
|
||||
False
|
||||
>>> for i in range(54):
|
||||
deck.pop()
|
||||
>>> for i in range(52):
|
||||
... if deck.is_empty():
|
||||
... print(f"Pas assez de cartes. Il y en uniquement {i}")
|
||||
... break
|
||||
... card = deck.pop()
|
||||
>>> deck.is_empty()
|
||||
True
|
||||
"""
|
||||
deck = Pile()
|
||||
return deck
|
||||
pass
|
||||
|
||||
|
||||
# from NSI_Bertrand.blackjack import build_deck
|
||||
|
||||
|
||||
def build_players(nbr):
|
||||
@ -67,36 +143,19 @@ def build_players(nbr):
|
||||
>>> players.is_empty()
|
||||
False
|
||||
>>> for _ in range(3):
|
||||
print(players.pop())
|
||||
[]
|
||||
[]
|
||||
[]
|
||||
... print(players.pop())
|
||||
<Player 0: []>
|
||||
<Player 1: []>
|
||||
<Player 2: []>
|
||||
>>> players.is_empty()
|
||||
True
|
||||
"""
|
||||
players = File()
|
||||
# -----------------------
|
||||
|
||||
# -----------------------
|
||||
return players
|
||||
|
||||
|
||||
def compute_score(hand):
|
||||
"""Calculer le score d'une main
|
||||
|
||||
:param hand: liste de cartes
|
||||
:return: le score associé
|
||||
|
||||
:example:
|
||||
>>> hand = [(2, "Pique"), ("As", "Coeur"), (8, "Carreau")]
|
||||
>>> compute_score(hand)
|
||||
11
|
||||
>>> compute_score([])
|
||||
0
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
# from NSI_Bertrand.blackjack import build_players
|
||||
|
||||
|
||||
def can_play(player):
|
||||
"""détermine si un joueur peu encore jouer
|
||||
|
||||
@ -104,15 +163,75 @@ def can_play(player):
|
||||
:return: True if his score is lower than 21
|
||||
|
||||
:example:
|
||||
>>>
|
||||
>>> hand = [(2, "Pique"), ("As", "Coeur"), (8, "Carreau")]
|
||||
>>> p = Player(1, hand)
|
||||
>>> can_play(p)
|
||||
True
|
||||
>>> hand = [(2, "Pique"), ("As", "Coeur"), (6, "Carreau")]
|
||||
>>> p = Player(1, hand)
|
||||
>>> can_play(p)
|
||||
True
|
||||
>>> hand = [(2, "Pique"), ("As", "Coeur"), ("Valet", "Carreau")]
|
||||
>>> p = Player(1, hand)
|
||||
>>> can_play(p)
|
||||
False
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
# from NSI_Bertrand.blackjack import can_play
|
||||
|
||||
|
||||
def won(player):
|
||||
"""Détermine si un jour a gagné c'est à dire qu'il a atteint les 21 points
|
||||
|
||||
:param player: une joueur avec une main
|
||||
:return: True si le joueur a exactement 21 points
|
||||
|
||||
:example:
|
||||
>>> hand = [(2, "Pique"), ("As", "Coeur"), (8, "Carreau")]
|
||||
>>> p = Player(1, hand)
|
||||
>>> won(p)
|
||||
True
|
||||
>>> hand = [(2, "Pique"), ("As", "Coeur"), (6, "Carreau")]
|
||||
>>> p = Player(1, hand)
|
||||
>>> won(p)
|
||||
False
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
# from NSI_Bertrand.blackjack import won
|
||||
|
||||
|
||||
def draw(player, deck):
|
||||
"""Distribue 1 carte à un joueur
|
||||
|
||||
:param player: Un joueur
|
||||
:param deck: pile avec toutes les cartes
|
||||
|
||||
:return: (player, deck) où le joueur a une carte en plus en main
|
||||
|
||||
:example:
|
||||
>>> player = build_players(1).pop()
|
||||
>>> deck = build_deck()
|
||||
>>> player, deck = draw(player, deck)
|
||||
>>> len(player.hand)
|
||||
1
|
||||
>>> player, deck = draw(player, deck)
|
||||
>>> len(player.hand)
|
||||
2
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
# from NSI_Bertrand.blackjack import draw
|
||||
|
||||
|
||||
def first_draw(players, deck):
|
||||
"""Distribue 2 cartes à chaque joueur
|
||||
|
||||
:param players: pile de joueur avec des mains vides
|
||||
:param players: file de joueur avec des mains vides
|
||||
:param deck: pile avec toutes les cartes
|
||||
|
||||
:return: (players, deck) où les joueurs ont deux cartes et où le deck a été mis à jour.
|
||||
@ -120,9 +239,9 @@ def first_draw(players, deck):
|
||||
:example:
|
||||
>>> players = build_players(3)
|
||||
>>> deck = build_deck()
|
||||
>>> players, deck = fist_draw(players, deck)
|
||||
>>> players, deck = first_draw(players, deck)
|
||||
>>> for i in range(3):
|
||||
print(len(players.pop()))
|
||||
... print(len(players.pop().hand))
|
||||
2
|
||||
2
|
||||
2
|
||||
@ -130,54 +249,25 @@ def first_draw(players, deck):
|
||||
pass
|
||||
|
||||
|
||||
def draw(players, deck):
|
||||
"""Distribue 1 carte à chaque joueur
|
||||
|
||||
:param players: pile de joueur avec des mains non vides
|
||||
:param deck: pile avec toutes les cartes
|
||||
|
||||
:return: (players, deck) où les joueurs ont plus de deux cartes et où le deck a été mis à jour.
|
||||
|
||||
:example:
|
||||
>>> players = build_players(3)
|
||||
>>> deck = build_deck()
|
||||
>>> players, deck = fist_draw(players, deck)
|
||||
>>> players, deck = draw(players, deck)
|
||||
>>> for i in range(3):
|
||||
print(len(players.pop()))
|
||||
3
|
||||
3
|
||||
3
|
||||
"""
|
||||
pass
|
||||
# from NSI_Bertrand.blackjack import first_draw
|
||||
|
||||
|
||||
def play_backjack(nbr_players):
|
||||
"""Simule une partie de blackjack entre "nbr_players"
|
||||
|
||||
On ne vous demande pas de reproduire une simulation parfaite du jeu blackjack. Commencez par une version simple où les joueur s obtiennent petit à petit les cartes. Puis complexifiez en ajoutant une par une les règles.
|
||||
|
||||
La version de correction ne prend pas en compte toutes les règles du jeux ni tout le déroulement d'une partie.
|
||||
|
||||
:param nbr_players: nombre de joueurs
|
||||
|
||||
:return: File de tuples (joueur, score, tour élimination) dans l'ordre d'élimination
|
||||
|
||||
:example:
|
||||
>>>
|
||||
:return: la liste des joueurs gagnants
|
||||
|
||||
"""
|
||||
result = File()
|
||||
# -----------------------
|
||||
pass
|
||||
|
||||
# -----------------------
|
||||
return result
|
||||
|
||||
# from NSI_Bertrand.blackjack import play_backjack
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# Test : Distribution de toutes les cartes
|
||||
j = DeckOfCards()
|
||||
while not j.is_empty():
|
||||
print(j.depile())
|
||||
|
||||
# Test : Calcul de mains de blackjack
|
||||
j = DeckOfCards()
|
||||
while not j.is_empty():
|
||||
mjoueurain_bjack(j)
|
||||
print(play_backjack(3))
|
||||
|
@ -22,7 +22,7 @@ def aff(t):
|
||||
def avance(maze, p):
|
||||
"""Avance dans le labyrinthe"""
|
||||
# on va sur la position du haut de la pile
|
||||
l, c = p.depile()
|
||||
l, c = p.pop()
|
||||
|
||||
# on marque la position comme "exploré"
|
||||
ligne = list(maze[l])
|
||||
@ -34,10 +34,10 @@ def avance(maze, p):
|
||||
# on empile les positions adjacentes libres
|
||||
case = maze[l + dl][c + dc]
|
||||
if case == " ":
|
||||
p.add((l + dl, c + dc))
|
||||
p.append((l + dl, c + dc))
|
||||
# si on a trouver la sortie, on vide la pile
|
||||
if case == "s":
|
||||
p.vide_la_pile()
|
||||
p.empty()
|
||||
return l, c
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ maze = maze_str.split("\n")
|
||||
|
||||
# pile des positions inexplorées
|
||||
p = Pile()
|
||||
p.add(find_e(maze))
|
||||
p.append(find_e(maze))
|
||||
|
||||
# Tant que la pile n'est pas vide ... on avance
|
||||
AFFICHAGE_CONSOLE = False
|
||||
@ -76,7 +76,7 @@ while not p.is_empty() and AFFICHAGE_CONSOLE:
|
||||
|
||||
# Réinitialisation du labyrinthe
|
||||
maze = maze_str.split("\n")
|
||||
p.add(find_e(maze))
|
||||
p.append(find_e(maze))
|
||||
|
||||
# Taille des cellules et du labyrinthe
|
||||
cell_size = 16
|
242
maze/maze.md
242
maze/maze.md
@ -4,248 +4,8 @@ author : TODARO Cédric
|
||||
date : 06 juin 2021
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
Cette activité a pour objectif de vous faire travailler avec la structure de données de type **pile**.
|
||||
|
||||
Elle se déroule en 3 temps :
|
||||
|
||||
- Élaboration de la classe ```Pile```
|
||||
- Utilisation de cette classe pour modéliser un paquet de 52 cartes
|
||||
- Utilisation de cette classe pour établir un algorithme de recherche de chemin "de sortie" dans une d'un labyrinth
|
||||
|
||||
Vous pouvez vous référer au cours de [Quentin Konieczko](#remerciements) en [pdf](https://qkzk.xyz/uploads/docnsitale/poo/2_cours_clean.pdf), en cas de difficulté avec la POO.
|
||||
|
||||
## La classe ```Pile```
|
||||
|
||||
Avec de définir la classe ```Pile```, nous avons besoin de définir la classe ```Node``` qui sera un noeud (une case, un emplacement, ...) de notre pile. Voici ci-dessous la représentation des classes ```Node``` et ```Pile``` :
|
||||
|
||||
![Représentation de la classe ```Node``` et ```Pile```](maze_img01.png)
|
||||
|
||||
### La classe ```Node```
|
||||
|
||||
La classe possède donc 2 attributs :
|
||||
|
||||
- ```self.value``` : Une valeur (qui peut-être de n'importe quel type)
|
||||
- ```self.nxt``` : Le noeud suivant
|
||||
|
||||
> Compléter le code suivant :
|
||||
|
||||
```python
|
||||
class Node():
|
||||
def __init__(self, valeur, suivant):
|
||||
# ----------
|
||||
self.value ...
|
||||
...
|
||||
# ----------
|
||||
```
|
||||
|
||||
### La classe ```Pile```
|
||||
|
||||
La classe ```Pile``` doit possèder un élément "courant" qui est l'élément sur le dessus de la pile. Dans le cas du schéma précédent, ce sera le noeud qui contient le 3 de carreau. Elle doit aussi posèder un entier ```n``` qui compte le nombre d'éléments dans la pile
|
||||
|
||||
Dans la définition d constructeur ```__init__```, nous devons retrouver :
|
||||
|
||||
- ```self.current``` : L'élément en haut de la pile, initialisé par défaut à ```None```.
|
||||
- ```self.n``` : Nombre d'éléments dans la pile, initialisé par défaut à 0.
|
||||
|
||||
> Compléter le code suivant :
|
||||
|
||||
```python
|
||||
class Pile():
|
||||
def __init__(self):
|
||||
# ----------
|
||||
...
|
||||
# ----------
|
||||
```
|
||||
|
||||
La classe ```Pile``` doit possèder les méthodes suivantes :
|
||||
|
||||
- ```is_empty(self)``` : Pour vérifier que la pile est vide.
|
||||
- ```get_top(self)``` : Pour obtenir la valeur de l'élément courant.
|
||||
- ```add(self, valeur)``` : Empile un noeud à la pile.
|
||||
- ```depile(self)``` : Dépile l'élément courant de la pile.
|
||||
- ```vide_la_pile(self)``` : Vide la pile.
|
||||
|
||||
### La ```pile``` est-elle vide ?
|
||||
|
||||
Il est pratique d'implanter une méthode permettant de savoir si la pile est vide.
|
||||
|
||||
- ```is_empty(self)``` : Retourne ```True``` si ```self.current``` est à ```None``` (vous pouvez aussi vérifier la valeur de ```self.n```)
|
||||
|
||||
> Compléter le code suivant :
|
||||
|
||||
```python
|
||||
class Pile():
|
||||
# ....
|
||||
def is_empty(self):
|
||||
# ----------
|
||||
...
|
||||
# ----------
|
||||
```
|
||||
|
||||
### On empile...
|
||||
|
||||
Pour empiler un élément dans la pile, il faut ajouter un ```Node``` qui deviendra le noeud courant de la pile et dont le suivant est l'ancien noeud courant.
|
||||
|
||||
- ```add(self, valeur)``` : Empile un noeud à la pile. Ne pas oublier d'incrémenter ```self.n```.
|
||||
|
||||
> Compléter le code suivant :
|
||||
|
||||
```python
|
||||
class Pile():
|
||||
# ....
|
||||
def add(self,valeur):
|
||||
# ----------
|
||||
...
|
||||
# ----------
|
||||
```
|
||||
|
||||
### ... et on "dépile"
|
||||
|
||||
La méthode ```depile(self)``` doit retourner la valeur de l'élément courant et faire de l'élément suivant de d'élément courant, le nouvel élément courant.
|
||||
|
||||
- ```depile(self)``` : Retourne la valeur de l'élément courant et le retire de la pile. Ne pas oublier de décrémenter ```self.n```. Si la liste est vide, ```depile(self)``` retourne ```None```.
|
||||
|
||||
> Compléter le code suivant :
|
||||
|
||||
```python
|
||||
class Pile():
|
||||
# ....
|
||||
def depile(self):
|
||||
# ----------
|
||||
...
|
||||
# ----------
|
||||
```
|
||||
|
||||
### Être au top !
|
||||
|
||||
La méthode ```get_top(self)``` doit retourner la valeur de l'élément courant si la liste n'est pas vide.
|
||||
|
||||
- ```get_top(self)``` : Retourne la valeur de l'élément courant. Si la liste est vide, ```get_top(self)``` retourne ```None```.
|
||||
|
||||
> Compléter le code suivant :
|
||||
|
||||
```python
|
||||
class Pile():
|
||||
# ....
|
||||
def get_top(self):
|
||||
# ----------
|
||||
...
|
||||
# ----------
|
||||
```
|
||||
|
||||
### Tout vider
|
||||
|
||||
La méthode ```vide_la_pile(self)``` permet de vider la pile.
|
||||
|
||||
- ```vide_la_pile(self)``` : Depile les éléments tant que la pile n'est pas vide.
|
||||
|
||||
> Compléter le code suivant :
|
||||
|
||||
```python
|
||||
class Pile():
|
||||
# ....
|
||||
def get_top(self):
|
||||
# ----------
|
||||
...
|
||||
# ----------
|
||||
```
|
||||
|
||||
### Tests
|
||||
|
||||
A ce stade, vous pouvez tester toutes les méthodes de votre ```Pile``` :
|
||||
|
||||
```python
|
||||
>>> p=Pile()
|
||||
>>> p.is_empty()
|
||||
True
|
||||
>>> p.add("Patate")
|
||||
>>> p.is_empty()
|
||||
False
|
||||
>>> p.get_top()
|
||||
'Patate'
|
||||
>>> p.add(6)
|
||||
>>> p.get_top()
|
||||
6
|
||||
>>> p.add(789)
|
||||
>>> p.add(["a","b"])
|
||||
>>> p.add((1,2,3,4,5,6,7))
|
||||
>>> p.get_top()
|
||||
(1, 2, 3, 4, 5, 6, 7)
|
||||
>>> p.depile()
|
||||
(1, 2, 3, 4, 5, 6, 7)
|
||||
>>> p.depile()
|
||||
['a', 'b']
|
||||
>>> p.depile()
|
||||
789
|
||||
>>> p.depile()
|
||||
6
|
||||
>>> p.depile()
|
||||
'Patate'
|
||||
>>> p.depile()
|
||||
>>> p.is_empty()
|
||||
True
|
||||
```
|
||||
|
||||
## Un jeu de cartes
|
||||
|
||||
On peut utiliser une pile pour modéliser un jeu de cartes.
|
||||
|
||||
![Un jeu de cartes](maze_img02.png)
|
||||
|
||||
Pour cela, il faut :
|
||||
|
||||
- Générer une liste ```jeu_trie``` de tuples ```(valeur,couleur)``` de toutes les cartes d'un jeu de 52 cartes.
|
||||
- Choisir au hasard un élément parmi ```jeu_trie```.
|
||||
- Empiler cet élément dans une pile et le retirer de ```jeu_trie```.
|
||||
- Recommencer jusqu'à ce que la liste soit vide.
|
||||
|
||||
> Écrire une fonction ```DeckOfCards()``` qui retourne un jeu de cartes mélangé.
|
||||
|
||||
```python
|
||||
def DeckOfCards():
|
||||
jeu = Pile()
|
||||
|
||||
jeu_trie = []
|
||||
for valeur in [2,3,4,5,6,7,8,9,10,"Valet","Dame","Roi","As"]:
|
||||
for couleur in ["Pique","Coeur","Trèfle","Carreau"]:
|
||||
# ...
|
||||
# ...
|
||||
return jeu
|
||||
```
|
||||
|
||||
**Remarque :** ```list.pop(i)``` enlève de la liste l'élément situé à la position indiquée et le renvoie en valeur de retour. Si aucune position n'est spécifiée, a.pop() enlève et renvoie le dernier élément de la liste.
|
||||
|
||||
### Blackjack
|
||||
|
||||
> But du jeu : Après avoir reçu deux cartes, le joueur tire des cartes pour s’approcher de la valeur 21 sans la dépasser. Le but du joueur est de battre le croupier en obtenant un total de points supérieur à celui-ci ou en voyant ce dernier dépasser 21. Chaque joueur joue contre le croupier, qui représente la banque, ou le casino, et non contre les autres joueurs.
|
||||
|
||||
A ce stade, vous pouvez écrire une fonction qui tire 2 cartes dans un jeu de cartes et qui calcule la valeur de la main de Blackjack correspondant.
|
||||
|
||||
```python
|
||||
def main_bjack(jeu):
|
||||
# ...
|
||||
```
|
||||
|
||||
La pile utilisé pour piocher les cartes étant la même pour chaque tirage, vous devriez toujours obtenir des cartes différentes.
|
||||
|
||||
```python
|
||||
>>> j=DeckOfCards()
|
||||
>>> while(not j.is_empty()):
|
||||
... main_bjack(j)
|
||||
...
|
||||
('Dame', 'Carreau') (3, 'Trèfle') 13
|
||||
13
|
||||
(8, 'Carreau') (5, 'Carreau') 13
|
||||
13
|
||||
(6, 'Coeur') ('As', 'Pique') 17
|
||||
17
|
||||
...
|
||||
...
|
||||
```
|
||||
|
||||
## Sortir d'un labyrinthe
|
||||
# Sortir d'un labyrinthe
|
||||
|
||||
On peut modéliser un labyrinthe par une chaîne de caractères de la manière suivante :
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user