Problème programmation jeu python "La bataille"

kenav01 - 3 déc. 2023 à 20:07
mamiemando Messages postés 33380 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 26 novembre 2024 - 4 déc. 2023 à 15:11

Bonsoir, je dois créer pour le lycée le jeu de la bataille en python. Je bloque au moment de comparer les cartes. Je ne comprends comment utiliser les méthodes "equality" ou "lower than". Voici mon programme, si ce serait possible de m'aider, merci d'avance !

import random
VALEURS = ['','', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'R', 'A']
COULEURS = ['', 'S', 'H', 'D', 'C']

class Carte:
    """Initialise couleur (de 1 à 4), et valeur (de 2 à 14)"""

    def __init__(self, couleur, valeur):
        self.couleur = couleur
        self.valeur = valeur

    def get_nom(self):
        """Renvoie le nom de la Carte As, 2, ... 10, Valet, Dame, Roi"""
        return VALEURS[self.valeur]

    def get_couleur(self):
        """Renvoie la couleur de la Carte (parmi pique, coeur, carreau, trefle)"""
        return COULEURS[self.couleur]

    def __str__(self):
        return self.get_couleur() +self.get_nom()

    def __eq__(self,c2): #c1 == c2 est comme faire c1.__eq__(c2)
        return self.get_nom() == c2

    def __lt__(self,c2):

        return self.get_nom() < c2

    def __gt__(self,c2):

        return self.get_nom() > c2


class PaquetDeCarte:
    """Initialise un paquet de cartes, avec un attribut contenu, de type list, vide"""

    def __init__(self):
        self.contenu = []
        self.contenu_j1 = []
        self.contenu_j2 = []

    def remplir(self):
        """Remplit le paquet de cartes : en parcourant les couleurs puis les valeurs"""
        self.contenu = [Carte(couleur, valeur) for couleur in range(1, 5) for valeur in range(2, 15)]

    def get_carte_at(self, pos):
        """Renvoie la Carte qui se trouve à la position donnée"""
        if 0 <= pos < 52:
            return self.contenu[pos]

    def melanger(self):
        random.shuffle(self.contenu)

    def distribuer(self):

        while len(self.contenu) != 0:
            x = Pile(self.contenu).depiler()
            Pile(self.contenu_j1).empiler(x)
            y =Pile(self.contenu).depiler()
            Pile(self.contenu_j2).empiler(y)

    def __str__(self):
        s= ""
        j1 = ""
        j2 = ""
        for i in self.contenu_j1:
            j1+= str(i) + " "
        for j in self.contenu_j2:
            j2+= str(j) + " "
        for i in self.contenu:
            s+= str(i) + " "
        return "paquet complet: "+ s + "/ paquet du joueur 1 : "+ j1 + "; paquet du joueur 2 :"+ j2



class Pile:

    def __init__(self,paquet):
        self.paquet = paquet

    def empiler(self,carte):
        self.paquet.append(carte)

    def depiler(self):
        if self.paquet:
            return self.paquet.pop()

class File:

    def __init__(self,paquet):
        self.paquet = paquet


    def enfiler(self,carte):
        self.paquet.insert(carte,0)

    def defiler(self):
        if self.paquet:
            return self.paquet.pop(0)



def game():
    tapis_j1 = []
    tapis_j2 = []
    paquet_carte = PaquetDeCarte()
    paquet_carte.remplir()
    paquet_carte.melanger()
    print("Bienvenue au jeu de la bataille")
    print("Distribution des cartes ...")
    paquet_carte.distribuer()
    print("Carte distribuée")
    print("Début du jeu")
    print("Nombre de cartes du joueur 1 :", str(len(paquet_carte.contenu_j1)), "/ Nombre de cartes du joueur 2 :", str(len(paquet_carte.contenu_j2)))
    while len(paquet_carte.contenu_j1) !=0 or len(paquet_carte.contenu_j2) !=0:
        cartej1 = Pile(paquet_carte.contenu_j1).depiler()
        cartej2 = Pile(paquet_carte.contenu_j1).depiler()
        Pile(tapis_j1).empiler(cartej1)
        Pile(tapis_j2).empiler(cartej2)


Windows / Opera 105.0.0.0

A voir également:

2 réponses

Phil_1857 Messages postés 1872 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 168
Modifié le 4 déc. 2023 à 14:59

Bonjour,

Je ne comprends comment utiliser les méthodes "equality" ...

Donc, ce n'est pas toi qui a écrit le code. Si tu parles de la méthode __eq__ par exemple, il s'agit de la surcharge de l'opérateur == qui permet de comparer 2 objets.

On utilise de genre de méthode lorsque == doit être (re)défini. Par exemple dans ton cas, on veut comparer 2 cartes, donc on ne peut pas écrire directement:

if carte_1 == carte_2

En python, on ne peut le faire que sur certains types (notamment les valeurs numériques, les chaînes de caractères, les listes, etc) mais pas sur des objets Carte

On utilise donc ce type de surcharge d'opérateur défini dans la classe, pour pouvoir écrire ensuite

if carte_1 == carte_2

Idem pour __lt__ (<), __gt__ (>), et même __str__ qui permet de faire un print d'un objet Carte.

Ceci dit, tu n'appelles jamais la fonction game(), donc il ne se passe rien.

1
mamiemando Messages postés 33380 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 26 novembre 2024 7 802
4 déc. 2023 à 15:11

Bonjour,

Pour préciser la réponse déjà très complète de Phil_1857, la méthode __lt__ est invoquée lorsqu'on fait appel à l'opérateur <, ce qui donne l'opportunité de (re)-définir son comportement en la surchargeant. C'est le même principe pour tout opérateur en python (voir la liste complète des opérateurs et leur méthodes correspondantes ici).

Dans l'extrait de code ci-dessous, je mets en évidence l'appel à la méthode ainsi surchargée, et à son appel au travers de l'opérateur :

class Object:
    def __init__(self, x: int = 0):
        self.x = x
    def __lt__(self, obj) -> bool:
        print(f"__lt__({self}, {obj})")
        return self.x < obj.x
    def __str__(self) -> str:
        return f"Object<x={self.x}>"

o1 = Object(1)
o2 = Object(2)
print("o1 < o2 =", o1 < o2)
print("o1 < o2 =", o1.__lt__(o2))

Résultat :

__lt__(Object<x=1>, Object<x=2>)
o1 < o2 = True
__lt__(Object<x=1>, Object<x=2>)
o1 < o2 = True

Note qu'en python, il y a deux manière de convertir un object en python :

  • via __str__ (ce qui correspond à %s dans une chaîne de formatage) ;
  • via __repr__ (ce qui correspond à %r dans une chaîne de formatage).
class Object:
    def __init__(self, x: int = 0):
        self.x = x
    def __str__(self) -> str:
        return f"Object<x={self.x}>"
    def __repr__(self) -> str:
        return f"<x={self.x}>"

o = Object(1)
print(o)

print("Avec __str__:")
print("%s" % o)
print(str(o))
print(o.__str__())

print("Avec __repr__:")
print("%r" % o)
print(repr(o))
print(o.__repr__())

... ce qui donne :

Object<x=1>
Avec __str__:
Object<x=1>
Object<x=1>
Object<x=1>
Avec __repr__:
<x=1>
<x=1>
<x=1>

Bonne chance

0