class gentil: #On introduit une classe avec le mot class
    """ On peut ici présenter la classe, ce texte qui apparait si on fait un help(gentil)"""
    def __init__(self, pdv = 10, force = 5, defense = 2, vivant = True, sac = []): #Fonction d'initialisation : fixe les attributs de la classe lorsqu'on crée un élément
        self.pdv = pdv #Un attribut est une variable de la classe
        self.force = force
        self.defense = defense
        self.vivant = vivant
        self.sac = sac
    def renforce(self):
        """ une méthode est une fonction propre à la classe """
        self.force+=1

class mechant: #On peut définir une 2e classe
    """ Classe des personnages à combattre"""
    def __init__(self, pdv = 5, force = 4, defense = 1, vivant = True, sac = []):
        self.pdv = pdv
        self.force = force
        self.defense = defense
        self.vivant = vivant
        self.sac = sac

def bagare(perso1, perso2): #Et faire des fonctions qui les manipules
    deg1 = max(0, perso2.force - perso1.defense)
    deg2 = max(0, perso1.force - perso2.defense)
    perso1.pdv -= deg1
    perso2.pdv -= deg2

    if perso1.pdv <= 0:
        perso1.vivant = False
        perso2.sac += perso1.sac
    if perso2.pdv <= 0:
        perso2.vivant = False
        perso1.sac += perso2.sac

#Exemple de code :

P1 = gentil() #Crée un élément de la classe gentil, les valeurs sont celles par défaut dans init

P2 = mechant(6,6,6, True, []) #Crée un élément de la classe méchant. l'élément self de la fonction init n'a pas besoin d'être recopié

print(P1.pdv, P2.pdv)

bagare(P1,P2) #On execute la fonction sur les deux éléments

print(P1.pdv, P2.pdv) #On constate que leur vie a bien été mis à jour

for i in range(10):
    P1.renforce() #On appelle une méthode comme ça

bagare(P1,P2)
print(P1.pdv, P2.pdv, P2.vivant)


## Exemple de classe et de ce qu'on peut en faire

class texte:
    """ classe texte, cette classe est plus ou moins la classe string mais en la rendant modifiable """
    def __init__(self, chaine = ""): #Fonction d'initialisation, sert à créer les objets
        self.chaine = chaine
        self.taille = len(chaine)

    def __add__(self, other): #Pour ajouter 2 éléments
    """ On peut présenter chaque méthode de la classe"""
        res = texte()
        res.chaine = self.chaine + other.chaine
        res.taille = self.taille + other.taille
        return res

    def __getitem__(self,ind): #Pour accéder à un élément
        try:
            return self.chaine[ind]
        except IndexError:
            print("La chaine ne contient pas autant d'éléments")
        except TypeError:
            print("On ne peux accéder qu'à des entiers'")

    def __setitem__(self,ind,carac): #Permets l'affectation en faisant txt[ind] = carac
        try :
            if len(carac) >1:
                raise Error
            self.chaine = self.chaine[:ind] + carac + self.chaine[ind+1:]

        except:
            print("Une erreur est survenue")

    def __repr__(self): #remplacera print
        return self.chaine

    def __str__(self): #Conversion en string
        return self.chaine

    def __neg__(self): #Définit -texte
        res = texte()
        res.chaine = self.chaine[::-1]
        res.taille = self.taille
        return res

    def __len__(self): #Pour définir la taille
        return self.taille
    # Les 2 fonctions suivantes servent à faire des boucles for sur notre classe
    def __iter__(self): #Cette fonction sert à initialiser
        self.n = 0
        return self

    def __next__(self): #Celle là à définir ce qui ce passe après chaque itération
        if self.n < self.taille:
            self.n +=1
            return self.chaine[self.n-1]
        else:
            raise StopIteration

















