Jupyter-ITVitae/pokémon.ipynb

156 KiB

None <html lang="en"> <head> gitea_input694149577 </head>
In [2]:
import polars as ps

pokémon = ps.read_csv("./pokémon/Pokemon.csv")
pokémon
Out[2]:
shape: (800, 13)
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendary
i64strstrstri64i64i64i64i64i64i64i64bool
1"Bulbasaur""Grass""Poison"3184549496565451false
2"Ivysaur""Grass""Poison"4056062638080601false
3"Venusaur""Grass""Poison"525808283100100801false
3"VenusaurMega V…"Grass""Poison"62580100123122120801false
4"Charmander""Fire"null3093952436050651false
5"Charmeleon""Fire"null4055864588065801false
6"Charizard""Fire""Flying"534788478109851001false
6"CharizardMega …"Fire""Dragon"63478130111130851001false
6"CharizardMega …"Fire""Flying"63478104781591151001false
7"Squirtle""Water"null3144448655064431false
8"Wartortle""Water"null4055963806580581false
9"Blastoise""Water"null530798310085105781false
712"Bergmite""Ice"null3045569853235286false
713"Avalugg""Ice"null514951171844446286false
714"Noibat""Flying""Dragon"2454030354540556false
715"Noivern""Flying""Dragon"53585708097801236false
716"Xerneas""Fairy"null6801261319513198996true
717"Yveltal""Dark""Flying"6801261319513198996true
718"Zygarde50% For…"Dragon""Ground"6001081001218195956true
719"Diancie""Rock""Fairy"60050100150100150506true
719"DiancieMega Di…"Rock""Fairy"700501601101601101106true
720"HoopaHoopa Con…"Psychic""Ghost"6008011060150130706true
720"HoopaHoopa Unb…"Psychic""Dark"6808016060170130806true
721"Volcanion""Fire""Water"6008011012013090706true
In [3]:
pokémon.sort(ps.col("HP")).tail(1)
Out[3]:
shape: (1, 13)
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendary
i64strstrstri64i64i64i64i64i64i64i64bool
242"Blissey""Normal"null540255101075135552false
In [4]:
from polars import col

pokémon.select(ps.col("Type 2").fill_null(ps.col("Type 1")))
pnn = pokémon.with_columns([
    ps.when(col("Type 2").is_null()).then(col("Type 1")).otherwise(col("Type 2")).alias("Type 2")
])

pnn
Out[4]:
shape: (800, 13)
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendary
i64strstrstri64i64i64i64i64i64i64i64bool
1"Bulbasaur""Grass""Poison"3184549496565451false
2"Ivysaur""Grass""Poison"4056062638080601false
3"Venusaur""Grass""Poison"525808283100100801false
3"VenusaurMega V…"Grass""Poison"62580100123122120801false
4"Charmander""Fire""Fire"3093952436050651false
5"Charmeleon""Fire""Fire"4055864588065801false
6"Charizard""Fire""Flying"534788478109851001false
6"CharizardMega …"Fire""Dragon"63478130111130851001false
6"CharizardMega …"Fire""Flying"63478104781591151001false
7"Squirtle""Water""Water"3144448655064431false
8"Wartortle""Water""Water"4055963806580581false
9"Blastoise""Water""Water"530798310085105781false
712"Bergmite""Ice""Ice"3045569853235286false
713"Avalugg""Ice""Ice"514951171844446286false
714"Noibat""Flying""Dragon"2454030354540556false
715"Noivern""Flying""Dragon"53585708097801236false
716"Xerneas""Fairy""Fairy"6801261319513198996true
717"Yveltal""Dark""Flying"6801261319513198996true
718"Zygarde50% For…"Dragon""Ground"6001081001218195956true
719"Diancie""Rock""Fairy"60050100150100150506true
719"DiancieMega Di…"Rock""Fairy"700501601101601101106true
720"HoopaHoopa Con…"Psychic""Ghost"6008011060150130706true
720"HoopaHoopa Unb…"Psychic""Dark"6808016060170130806true
721"Volcanion""Fire""Water"6008011012013090706true
In [5]:
gen1 = pnn.filter(col("Generation") == 1)
gen1
Out[5]:
shape: (166, 13)
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendary
i64strstrstri64i64i64i64i64i64i64i64bool
1"Bulbasaur""Grass""Poison"3184549496565451false
2"Ivysaur""Grass""Poison"4056062638080601false
3"Venusaur""Grass""Poison"525808283100100801false
3"VenusaurMega V…"Grass""Poison"62580100123122120801false
4"Charmander""Fire""Fire"3093952436050651false
5"Charmeleon""Fire""Fire"4055864588065801false
6"Charizard""Fire""Flying"534788478109851001false
6"CharizardMega …"Fire""Dragon"63478130111130851001false
6"CharizardMega …"Fire""Flying"63478104781591151001false
7"Squirtle""Water""Water"3144448655064431false
8"Wartortle""Water""Water"4055963806580581false
9"Blastoise""Water""Water"530798310085105781false
142"AerodactylMega…"Rock""Flying"615801358570951501false
143"Snorlax""Normal""Normal"5401601106565110301false
144"Articuno""Ice""Flying"580908510095125851true
145"Zapdos""Electric""Flying"580909085125901001true
146"Moltres""Fire""Flying"580901009012585901true
147"Dratini""Dragon""Dragon"3004164455050501false
148"Dragonair""Dragon""Dragon"4206184657070701false
149"Dragonite""Dragon""Flying"6009113495100100801false
150"Mewtwo""Psychic""Psychic"68010611090154901301true
150"MewtwoMega Mew…"Psychic""Fighting"7801061901001541001301true
150"MewtwoMega Mew…"Psychic""Psychic"780106150701941201401true
151"Mew""Psychic""Psychic"6001001001001001001001false
In [6]:
no_megas = pnn.filter(~col("Name").str.contains("Mega "))
no_megas
Out[6]:
shape: (752, 13)
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedGenerationLegendary
i64strstrstri64i64i64i64i64i64i64i64bool
1"Bulbasaur""Grass""Poison"3184549496565451false
2"Ivysaur""Grass""Poison"4056062638080601false
3"Venusaur""Grass""Poison"525808283100100801false
4"Charmander""Fire""Fire"3093952436050651false
5"Charmeleon""Fire""Fire"4055864588065801false
6"Charizard""Fire""Flying"534788478109851001false
7"Squirtle""Water""Water"3144448655064431false
8"Wartortle""Water""Water"4055963806580581false
9"Blastoise""Water""Water"530798310085105781false
10"Caterpie""Bug""Bug"1954530352020451false
11"Metapod""Bug""Bug"2055020552525301false
12"Butterfree""Bug""Flying"3956045509080701false
711"GourgeistSuper…"Ghost""Grass"494851001225875546false
712"Bergmite""Ice""Ice"3045569853235286false
713"Avalugg""Ice""Ice"514951171844446286false
714"Noibat""Flying""Dragon"2454030354540556false
715"Noivern""Flying""Dragon"53585708097801236false
716"Xerneas""Fairy""Fairy"6801261319513198996true
717"Yveltal""Dark""Flying"6801261319513198996true
718"Zygarde50% For…"Dragon""Ground"6001081001218195956true
719"Diancie""Rock""Fairy"60050100150100150506true
720"HoopaHoopa Con…"Psychic""Ghost"6008011060150130706true
720"HoopaHoopa Unb…"Psychic""Dark"6808016060170130806true
721"Volcanion""Fire""Water"6008011012013090706true
In [7]:
from plotnine import ggplot, aes, geom_histogram, labs

(
    ggplot(no_megas.to_pandas())
    + aes(x="Attack") 
    + geom_histogram(bins=(200/25))
    + labs(title="Distribution of attack stat for all Pokémon", y="Amount of Pokémon")
)
No description has been provided for this image
In [8]:
only_fairy = pnn.filter(col("Type 1").str.contains("Fairy") | col("Type 2").str.contains("Fairy"))

(
    ggplot(only_fairy.to_pandas())
    + aes(x="Generation") 
    + geom_histogram(bins=(6), color='#EF9FEF', fill='#EF6FEF')
    + labs(title="Amount of fairy Pokémon in each generation", y="Amount of Pokémon")
)
No description has been provided for this image
In [22]:
types = pokémon.select(["Type 1"]).unique().to_series().to_list()
In [25]:
pokétype = ps.read_csv("./pokémon/Pokemon Type Chart.csv")
pokétype
Out[25]:
shape: (18, 19)
NormalFireWaterElectricGrassIceFightingPoisonGroundFlyingPsychicBugRockGhostDragonDarkSteelFairy
strf64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64
"Normal"1.01.01.01.01.01.01.01.01.01.01.01.00.50.01.01.00.51.0
"Fire"1.00.50.51.02.02.01.01.01.01.01.02.00.51.00.51.02.01.0
"Water"1.02.00.51.00.51.01.01.02.01.01.01.02.01.00.51.01.01.0
"Electric"1.01.02.00.50.51.01.01.00.02.01.01.01.01.00.51.01.01.0
"Grass"1.00.52.01.00.51.01.00.52.00.51.00.52.01.00.51.00.51.0
"Ice"1.00.50.51.02.00.51.01.02.02.01.01.01.01.02.01.00.51.0
"Fighting"2.01.01.01.01.02.01.00.51.00.50.50.52.00.01.02.02.00.5
"Poison"1.01.01.01.02.01.01.00.50.51.01.01.00.50.51.01.00.02.0
"Ground"1.02.01.02.00.51.01.02.01.00.01.00.52.01.01.01.02.01.0
"Flying"1.01.01.00.52.01.02.01.01.01.01.02.00.51.01.01.00.51.0
"Psychic"1.01.01.01.01.01.02.02.01.01.00.51.01.01.01.00.00.51.0
"Bug"1.00.51.01.02.01.00.50.51.00.52.01.01.00.51.02.00.50.5
"Rock"1.02.01.01.01.02.00.51.00.52.01.02.01.01.01.01.00.51.0
"Ghost"0.01.01.01.01.01.01.01.01.01.02.01.01.02.01.00.51.01.0
"Dragon"1.01.01.01.01.01.01.01.01.01.01.01.01.01.02.01.00.50.0
"Dark"1.01.01.01.01.01.00.51.01.01.02.01.01.02.01.00.51.00.5
"Steel"1.00.50.50.51.02.01.01.01.01.01.01.02.01.01.01.00.52.0
"Fairy"1.00.51.01.01.01.02.00.51.01.01.01.01.01.02.02.00.51.0
In [255]:
from dataclasses import dataclass
from enum import Enum
from typing import TypeVar
import random

TPokémon = TypeVar("TPokémon", bound="Pokémon")

pokémon_list: list = []

class Effective(Enum):
    """
    Enum Description: 
    """
    SUPER = "It's super effective!"
    NORMAL = ""
    NOTVERY = "It's not very effective..."
    NOT = "But it has no effect!"


@dataclass
class Pokémon:
    name: str
    types: list
    hp: int
    curr_hp: int
    attack: int
    defense: int
    sp_atk: int
    sp_def: int

    def attack_opponent(self, opponent: TPokémon, typeatk: str, atkpwr: int):
        if opponent.curr_hp == 0:
            print("You cannot attack a fainted Pokémon!")
            return

        type_modifier = pokétype.filter(pokétype[""].str.contains(typeatk))[opponent.types[0]][0]
        if (opponent.types[1] is not None):
            type_modifier *= pokétype.filter(pokétype[""].str.contains(typeatk))[opponent.types[1]][0]
        
        damage = self.attack * type_modifier * (atkpwr / 100)
        

        if(typeatk in self.types):
            damage = damage * 1.5
        opponent.curr_hp = opponent.curr_hp - damage
        print(f"""{self.name} attacks {opponent.name} for {int(damage)} damage!\n
{Effective.SUPER.value if type_modifier > 1.0 else Effective.NORMAL.value}
{Effective.NOTVERY.value if ((type_modifier < 1.0) and (type_modifier > 0.0))  else Effective.NORMAL.value}
{Effective.NOT.value if type_modifier == 0.0 else Effective.NORMAL.value}""")

        if (opponent.curr_hp <= 0):
            opponent.curr_hp = 0
            print(f"{opponent.name} fainted!")
            return
        print(f"It now has {int(opponent.curr_hp)} HP")

    def heal(self):
        self.curr_hp = self.hp

for row in pokémon.rows(named=True):
    pokémon_list.append(Pokémon(
        name = row["Name"],
        types = [row["Type 1"], row["Type 2"]],
        hp = row["HP"],
        curr_hp = row["HP"],
        attack = row["Attack"],
        defense = row["Defense"],
        sp_atk = row["Sp. Atk"],
        sp_def = row["Sp. Def"],
    ))
In [256]:
pokémon_list[0].attack_opponent(pokémon_list[15], "Grass", 40)
Bulbasaur attacks Butterfree for 16 damage!


It's not very effective...

It now has 167 HP
In [201]:
for poke in pokémon_list:
    poke.heal()
</html>