Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ###########
- # CLASSES #
- ###########
- #Classes allow you to define your own arbitrarily complex data types. This allows
- #you to both model the problem you're trying to solve and manage the program's
- #complexity better. For example, suppose we wanted to create a Pokémon battle
- #simulator, like ShoddyBattle. Each Pokémon has a myriad of attributes: 6 base
- #stats, 6 IVs, 6 EVs, an EXP total, its level, Original Trainer, Trainer ID,
- #Secret ID, Nature, Gender, 4 learned moves, species name, nickname, Pokédex
- #number, location of capture, region of capture, and level of capture. That's an
- #overwhelming number of stats to keep track of, and you'll have a copy of those
- #variables for each Pokémon in your team (and the opponent's team!)
- #Now suppose you wanted to write a function that operates on two Pokémon - for
- #example, a function to calculate the damage an attack will do. It'd be extremely
- #cumbersome and error-prone to write a function that accepts over 50 parameters.
- #You're not really trying to pass 50+ variables - you're trying to pass only two
- #Pokémon. We want to *encapsulate* all those attributes into a new variable type:
- #a Pokemon.
- #Classes also allow us to initialize (give proper initial values to) the attri-
- #butes of each new Pokémon properly. This is extremely important-for example, it
- #makes no sense to create a Level 100 Pokémon that has 0 EXP, because a Pokémon's
- #level is a function of its EXP. Likewise, it makes no sense for a new Pokémon's
- #stats to be initialized 0, because their stats depend on their base stats, IVs,
- #EVs, and level. In fact, that would be an extremely dangerous thing to do - the
- #game's damage formula involves a division between Attack and Defense. If stats
- #were initialized to 0, and we forgot to properly set the defending Pokémon's
- #Defense, you would have a division by 0 on your hands and the program would
- #crash.
- #Without further ado, let's create a basic Pokémon class.
- class Pokemon:
- """A simple Pokémon class; it only stores its level and final stats.
- The Pokemon is created at level 100 by default."""
- #The above is a documentation string. It's good practice to document what
- #your classes and functions do.
- #Here we set the default values of the class's *attributes*. Attributes are
- #the variables that each instance of our Pokemon class holds.
- level = 100
- #__init__ is the class's constructor. A constructor is a special function
- #that's called when a new instance (a new Pokemon object) of the class is
- #created. Its job is to properly intialize the class's attributes.
- def __init__(self, hp, attack, defense, sp_attack, sp_defense, speed):
- #It's incredibly important to realize there are two variables called "hp"
- #inside this function. The one that's a parameter of the constructor is
- #a local variable, just like the ones you've encountered in the past.
- #It'll be destroyed when the function finishes. self.hp on the other hand
- #refers to the Pokemon Class's hp attribute, and will live on when the
- #constructor exits.
- self.hp = hp
- self.attack = attack
- self.defense = defense
- self.sp_attack = sp_attack
- self.sp_defense = sp_defense
- self.speed = speed
- #If we want to set an attribute, we must always refer
- #to it as self.<attribute name>. Otherwise, we'd be creating a local
- #variable inside the constructor. For example:
- # name = "VENUSAUR"
- #would create a local variable called name inside this function.
- # self.name = "VENUSAUR"
- #would create an attribute called name inside the class instead.
- #However, outside of functions, self isn't necessary - look at the level
- #attribute before the constructor.
- #This function will print out all of the Pokémon's attributes (its variables)
- #for us. Like I said earlier, methods will have at least one parameter - the
- #Pokemon object they're acting upon.
- def print_stats(self):
- print("STATS:")
- print("Level: ", self.level)
- print("HP: ", self.hp)
- print("Attack: ", self.attack)
- print("Defense: ", self.defense)
- print("Special Attack: ", self.sp_attack)
- print("Special Defense: ", self.sp_defense)
- print("Speed: ", self.speed)
- #And that's it. Now we've defined a Pokemon class that contains two methods
- #and seven members. One of those two methods is a constructor. We can now
- #easily create a new Pokemon by calling the constructor like this:
- venusaur = Pokemon(404, 317, 266, 298, 261, 350)
- #Note that we only passed 6 parameters - the Pokémon's stats - not 7. The hidden
- #first parameter "self" is passed automatically to the constructor and refers
- #to the venusaur variable we just created. As proof, we can directly verify
- #venusaur's attributes:
- print("Venusaur's level: ", venusaur.level) #prints 100
- print("Venusaur's HP: ", venusaur.hp) #prints 404
- #In a similar fashion, we can call the print_stats method:
- venusaur.print_stats()
- #Again, note that the self parameter is actually venusaur, so we don't pass it
- #ourselves when we call the function.
- #we can just as easily create a new Pokemon by calling the constructor again:
- charizard = Pokemon(300, 410, 197, 383, 266, 360)
- #We can now write a function to have one Pokemon attack the other, without
- #explicitly passing each Pokemon's stats!
- def attack(attacker, defender, move_bp, type_effectiveness):
- """Doesn't take crits, randomness, burn, etc into account"""
- #Don't worry about the details of the formula.
- damage = ( ((attacker.level * 2/5 + 2) * move_bp * (attacker.attack/50)
- / defender.defense + 2) * type_effectiveness )
- #It's good practice to keep your lines under 80 characters. If you need to
- #do really long calculations, wrap the whole thing in parentheses so you
- #can break it up into multiple lines.
- defender.hp -= damage #subtract the damage from the defender's hp.
- return damage #return the damage done
- #And now we have charizard use Flamethrower on venusaur:
- print("Damage done: ", attack(charizard, venusaur, 100, 2))
- #Let's verify Venusaur's HP to be sure:
- print("Venusaur's HP after attack: ", venusaur.hp)
Advertisement
Add Comment
Please, Sign In to add comment