Last active
October 4, 2025 08:20
-
-
Save SebDeclercq/6c097a8caeebce4fb11844a18dfd6405 to your computer and use it in GitHub Desktop.
Jeux de cartes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import random | |
| import time | |
| import sys | |
| # Classe qui définit un jeu de cartes | |
| class JeuDeCartes: | |
| def __init__(self): | |
| # Un jeu possède des cartes de 4 couleurs | |
| # mais est généralement utilisé en un seul paquet | |
| self.paquet = [] | |
| for couleur in ["carreau", "coeur", "pique", "trèfle"]: # Pour chaque couleur | |
| for valeur in list(range(2,11)): # Pour chaque carte numérique | |
| carte = Carte(couleur, valeur) # Crée l'objet | |
| self.paquet.append(carte) # Et l'insère dans le paquet | |
| for (nom, valeur) in {"as": 14, "valet": 11, "dame": 12, "roi": 13}.items(): # Pour chaque carte "nommée" | |
| carte = Carte(couleur, valeur, nom) # Crée l'objet | |
| self.paquet.append(carte) # Et l'insère dans le paquet | |
| self.melange() # Mélange automatiquement le paquet | |
| self.position = 0 | |
| self.paquetPourDistribue = self.paquet.copy() | |
| def melange(self): # Méthode qui | |
| random.shuffle(self.paquet) # mélange le paquet | |
| return self.paquet # et le retourne | |
| def choisitCarte(self, paquet=None): # Méthode qui permet de tirer une carte au hasard | |
| carte = "" | |
| if (len(self.paquetPourDistribue) > 0): # s'il en reste au moins une | |
| carte = self.paquetPourDistribue.pop(random.randrange(len(self.paquetPourDistribue))) | |
| return carte | |
| def __iter__(self): | |
| return iter(self.paquet) | |
| def __next__(self): | |
| carte = self.paquet[self.position] | |
| self.position += 1 | |
| return carte | |
| # Classe qui définit les cartes à jouer | |
| class Carte: | |
| def __init__(self, couleur, valeur, nom=None): | |
| if not nom: nom = valeur | |
| self.couleur, self.valeur, self.nom = couleur, int(valeur), nom | |
| def __str__(self): | |
| mapping = {"carreau": "♦", "coeur": "♥", "pique": "♠", "trèfle": "♣"} | |
| return f"{mapping[self.couleur]} {self.nom}" | |
| def __repr__(self): | |
| return f"{self.couleur}.{self.nom}" | |
| class Jeu: | |
| # Constructeur de la classe | |
| def __init__(self, nbJoueurs=2, interactif=True): | |
| self.interactif = interactif | |
| if self.interactif: | |
| print(f"\033[1mSaisir q ou quit pour quitter le jeu\033[0m") | |
| self.jeu = JeuDeCartes() # Instiancie le jeu de cartes | |
| self.mains = {} | |
| for i in range(nbJoueurs): # Pour chaque joueur | |
| self.mains["joueur" + str(i + 1)] = [] # Crée une main | |
| self.distribue() # Distribue les cartes | |
| # Méthode qui permet de distribuer les cartes aux joueurs | |
| def distribue(self): | |
| nbCartesParJoueur = 52 // len(self.mains) # Récupère le nombre de cartes à distribuer en fonction du nombre de joueurs | |
| for joueur in self.mains: # Pour chaque joueur | |
| for i in range(nbCartesParJoueur): | |
| self.mains[joueur].append(self.jeu.choisitCarte()) # Pioche les cartes et crée sa main | |
| # Méhode qui gère l'interaction avec l'utilisateur | |
| def gereInteraction(self): | |
| if self.interactif: # Si mode interactif | |
| key = input().rstrip() # Attend l'input | |
| if key == "q" or key == "quit": # Quitte si demande | |
| print(f"Fin du jeu") | |
| exit() | |
| elif len(key) > 0 and key[0] == "a": # Si "affichage" | |
| joueur = key[2:] if len(key) > 1 else "all" # Si un nom de joueur spécifique est demandé, sinon, tous | |
| if joueur in self.mains.keys(): | |
| print(f"{joueur} a les cartes suivantes : ", end="") | |
| for carte in self.mains[joueur]: # Affiche chaque carte du joueur | |
| print(carte, end=", ") | |
| print("") | |
| elif joueur == "all": # Pour chaque joueur | |
| for (joueur, main) in self.mains.items(): | |
| print(f"{joueur} a les cartes suivantes : ", end="") | |
| for carte in main: # Affiche chaque carte du joueur | |
| print(carte, end=", ") | |
| print("") | |
| else: # Si mode automatique | |
| time.sleep(0.5) | |
| def joue(self): # Méthode à créer obligatoirement | |
| raise NotImplementedError # chez les classes filles | |
| # Classe qui permet de faire un jeu de bataille | |
| class Bataille(Jeu): | |
| # Méthode qui initialise le jeu | |
| def joue(self): | |
| while len(self.mains) > 1: # S'il reste plus d'un joueur | |
| self.tour() # Un nouveau tour est lancé (voir méthode self.tour()) | |
| print("RESTE: ") | |
| for (joueur, main) in self.mains.copy().items(): # Pour chaque joueur et sa main | |
| if (len(main) == 0): # S'il n'a plus de carte après le dernier tour joué | |
| del self.mains[joueur] # Le joueur est éliminé | |
| print(f"\n\033[1m{joueur} est éliminé !\033[0m") | |
| else: # Sinon, affiche simplement le nombre de cartes restantes | |
| print(f"{joueur}:{len(main)}", end=" ") | |
| self.gereInteraction() | |
| vainqueur = list(self.mains.keys())[0] | |
| print(f"\n\033[1m{vainqueur} a gagné !\033[0m") # Si l'on quitte le while, c'est qu'il ne reste que le VAINQUEUR \o/ | |
| # Méthode qui effectue le déroulement complet d'un tour | |
| def tour(self): | |
| tour = {} | |
| for (joueur, main) in self.mains.items(): # Pour chaque joueur | |
| carte = main.pop(0) # Prend la carte du dessus | |
| tour[joueur] = {"carte": carte, "score": carte.valeur} # Et alimente le résultat du tour pour le joueur | |
| scoreMax, vainqueur = None, None | |
| i = 32 # Pour le code couleur | |
| for (joueur, details) in tour.items(): # Pour chaque joueur ayant participé au tour | |
| if self.interactif: # Si mode interactif, imprime le nom de la carte | |
| print(f"\033[{i}m{joueur} : \033[1m{details['carte']}\033[0m") | |
| if not scoreMax: # Si aucun scoreMax n'a été attribué | |
| scoreMax, vainqueur = details["score"], joueur # Prend celui du joueur et classe le jour vainqueur du tour | |
| else: # Sinon | |
| if details["score"] > scoreMax: # Si le score du joueur est supérieur au scoreMax | |
| scoreMax, vainqueur = details["score"], joueur # Prend celui du joueur et classe le jour vainqueur du tour | |
| elif details["score"] == scoreMax: # Si le score est identique, il y a égalité | |
| vainqueur = None # et donc aucun vainqueur | |
| else: # Sinon, c'est que le joueur a perdu le tour | |
| continue | |
| i += 1 # Incrémente le code couleur | |
| if vainqueur: # S'il y a un vainqueur (i.e. pas égalité) | |
| if self.interactif: | |
| print(f"{vainqueur} gagne") | |
| self.donneCartesVainqueur(vainqueur, tour) # Lui donne toutes les cartes jouées ce tour-ci | |
| else: # Sinon, il y a bataille ! | |
| print(f"\033[1mBataille !\033[0m") | |
| cartesRetournees = [] | |
| while not vainqueur: # Tant qu'il n'y a aucun vainqueur, la bataille continue | |
| for main in self.mains.values(): # Dans chaque main | |
| carte = main.pop(0) # prend la carte du dessus | |
| cartesRetournees.append(carte) # et la met dans le tas | |
| vainqueur, tour = self.tour() # La bataille consiste en un tour supplémentaire | |
| self.donneCartesVainqueur(vainqueur, tour) # Distribue les cartes du denier tour au vainqueur | |
| if self.interactif: | |
| print(f"Les cartes retournées sont :", end=" ") | |
| for carte in cartesRetournees: # ainsi que toutes les cartes du pot | |
| if self.interactif: | |
| print(f"\033[1m{carte}\033[0m", end=" ") | |
| self.mains[vainqueur].append(carte) | |
| print("") | |
| return vainqueur, tour # Retourne le nom du vainqueur et le contenu du dernier tour | |
| # Méthode qui permet de donner les cartes au bon joueur | |
| def donneCartesVainqueur(self, vainqueur, tour): | |
| for (joueur, details) in tour.items(): | |
| self.mains[vainqueur].append(details["carte"]) | |
| # Classe qui permet de faire un jeu de pouilleux/valet puant/zwarte piet | |
| class Pouilleux(Jeu): | |
| # Méthode qui initialise le jeu | |
| def joue(self): | |
| # 1. SUPPRIME LE VALET DE TRÈFLE | |
| for (joueur, main) in self.mains.items(): | |
| i = 0 | |
| for carte in main: | |
| if carte.couleur == "trèfle" and carte.nom == "valet": | |
| main.pop(i) | |
| # 2. GÉNÈRE LES PAIRES | |
| self.paires = [] | |
| for carte in self.jeu: | |
| for (couleur1, couleur2) in {"coeur": "carreau", "pique": "trèfle"}.items(): # Pour chaque paire de couleur (rouge/noire) | |
| if carte.couleur == couleur1: | |
| for carte2 in self.jeu: | |
| if carte2.couleur == couleur2 and carte2.valeur == carte.valeur: | |
| self.paires.append([carte, carte2]) # Récupère les paires par couleur dans une liste | |
| # 3. SUPPRIME LES PAIRES DANS LES MAINS DISTRIBUÉES | |
| for main in self.mains.values(): | |
| self.supprimePaires(main) | |
| # 4. LANCE LE JEU | |
| while len(self.mains) > 1: | |
| self.tour() | |
| # Méthode qui effectue le déroulement complet d'un tour | |
| def tour(self): | |
| ordreJoueurs = list(self.mains.keys()) # Récupère l'ordre des joueurs pour savoir qui pioche chez qui | |
| i, j = 1, 32 # Instancie un compteur et le code couleur | |
| for joueur in ordreJoueurs: # Détermine pour chaque joueur chez qui il pioche | |
| if i < len(ordreJoueurs): | |
| pioche = ordreJoueurs[i] | |
| else: | |
| pioche = ordreJoueurs[0] | |
| i += 1 | |
| nbCartesJoueur, nbCartesPioche = len(self.mains[joueur]), len(self.mains[pioche]) # Récupère les nombres de cartes dans les mains utilisées | |
| if nbCartesPioche == 0: # Passe au suivant si la pioche est vide | |
| continue | |
| print(f"\033[{j}m{joueur} ({nbCartesJoueur}) pioche chez {pioche} ({nbCartesPioche})") | |
| carte = self.mains[pioche].pop(random.randrange(len(self.mains[pioche]))) # Sinon, pioche une carte | |
| print(f"{joueur} a pioché {carte}\033[0m", end=" ") | |
| self.mains[joueur].append(carte) # L'ajoute à la main du joueur qui a pioché | |
| self.supprimePaires(self.mains[joueur]) # Nettoie la main du joueur de ses paires par couleur | |
| if not j == 33: # Sauf si le code couleur est 33 | |
| j += 1 # Incrémente le code couleur | |
| else: | |
| j += 2 # Sinon saute le code 34 (trop sombre) | |
| if len(self.mains[pioche]) == 0: # Si la pioche est vide à la fin du tour du joueur | |
| del self.mains[pioche] # Supprime le joueur de la pioche qui a gagné ! | |
| print(f"\n\033[1m{pioche} a terminé le jeu :-)\033[0m") | |
| if len(self.mains) == 1: # S'il ne reste plus qu'une main, il s'agit du perdant | |
| print(f"\033[1m{joueur} a perdu !!!\033[0m") | |
| break | |
| self.gereInteraction() # Gère l'interaction avec l'utilisateur | |
| # Méthode qui permet de supprimer les paires par couleur | |
| def supprimePaires(self, main): | |
| for carte in main: # Pour chaque carte de la main | |
| for paire in self.paires: # Cherche les paires | |
| if carte.couleur in ["coeur", "pique"] and carte in paire: # sur base des couleurs "principales" | |
| carte2 = paire[1] # Récupère la 2e carte de la paire | |
| if carte2 in main: # Si les deux cartes de la paire sont dans la main | |
| del main[main.index(carte)] # supprime les deux cartes | |
| del main[main.index(carte2)] | |
| ############################## | |
| ### LE SCRIPT | |
| if __name__ == "__main__": | |
| jeu, nbJoueurs, interactif = "bataille", 2, True | |
| i = 0 | |
| while sys.argv: | |
| i += 1 | |
| if i == 1: | |
| sys.argv.pop(0) | |
| continue | |
| elif i == 2: | |
| jeu = sys.argv.pop(0).lower() | |
| elif i == 3: | |
| nbJoueurs = int(sys.argv.pop(0)) | |
| elif i == 4: | |
| arg = sys.argv.pop(0) | |
| if arg == "0" or arg == "" or arg == "False": | |
| interactif = False | |
| if jeu == "bataille": | |
| jeu = Bataille(nbJoueurs, interactif) | |
| jeu.joue() | |
| elif jeu in ["pouilleux", "valetpuant", "zwartepiet"]: | |
| jeu = Pouilleux(nbJoueurs, interactif) | |
| jeu.joue() | |
| ############################## |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hé ! Je viens de jeter un œil à ton 009_JeuxDeCartes.py et j'ai des trucs sympas à dire ! Mais mec, si tu as envie de quelque chose de plus frais qu'un simple jeu de cartes, tu dois aller sur ce lien. C'est un tout nouveau niveau, mec, pas une machine à sous banale. Chaque tour pourrait être votre grand moment gagnant. De plus, tu peux y participer depuis n'importe où, depuis ton mobile ou ton ordinateur. Ne te contente pas des anciens jeux, pimente-les !