Commit 0ec8bc18 authored by Guillaume DEWISME's avatar Guillaume DEWISME

init

parents
Pipeline #3068 failed with stages
# poker_game.py
import random
from treys import Card as TreysCard, Evaluator, Deck as TreysDeck
from typing import List, Optional
class Carte:
"""Représente une carte unique dans le jeu de poker."""
def __init__(self, card_int: int):
self.carte = card_int
def __str__(self):
return TreysCard.int_to_pretty_str(self.carte)
class Player:
"""Gère les informations et actions d'un joueur."""
def __init__(self, name: str, jetons: int = 1000):
self.name = name
self.jetons = jetons
self.main: List[Carte] = []
self.est_actif = True # Indique si le joueur est toujours dans la manche
def miser(self, montant: int) -> int:
"""Permet au joueur de miser une certaine quantité de jetons."""
montant_mis = min(montant, self.jetons)
self.jetons -= montant_mis
return montant_mis
def se_coucher(self):
"""Permet au joueur de se coucher."""
self.est_actif = False
def recevoir_carte(self, carte: Carte):
"""Permet au joueur de recevoir une carte."""
self.main.append(carte)
def __str__(self):
cartes = ' '.join(str(carte) for carte in self.main)
statut = "Actif" if self.est_actif else "Couché"
return f"{self.name}: Jetons={self.jetons}, Cartes=[{cartes}], Statut={statut}"
class Table:
"""Gère les cartes communes, le pot et les phases du jeu."""
def __init__(self):
self.deck = TreysDeck()
self.evaluator = Evaluator()
self.flop: List[Carte] = []
self.turn: Optional[Carte] = None
self.river: Optional[Carte] = None
self.pot: int = 0
def distribuer_cartes(self, joueurs: List[Player]):
"""Distribue deux cartes à chaque joueur actif."""
for joueur in joueurs:
joueur.recevoir_carte(Carte(self.deck.draw(1)[0]))
joueur.recevoir_carte(Carte(self.deck.draw(1)[0]))
def reveal_flop(self):
"""Révèle le flop (3 cartes)."""
self.flop = [Carte(card) for card in self.deck.draw(3)]
def reveal_turn(self):
"""Révèle le turn (1 carte)."""
self.turn = Carte(self.deck.draw(1)[0])
def reveal_river(self):
"""Révèle la river (1 carte)."""
self.river = Carte(self.deck.draw(1)[0])
def afficher_cartes_communes(self) -> str:
"""Retourne une chaîne représentant les cartes communes."""
cartes = self.flop.copy()
if self.turn:
cartes.append(self.turn)
if self.river:
cartes.append(self.river)
return ' '.join(str(carte) for carte in cartes)
def reset_table(self):
"""Réinitialise la table pour une nouvelle manche."""
self.deck = TreysDeck()
self.deck.shuffle()
self.flop = []
self.turn = None
self.river = None
self.pot = 0
class Partie:
"""Coordonne le déroulement global de la partie."""
def __init__(self, joueurs: List[Player]):
self.joueurs = joueurs
self.table = Table()
self.evaluator = Evaluator()
def demarrer(self):
"""Démarre la partie et continue jusqu'à ce qu'un seul joueur reste."""
while self.nombre_joueurs_actifs() > 1:
self.manche()
self.declarer_gagnant_final()
def manche(self):
"""Gère une manche complète de poker."""
print("\n--- Nouvelle Manche ---")
self.table.reset_table()
active_joueurs = self.joueurs_actifs()
for joueur in active_joueurs:
joueur.main = []
joueur.est_actif = True
self.table.distribuer_cartes(active_joueurs)
print("Cartes distribuées aux joueurs.")
# Afficher les cartes privées des joueurs un par un
for joueur in active_joueurs:
input(f"\n{joueur.name}, appuyez sur Entrée pour voir vos cartes...")
print(f"Vos cartes : {joueur.main[0]} {joueur.main[1]}")
input("Appuyez sur Entrée pour passer au joueur suivant...")
# Phase Pre-Flop
if self.phase_mise(active_joueurs, "Pre-Flop"):
return # Manche terminée par un gagnant
# Flop
self.table.reveal_flop()
print(f"\nFlop: {self.table.afficher_cartes_communes()}")
if self.phase_mise(active_joueurs, "Flop"):
return # Manche terminée par un gagnant
# Turn
self.table.reveal_turn()
print(f"\nTurn: {self.table.afficher_cartes_communes()}")
if self.phase_mise(active_joueurs, "Turn"):
return # Manche terminée par un gagnant
# River
self.table.reveal_river()
print(f"\nRiver: {self.table.afficher_cartes_communes()}")
if self.phase_mise(active_joueurs, "River"):
return # Manche terminée par un gagnant
# Détermination du gagnant
self.determiner_gagnant(active_joueurs)
# Élimination des joueurs sans jetons
self.eliminer_joueurs()
def phase_mise(self, joueurs: List[Player], phase: str) -> bool:
"""
Gère la phase de mise pour chaque joueur actif.
Retourne True si un gagnant a été déterminé (tous sauf un se sont couchés).
"""
print(f"\n--- Phase: {phase} ---")
for joueur in joueurs:
if joueur.est_actif:
action, montant = self.obtenir_action(joueur)
if action == 'miser':
mis = joueur.miser(montant)
self.table.pot += mis
print(f"{joueur.name} mise {mis} jetons. Pot actuel: {self.table.pot}")
elif action == 'se coucher':
joueur.se_coucher()
print(f"{joueur.name} se couche.")
# Vérifier s'il ne reste qu'un seul joueur actif
if self.nombre_joueurs_actifs() == 1:
gagnant = self.joueurs_actifs()[0]
gagnant.jetons += self.table.pot
print(
f"\n{gagnant.name} remporte le pot de {self.table.pot} jetons en ayant les autres joueurs couchés!")
return True # Manche terminée
return False # Continuer la manche
def obtenir_action(self, joueur: Player) -> (str, int):
"""Obtient l'action d'un joueur humain."""
while True:
action = input(f"{joueur.name}, choisissez une action (miser/se coucher): ").strip().lower()
if action not in ['miser', 'se coucher']:
print("Action invalide. Veuillez choisir 'miser' ou 'se coucher'.")
continue
if action == 'miser':
montant = self.demander_montant(joueur)
return 'miser', montant
else:
return 'se coucher', 0
def demander_montant(self, joueur: Player) -> int:
"""Demande au joueur humain le montant à miser."""
while True:
try:
montant = int(
input(f"{joueur.name}, combien voulez-vous miser? (Jetons disponibles: {joueur.jetons}): "))
if 0 < montant <= joueur.jetons:
return montant
else:
print("Montant invalide. Veuillez entrer un nombre entre 1 et vos jetons disponibles.")
except ValueError:
print("Entrée invalide. Veuillez entrer un nombre entier.")
def determiner_gagnant(self, joueurs: List[Player]):
"""Détermine le gagnant de la manche."""
actifs = [j for j in joueurs if j.est_actif]
if len(actifs) == 1:
gagnant = actifs[0]
gagnant.jetons += self.table.pot
print(f"\n{gagnant.name} remporte le pot de {self.table.pot} jetons en ayant les autres joueurs couchés!")
return
# Évaluer les mains des joueurs actifs
meilleures_mains = {}
for joueur in actifs:
cartes_joueur = [carte.carte for carte in joueur.main] + [carte.carte for carte in self.table.flop]
if self.table.turn:
cartes_joueur.append(self.table.turn.carte)
if self.table.river:
cartes_joueur.append(self.table.river.carte)
score = self.evaluator.evaluate([carte.carte for carte in self.table.flop], cartes_joueur)
meilleures_mains[joueur] = score
print(f"{joueur.name} a une main avec un score de {score}.")
# Trouver le joueur avec le meilleur score (le plus bas)
gagnant = min(meilleures_mains, key=meilleures_mains.get)
gagnant.jetons += self.table.pot
print(f"\n{gagnant.name} remporte le pot de {self.table.pot} jetons avec la meilleure main!")
# Afficher les cartes des joueurs
self.afficher_mains_joueurs(hidden=False)
def afficher_mains_joueurs(self, hidden: bool = True):
"""Affiche les mains des joueurs. Si 'hidden' est True, cache les cartes des joueurs."""
for joueur in self.joueurs:
if hidden:
print(f"{joueur.name}: Cartes=[?? ??]")
else:
cartes = ' '.join(str(carte) for carte in joueur.main)
print(f"{joueur.name}: Cartes=[{cartes}]")
def joueurs_actifs(self) -> List[Player]:
"""Retourne la liste des joueurs actifs (ayant des jetons)."""
return [j for j in self.joueurs if j.jetons > 0 and j.est_actif]
def nombre_joueurs_actifs(self) -> int:
"""Retourne le nombre de joueurs actifs."""
return len(self.joueurs_actifs())
def eliminer_joueurs(self):
"""Élimine les joueurs qui n'ont plus de jetons."""
for joueur in self.joueurs:
if joueur.jetons <= 0 and joueur.est_actif:
joueur.est_actif = False
print(f"{joueur.name} est éliminé de la partie!")
def declarer_gagnant_final(self):
"""Déclare le gagnant final de la partie."""
gagnants = [j for j in self.joueurs if j.jetons > 0]
if gagnants:
gagnant = max(gagnants, key=lambda x: x.jetons)
print(f"\nLe gagnant de la partie est {gagnant.name} avec {gagnant.jetons} jetons!")
else:
print("\nTous les joueurs ont été éliminés. Personne ne gagne la partie!")
def creer_joueurs() -> List[Player]:
"""Crée les joueurs humains pour la partie."""
joueurs = []
while True:
try:
nombres = int(input("Combien de joueurs participent? (2-6): "))
if 2 <= nombres <= 6:
break
else:
print("Veuillez entrer un nombre de joueurs entre 2 et 6.")
except ValueError:
print("Entrée invalide. Veuillez entrer un nombre entier.")
for i in range(nombres):
nom = input(f"Entrez le nom du joueur {i + 1}: ").strip()
if not nom:
nom = f"Joueur{i + 1}"
joueurs.append(Player(nom))
return joueurs
def main():
"""Point d'entrée principal du jeu."""
print("Bienvenue au jeu de Poker Texas Hold'em!")
joueurs = creer_joueurs()
partie = Partie(joueurs)
partie.demarrer()
if __name__ == "__main__":
main()
'''
explication:
Oui, dans le programme Python que j'ai fourni, les **combinaisons de cartes** sont bien gérées grâce à l'utilisation de la librairie **`treys`**. Voici une explication détaillée de ce qui est géré dans le programme et comment les combinaisons sont prises en compte.
## **Gestion des Combinaisons de Cartes**
Le programme utilise la classe **`Evaluator`** de la librairie `treys` pour évaluer la force des mains des joueurs. Voici comment cela fonctionne :
1. **Distribution des Cartes :**
- Chaque joueur reçoit **deux cartes privées** ("hole cards").
- **Cinq cartes communes** sont distribuées au centre de la table en trois phases : **Flop** (3 cartes), **Turn** (1 carte), et **River** (1 carte).
2. **Évaluation des Mains :**
- À la fin de la dernière phase de mise (River), le programme combine les deux cartes privées de chaque joueur avec les cinq cartes communes pour former une main de cinq cartes.
- La classe **`Evaluator`** calcule un **score** pour chaque main, où un score plus bas indique une main plus forte.
- Le joueur avec le **score le plus bas** remporte le pot.
**Exemple :**
```python
score = self.evaluator.evaluate([carte.carte for carte in self.table.flop], cartes_joueur)
```
## **Fonctionnalités Gérées par le Programme**
Voici un aperçu complet des fonctionnalités et des composants gérés par le programme :
### **1. Classes Principales**
#### **a. Carte**
- **Description :** Représente une carte individuelle.
- **Attributs :**
- `carte` : Représente la carte sous forme d'entier (utilisé par `treys`).
- **Méthodes :**
- `__str__` : Retourne une représentation lisible de la carte (ex. : "A♠").
#### **b. Player**
- **Description :** Gère les informations et actions d'un joueur.
- **Attributs :**
- `name` : Nom du joueur.
- `jetons` : Nombre de jetons du joueur.
- `main` : Liste des cartes privées du joueur.
- `est_actif` : Indique si le joueur est toujours dans la manche.
- **Méthodes :**
- `miser(montant)` : Permet au joueur de miser une certaine quantité de jetons.
- `se_coucher()` : Permet au joueur de se coucher (abandonner la manche).
- `recevoir_carte(carte)` : Permet au joueur de recevoir une carte.
- `__str__()` : Retourne une représentation lisible des informations du joueur.
#### **c. Table**
- **Description :** Gère les cartes communes, le pot et les phases du jeu.
- **Attributs :**
- `deck` : Instance du paquet de cartes (`treys.Deck`).
- `evaluator` : Instance de l'évaluateur de mains (`treys.Evaluator`).
- `flop`, `turn`, `river` : Listes de cartes communes.
- `pot` : Total des jetons misés.
- **Méthodes :**
- `distribuer_cartes(joueurs)` : Distribue deux cartes à chaque joueur actif.
- `reveal_flop()` : Révèle les trois premières cartes communes (Flop).
- `reveal_turn()` : Révèle la quatrième carte commune (Turn).
- `reveal_river()` : Révèle la cinquième carte commune (River).
- `afficher_cartes_communes()` : Retourne une chaîne de caractères représentant les cartes communes.
- `reset_table()` : Réinitialise la table pour une nouvelle manche.
#### **d. Partie**
- **Description :** Coordonne le déroulement global de la partie.
- **Attributs :**
- `joueurs` : Liste des joueurs.
- `table` : Instance de la table de jeu.
- `evaluator` : Instance de l'évaluateur de mains.
- **Méthodes :**
- `demarrer()` : Démarre la partie et continue jusqu'à ce qu'un seul joueur reste.
- `manche()` : Gère une manche complète de poker.
- `phase_mise(joueurs, phase)` : Gère la phase de mise pour chaque joueur actif.
- `obtenir_action(joueur)` : Obtient l'action d'un joueur humain.
- `interaction_humaine(joueur)` : Gère l'interaction avec un joueur humain pour obtenir son action.
- `demander_montant(joueur)` : Demande au joueur humain le montant à miser.
- `determiner_gagnant(joueurs)` : Détermine le gagnant de la manche.
- `afficher_mains_joueurs(hidden)` : Affiche les mains des joueurs (cachées ou révélées).
- `joueurs_actifs()` : Retourne la liste des joueurs actifs.
- `nombre_joueurs_actifs()` : Retourne le nombre de joueurs actifs.
- `eliminer_joueurs()` : Élimine les joueurs qui n'ont plus de jetons.
- `declarer_gagnant_final()` : Déclare le gagnant final de la partie.
### **2. Fonctionnalités Clés**
#### **a. Distribution des Cartes**
- **Pre-Flop :** Chaque joueur actif reçoit deux cartes privées.
- **Flop :** Trois cartes communes sont révélées.
- **Turn :** Une quatrième carte commune est révélée.
- **River :** Une cinquième carte commune est révélée.
#### **b. Phases de Mise**
- **Pre-Flop, Flop, Turn, River :** À chaque phase, les joueurs actifs peuvent choisir de **miser** ou de **se coucher**.
#### **c. Évaluation des Mains**
- Utilisation de **`Evaluator.evaluate`** pour déterminer la force de la main de chaque joueur en combinant leurs cartes privées avec les cartes communes.
- Le joueur avec le **score le plus bas** remporte le pot.
#### **d. Gestion du Pot**
- Chaque mise effectuée par un joueur est ajoutée au pot total de la table.
#### **e. Élimination des Joueurs**
- Les joueurs qui n'ont plus de jetons après une manche sont éliminés de la partie.
#### **f. Déclaration du Gagnant**
- La partie continue jusqu'à ce qu'il ne reste qu'un seul joueur avec des jetons. Ce joueur est déclaré gagnant.
### **3. Interactions avec l'Utilisateur**
- **Entrée Utilisateur :**
- Nombre de joueurs (entre 2 et 6).
- Nom de chaque joueur.
- Actions des joueurs pendant les phases de mise (choix entre "miser" ou "se coucher").
- Montant à miser lorsque l'action "miser" est choisie.
- **Sortie :**
- Affichage des cartes distribuées aux joueurs (cachées pendant les mises).
- Affichage des cartes communes après chaque phase (Flop, Turn, River).
- Informations sur les mises effectuées et le pot actuel.
- Annonces des gagnants des manches et du gagnant final de la partie.
## **Résumé des Composants et Fonctionnalités Gérées**
1. **Classes et Objets :**
- **Carte** : Gestion des cartes individuelles.
- **Player** : Gestion des informations et actions des joueurs humains.
- **Table** : Gestion des cartes communes, du pot, et des phases du jeu.
- **Partie** : Coordination des manches, des mises, de l'évaluation des mains, et de la déclaration des gagnants.
2. **Phases du Jeu :**
- **Pre-Flop** : Distribution des cartes privées et premier tour de mises.
- **Flop** : Révélation de trois cartes communes et second tour de mises.
- **Turn** : Révélation d'une quatrième carte commune et troisième tour de mises.
- **River** : Révélation d'une cinquième carte commune et dernier tour de mises.
- **Showdown** : Évaluation des mains et détermination du gagnant.
3. **Actions des Joueurs :**
- **Miser** : Placer des jetons dans le pot.
- **Se Coucher** : Abandonner la manche.
4. **Gestion du Pot :**
- Accumulation des mises des joueurs pendant chaque phase.
- Attribution du pot au gagnant de la manche.
5. **Évaluation des Mains :**
- Utilisation de `treys.Evaluator` pour déterminer la force des mains.
- Comparaison des scores pour identifier le joueur gagnant.
6. **Élimination et Déclaration du Gagnant Final :**
- Élimination des joueurs sans jetons après chaque manche.
- Continuer la partie jusqu'à ce qu'un seul joueur reste avec des jetons.
## **Conclusion**
Le programme gère efficacement les **combinaisons de cartes** grâce à la librairie `treys`, ce qui permet d'évaluer et de comparer les mains des joueurs de manière précise. De plus, il couvre toutes les phases essentielles d'une partie de Texas Hold'em, incluant la distribution des cartes, les phases de mise, l'évaluation des mains, et la gestion du pot.
### **Points Forts du Programme :**
- **Programmation Orientée Objet :** Utilisation de classes pour encapsuler les différentes responsabilités du jeu.
- **Évaluation des Mains :** Intégration de `treys` pour une évaluation précise et fiable des combinaisons de cartes.
- **Gestion des Interactions :** Interface utilisateur simple et intuitive pour guider les joueurs à travers les différentes phases de la partie.
- **Gestion des Jetons et des Éliminations :** Suivi des jetons des joueurs et élimination automatique des joueurs sans jetons.
### **Améliorations Futures Possibles :**
- **Ajouter les Blinds :** Introduire les mises obligatoires (small blind et big blind) au début de chaque manche.
- **Options de Mise Avancées :** Ajouter des options comme relancer (raise), égaliser (call), ou checker (check).
- **Interface Graphique :** Créer une interface utilisateur plus conviviale en utilisant des bibliothèques comme `tkinter` ou `pygame`.
- **Sauvegarde des Scores :** Enregistrer les scores et les statistiques des joueurs pour suivre les performances sur plusieurs parties.
- **Support Multijoueur Réseau :** Permettre à plusieurs joueurs de jouer en réseau via des sockets ou une API web.
N'hésitez pas à personnaliser et étendre ce programme selon vos besoins et votre créativité. Si vous avez d'autres questions ou besoin d'assistance supplémentaire, je suis là pour vous aider !
'''
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment