diff --git a/pokemone_battle.py/main.py b/pokemone_battle.py/main.py index 4cd9ab6e..5e051be9 100644 --- a/pokemone_battle.py/main.py +++ b/pokemone_battle.py/main.py @@ -2,158 +2,198 @@ import numpy as np import sys -# Delay printing +# Delay printing def delay_print(s): - # print one character at a time - # https://stackoverflow.com/questions/9246076/how-to-print-one-character-at-a-time-on-one-line for c in s: sys.stdout.write(c) sys.stdout.flush() time.sleep(0.05) -# Create the class + +# Type advantage matrix +TYPE_ADVANTAGE = { + "Fire": {"weak": ["Water"], "strong": ["Grass"]}, + "Water": {"weak": ["Grass"], "strong": ["Fire"]}, + "Grass": {"weak": ["Fire"], "strong": ["Water"]}, +} + + class Pokemon: - def __init__(self, name, types, moves, EVs, health='==================='): - # save variables as attributes + def __init__(self, name, ptype, moves, EVs, level=1, health="==================="): self.name = name - self.types = types + self.ptype = ptype self.moves = moves - self.attack = EVs['ATTACK'] - self.defense = EVs['DEFENSE'] + self.attack = EVs["ATTACK"] + self.defense = EVs["DEFENSE"] + self.level = level self.health = health - self.bars = 20 # Amount of health bars - - - def fight(self, Pokemon2): - # Allow two pokemon to fight each other - + self.bars = 20 # Amount of health bars + self.experience = 0 + + def type_advantage(self, opponent_type): + if opponent_type in TYPE_ADVANTAGE[self.ptype]["strong"]: + return 2, "\nIt's super effective!" + elif opponent_type in TYPE_ADVANTAGE[self.ptype]["weak"]: + return 0.5, "\nIt's not very effective..." + else: + return 1, "\nIt's not very effective..." + + def fight(self, opponent): # Print fight information - print("-----POKEMONE BATTLE-----") - print(f"\n{self.name}") - print("TYPE/", self.types) + print("-----POKEMON BATTLE-----") + print(f"\n{self.name} (LVL {self.level})") + print("TYPE/", self.ptype) print("ATTACK/", self.attack) print("DEFENSE/", self.defense) - print("LVL/", 3*(1+np.mean([self.attack,self.defense]))) + print("LVL/", 3 * (1 + np.mean([self.attack, self.defense]))) print("\nVS") - print(f"\n{Pokemon2.name}") - print("TYPE/", Pokemon2.types) - print("ATTACK/", Pokemon2.attack) - print("DEFENSE/", Pokemon2.defense) - print("LVL/", 3*(1+np.mean([Pokemon2.attack,Pokemon2.defense]))) + print(f"\n{opponent.name} (LVL {opponent.level})") + print("TYPE/", opponent.ptype) + print("ATTACK/", opponent.attack) + print("DEFENSE/", opponent.defense) + print("LVL/", 3 * (1 + np.mean([opponent.attack, opponent.defense]))) time.sleep(2) - # Consider type advantages - version = ['Fire', 'Water', 'Grass'] - for i,k in enumerate(version): - if self.types == k: - # Both are same type - if Pokemon2.types == k: - string_1_attack = '\nIts not very effective...' - string_2_attack = '\nIts not very effective...' - - # Pokemon2 is STRONG - if Pokemon2.types == version[(i+1)%3]: - Pokemon2.attack *= 2 - Pokemon2.defense *= 2 - self.attack /= 2 - self.defense /= 2 - string_1_attack = '\nIts not very effective...' - string_2_attack = '\nIts super effective!' - - # Pokemon2 is WEAK - if Pokemon2.types == version[(i+2)%3]: - self.attack *= 2 - self.defense *= 2 - Pokemon2.attack /= 2 - Pokemon2.defense /= 2 - string_1_attack = '\nIts super effective!' - string_2_attack = '\nIts not very effective...' - - - # Now for the actual fighting... - # Continue while pokemon still have health - while (self.bars > 0) and (Pokemon2.bars > 0): - # Print the health of each pokemon + # Type advantage + attack_multiplier, string_1_attack = self.type_advantage(opponent.ptype) + defense_multiplier, string_2_attack = opponent.type_advantage(self.ptype) + self.attack *= attack_multiplier + self.defense /= defense_multiplier + opponent.attack *= defense_multiplier + opponent.defense /= attack_multiplier + + # Fight loop + while self.bars > 0 and opponent.bars > 0: print(f"\n{self.name}\t\tHLTH\t{self.health}") - print(f"{Pokemon2.name}\t\tHLTH\t{Pokemon2.health}\n") + print(f"{opponent.name}\t\tHLTH\t{opponent.health}\n") print(f"Go {self.name}!") - for i, x in enumerate(self.moves): - print(f"{i+1}.", x) - index = int(input('Pick a move: ')) - delay_print(f"\n{self.name} used {self.moves[index-1]}!") - time.sleep(1) - delay_print(string_1_attack) + for i, move in enumerate(self.moves): + print(f"{i+1}. {move}") + index = int(input("Pick a move: ")) + if 1 <= index <= len(self.moves): + delay_print(f"\n{self.name} used {self.moves[index-1]}!") + time.sleep(1) + delay_print(string_1_attack) + else: + print("\nInvalid move. Try again.") + continue # Determine damage - Pokemon2.bars -= self.attack - Pokemon2.health = "" - - # Add back bars plus defense boost - for j in range(int(Pokemon2.bars+.1*Pokemon2.defense)): - Pokemon2.health += "=" + opponent.bars -= self.attack + opponent.health = "=" * max(int(opponent.bars + 0.1 * opponent.defense), 0) time.sleep(1) print(f"\n{self.name}\t\tHLTH\t{self.health}") - print(f"{Pokemon2.name}\t\tHLTH\t{Pokemon2.health}\n") - time.sleep(.5) + print(f"{opponent.name}\t\tHLTH\t{opponent.health}\n") + time.sleep(0.5) - # Check to see if Pokemon fainted - if Pokemon2.bars <= 0: - delay_print("\n..." + Pokemon2.name + ' fainted.') + if opponent.bars <= 0: + delay_print("\n..." + opponent.name + " fainted.") break - # Pokemon2s turn - - print(f"Go {Pokemon2.name}!") - for i, x in enumerate(Pokemon2.moves): - print(f"{i+1}.", x) - index = int(input('Pick a move: ')) - delay_print(f"\n{Pokemon2.name} used {Pokemon2.moves[index-1]}!") + # Opponent's turn + print(f"Go {opponent.name}!") + for i, move in enumerate(opponent.moves): + print(f"{i+1}. {move}") + index = np.random.randint( + 1, len(opponent.moves) + 1 + ) # Random move for the opponent + delay_print(f"\n{opponent.name} used {opponent.moves[index-1]}!") time.sleep(1) delay_print(string_2_attack) # Determine damage - self.bars -= Pokemon2.attack - self.health = "" - - # Add back bars plus defense boost - for j in range(int(self.bars+.1*self.defense)): - self.health += "=" + self.bars -= opponent.attack + self.health = "=" * max(int(self.bars + 0.1 * self.defense), 0) time.sleep(1) print(f"{self.name}\t\tHLTH\t{self.health}") - print(f"{Pokemon2.name}\t\tHLTH\t{Pokemon2.health}\n") - time.sleep(.5) + print(f"{opponent.name}\t\tHLTH\t{opponent.health}\n") + time.sleep(0.5) - # Check to see if Pokemon fainted if self.bars <= 0: - delay_print("\n..." + self.name + ' fainted.') + delay_print("\n..." + self.name + " fainted.") break money = np.random.choice(5000) delay_print(f"\nOpponent paid you ${money}.\n") - - - - - - -if __name__ == '__main__': - #Create Pokemon - Charizard = Pokemon('Charizard', 'Fire', ['Flamethrower', 'Fly', 'Blast Burn', 'Fire Punch'], {'ATTACK':12, 'DEFENSE': 8}) - Blastoise = Pokemon('Blastoise', 'Water', ['Water Gun', 'Bubblebeam', 'Hydro Pump', 'Surf'],{'ATTACK': 10, 'DEFENSE':10}) - Venusaur = Pokemon('Venusaur', 'Grass', ['Vine Wip', 'Razor Leaf', 'Earthquake', 'Frenzy Plant'],{'ATTACK':8, 'DEFENSE':12}) - - Charmander = Pokemon('Charmander', 'Fire', ['Ember', 'Scratch', 'Tackle', 'Fire Punch'],{'ATTACK':4, 'DEFENSE':2}) - Squirtle = Pokemon('Squirtle', 'Water', ['Bubblebeam', 'Tackle', 'Headbutt', 'Surf'],{'ATTACK': 3, 'DEFENSE':3}) - Bulbasaur = Pokemon('Bulbasaur', 'Grass', ['Vine Wip', 'Razor Leaf', 'Tackle', 'Leech Seed'],{'ATTACK':2, 'DEFENSE':4}) - - Charmeleon = Pokemon('Charmeleon', 'Fire', ['Ember', 'Scratch', 'Flamethrower', 'Fire Punch'],{'ATTACK':6, 'DEFENSE':5}) - Wartortle = Pokemon('Wartortle', 'Water', ['Bubblebeam', 'Water Gun', 'Headbutt', 'Surf'],{'ATTACK': 5, 'DEFENSE':5}) - Ivysaur = Pokemon('Ivysaur\t', 'Grass', ['Vine Wip', 'Razor Leaf', 'Bullet Seed', 'Leech Seed'],{'ATTACK':4, 'DEFENSE':6}) - - - Charizard.fight(Squirtle) # Get them to fight \ No newline at end of file + self.gain_experience(100) + + def gain_experience(self, exp): + self.experience += exp + if self.experience >= 100: + self.level_up() + + def level_up(self): + self.level += 1 + self.attack += 1 + self.defense += 1 + self.bars += 5 + self.health = "=" * self.bars + self.experience = 0 + print(f"\n{self.name} leveled up to level {self.level}!") + + +if __name__ == "__main__": + # Create Pokemon + Charizard = Pokemon( + "Charizard", + "Fire", + ["Flamethrower", "Fly", "Blast Burn", "Fire Punch"], + {"ATTACK": 12, "DEFENSE": 8}, + ) + Blastoise = Pokemon( + "Blastoise", + "Water", + ["Water Gun", "Bubblebeam", "Hydro Pump", "Surf"], + {"ATTACK": 10, "DEFENSE": 10}, + ) + Venusaur = Pokemon( + "Venusaur", + "Grass", + ["Vine Whip", "Razor Leaf", "Earthquake", "Frenzy Plant"], + {"ATTACK": 8, "DEFENSE": 12}, + ) + + Charmander = Pokemon( + "Charmander", + "Fire", + ["Ember", "Scratch", "Tackle", "Fire Punch"], + {"ATTACK": 4, "DEFENSE": 2}, + ) + Squirtle = Pokemon( + "Squirtle", + "Water", + ["Bubblebeam", "Tackle", "Headbutt", "Surf"], + {"ATTACK": 3, "DEFENSE": 3}, + ) + Bulbasaur = Pokemon( + "Bulbasaur", + "Grass", + ["Vine Whip", "Razor Leaf", "Tackle", "Leech Seed"], + {"ATTACK": 2, "DEFENSE": 4}, + ) + + Charmeleon = Pokemon( + "Charmeleon", + "Fire", + ["Ember", "Scratch", "Flamethrower", "Fire Punch"], + {"ATTACK": 6, "DEFENSE": 5}, + ) + Wartortle = Pokemon( + "Wartortle", + "Water", + ["Bubblebeam", "Water Gun", "Headbutt", "Surf"], + {"ATTACK": 5, "DEFENSE": 5}, + ) + Ivysaur = Pokemon( + "Ivysaur", + "Grass", + ["Vine Whip", "Razor Leaf", "Bullet Seed", "Leech Seed"], + {"ATTACK": 4, "DEFENSE": 6}, + ) + + Charizard.fight(Squirtle) # Get them to fight