<jupyter_start><jupyter_text>Ejemplo de clases: Juego Pokémon En este ejemplo, crearemos nuestra clase básica Pokémon, que tendrá sus atributos y funciones, comunes a todos los pokémons.<jupyter_code># Necesitaremos un diccionario con las razas de pokemons y sus tipos, así como sus stats base:
POKES = {'bulbasaur': {'ps': 100, 'at': 100, 'de': 100, 've': 150, 'tipo': 'pla'}, 
        'charmander': {'ps': 120, 'at': 150, 'de': 100, 've': 110, 'tipo': 'fue'}, 
        'squirtle': {'ps': 80, 'at': 80, 'de': 200, 've': 80, 'tipo': 'agu'}}

# También nos crearemos un diccionario con la efectividad de los tips:
EFECTIVIDAD = {'pla': {'agu': 2, 'fue': 0.5},
              'fue': {'pla': 2, 'agu': 0.5},
              'agu': {'fue': 2, 'pla': 0.5}}

import random



class Pokemon:

    # Constructor de la clase
    def __init__(self, nombre, raza, nivel):
        # Atributos:
        self.nombre = nombre
        self.raza = raza
        self.raza_pokemon = POKES[raza]
        self.nivel = int(nivel)
        # Para darle importancia al nivel, multiplicamos los stats por un valor
        self.ps = int(self.raza_pokemon['ps'] * nivel/10)
        self.ataque = int(self.raza_pokemon['at'] * nivel/10)
        self.defensa = int(self.raza_pokemon['de'] * nivel/10)
        self.velocidad = int(self.raza_pokemon['ve'] * nivel/10)
        self.tipo = self.raza_pokemon['tipo']
    
    def ataca(self, pokemon_rival):
        efectividad = EFECTIVIDAD[self.tipo].get(pokemon_rival.tipo, 1)
        ataque = int(self.ataque * random.random() * 10 / pokemon_rival.defensa * efectividad)
        pokemon_rival.ps = max(pokemon_rival.ps - ataque, 0)
        print(f"El ataque de {self.nombre} es de {ataque} puntos.")
        if pokemon_rival.ps <= 0:
            pokemon_rival.muere()
            # Esta función indicará al bucle de ejecución principal si se termina la batalla
            return True
        else:
            print(f"{pokemon_rival.nombre.title()} se ha quedado a {pokemon_rival.ps} puntos de vida")
            return False
    
    def cura(self):
        ps_recuperado = int(20 * random(0, 5))
        self.ps = self.ps + ps_recuperado
        print(f"{self.nombre.title()} ha recuperado {ps_recuperado} puntos de vida")
            
    def muere(self):
        print(f"Oh, no. Parece que {self.nombre} ha perdido todos sus puntos de vida.")
        
    # Además, vamos a darle una interfaz chula para conocer los stats de nuestro poke:
    def get_stats(self):
        print(f"{self.nombre} ({self.raza})")
        print(f"\tPS:\t{self.ps}")
        print(f"\tAT:\t{self.ataque}")
        print(f"\tDE:\t{self.defensa}")
        print(f"\tVE:\t{self.velocidad}")
        print(f"\tTipo:\t{self.tipo}")
        print()
    
    def revivir(self):
        self.ps = self.raza_pokemon['ps'] * self.nivel/10
        print(f"{self.nombre.title()} ha tomado un revivir y está en plenas condiciones con sus {self.ps} puntos de vida. LLévalo a un centro Pokémon.")<jupyter_output><empty_output><jupyter_text>Una vez definida la estructura del pokemon, pasamos al bucle de ejecución principal:<jupyter_code># Instanciamos 2 pokemons:
bulbasaur = Pokemon(nombre='Plantita', raza = 'bulbasaur', nivel = 20)
charmander = Pokemon(nombre='Bombero', raza = 'charmander', nivel = 20)
# Ahora podemos acceder a los stats de cada pokemon:
bulbasaur.get_stats()
charmander.get_stats()
# Simulamos un ataque de charmander:
charmander.ataca(bulbasaur)
# Y si hubiera sido al revés?
bulbasaur.ataca(charmander)<jupyter_output>El ataque de Plantita es de 2 puntos.
Bombero se ha quedado a 238 puntos de vida<jupyter_text>Vamos a revivir a bulbasaur para que sea un poco menos injusto:<jupyter_code>bulbasaur.revivir()
bulbasaur.get_stats()
# Ahora podemos hacer una lucha:

final = False

pokemons = [bulbasaur, charmander]
while not final:
    if pokemons[0].velocidad >= pokemons[1].velocidad:
        # Aunque lo pongamos en un if, como estamos ejecutando el método, la interacción se produce y pierde puntos de vida:
        # Empieza atacando el más rápido (en caso de empate, vamos con el priemro que hayamos puesto en la lista, no somos legales jajaja)
        if pokemons[0].ataca(pokemons[1]):
            ganador = pokemons[0]
            break
        # Luego ataca el otro:
        if pokemons[1].ataca(pokemons[0]):
            ganador = pokemons[1]
            break
    else:
        if pokemons[1].ataca(pokemons[0]):
            ganador = pokemons[0]
            break
        # Luego ataca el otro:
        if pokemons[0].ataca(pokemons[1]):
            ganador = pokemons[1]
            break<jupyter_output>El ataque de Plantita es de 4 puntos.
Bombero se ha quedado a 234 puntos de vida
El ataque de Bombero es de 26 puntos.
Plantita se ha quedado a 174.0 puntos de vida
El ataque de Plantita es de 0 puntos.
Bombero se ha quedado a 234 puntos de vida
El ataque de Bombero es de 13 puntos.
Plantita se ha quedado a 161.0 puntos de vida
El ataque de Plantita es de 1 puntos.
Bombero se ha quedado a 233 puntos de vida
El ataque de Bombero es de 19 puntos.
Plantita se ha quedado a 142.0 puntos de vida
El ataque de Plantita es de 3 puntos.
Bombero se ha quedado a 230 puntos de vida
El ataque de Bombero es de 3 puntos.
Plantita se ha quedado a 139.0 puntos de vida
El ataque de Plantita es de 4 puntos.
Bombero se ha quedado a 226 puntos de vida
El ataque de Bombero es de 21 puntos.
Plantita se ha quedado a 118.0 puntos de vida
El ataque de Plantita es de 3 puntos.
Bombero se ha quedado a 223 puntos de vida
El ataque de Bombero es de 16 puntos.
Plantita se ha quedado a 102.0 puntos de vida
El ataque d[...]<jupyter_text>Probemos ahora contra squirtle<jupyter_code># Instanciamos 2 pokemons:
squirtle = Pokemon(nombre='Tortuguín', raza = 'squirtle', nivel = 15)
charmander = Pokemon(nombre='Bombero', raza = 'charmander', nivel = 20)
# Ahora podemos acceder a los stats de cada pokemon:
squirtle.get_stats()
charmander.get_stats()
# Ahora podemos hacer una lucha:
final = False



pokemons = [squirtle, charmander]
while not final:
    if pokemons[0].velocidad >= pokemons[1].velocidad:
        # Aunque lo pongamos en un if, como estamos ejecutando el método, la interacción se produce y pierde puntos de vida:
        # Empieza atacando el más rápido (en caso de empate, vamos con el priemro que hayamos puesto en la lista, no somos legales jajaja)
        if pokemons[0].ataca(pokemons[1]):
            ganador = pokemons[0]
            break
        # Luego ataca el otro:
        if pokemons[1].ataca(pokemons[0]):
            ganador = pokemons[1]
            break
    else:
        if pokemons[1].ataca(pokemons[0]):
            ganador = pokemons[0]
            break
        # Luego ataca el otro:
        if pokemons[0].ataca(pokemons[1]):
            ganador = pokemons[1]
            break<jupyter_output>El ataque de Bombero es de 3 puntos.
Tortuguín se ha quedado a 117 puntos de vida
El ataque de Tortuguín es de 6 puntos.
Bombero se ha quedado a 234 puntos de vida
El ataque de Bombero es de 3 puntos.
Tortuguín se ha quedado a 114 puntos de vida
El ataque de Tortuguín es de 10 puntos.
Bombero se ha quedado a 224 puntos de vida
El ataque de Bombero es de 1 puntos.
Tortuguín se ha quedado a 113 puntos de vida
El ataque de Tortuguín es de 11 puntos.
Bombero se ha quedado a 213 puntos de vida
El ataque de Bombero es de 3 puntos.
Tortuguín se ha quedado a 110 puntos de vida
El ataque de Tortuguín es de 8 puntos.
Bombero se ha quedado a 205 puntos de vida
El ataque de Bombero es de 0 puntos.
Tortuguín se ha quedado a 110 puntos de vida
El ataque de Tortuguín es de 0 puntos.
Bombero se ha quedado a 205 puntos de vida
El ataque de Bombero es de 2 puntos.
Tortuguín se ha quedado a 108 puntos de vida
El ataque de Tortuguín es de 2 puntos.
Bombero se ha quedado a 203 puntos de vida
El ataque de B[...]
{'fraction_non_alphanumeric': 0.09160402599057205, 'fraction_numerical': 0.027009810166900242, 'mean_word_length': 3.031843862352337, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '477295', 'license': 'MIT', 'n_tokens_mistral': 3052, 'n_tokens_neox': 2852, 'n_words': 980, 'path': 'Bloque 1 - Ramp-Up/05_Python/04_Clases y objetos/03_Ejemplo_clases.ipynb', 'repo_name': 'JuanDG5/bootcamp_thebridge_PTSep20', 'size': '7849'}