homework commit
This commit is contained in:
Binary file not shown.
Binary file not shown.
+213
@@ -0,0 +1,213 @@
|
||||
import random
|
||||
import math
|
||||
import game_data as gd
|
||||
import copy
|
||||
|
||||
class Pokemon:
|
||||
def __init__(self, national_pokedex_number, name, level = 1, types = [], baseStats = {}, moves = [], curr_hp = 0):
|
||||
self.national_pokedex_number = national_pokedex_number
|
||||
self.name = name
|
||||
self.level = level
|
||||
self.types = types
|
||||
self.baseStats = baseStats
|
||||
self.moves_dict = {}
|
||||
if len(self.moves_dict) > 4:
|
||||
raise ValueError("A Pokemon can only have 4 moves.")
|
||||
else:
|
||||
for move in moves:
|
||||
if move not in gd.available_moves:
|
||||
raise ValueError(f"{move} is not an available move.")
|
||||
else:
|
||||
self.moves_dict[move] = copy.deepcopy(gd.available_moves[move])
|
||||
self.curr_hp = self.baseStats['hp']
|
||||
|
||||
|
||||
def _get_baseStats(self):
|
||||
return self.baseStats
|
||||
|
||||
def get_current_hp(self):
|
||||
return self.curr_hp
|
||||
|
||||
def can_battle(self):
|
||||
condition1 = self.curr_hp > 0
|
||||
condition2 = False
|
||||
for move in self.moves_dict:
|
||||
move_usage_avail = self.moves_dict[move]['PP'] > 0
|
||||
if move_usage_avail:
|
||||
condition2 = True
|
||||
break
|
||||
else:
|
||||
condition2 = False
|
||||
return condition1 and condition2
|
||||
|
||||
def learnMove(self, move):
|
||||
if len(self.moves_dict) >= 4:
|
||||
raise ValueError("A Pokemon can only have 4 moves.")
|
||||
else:
|
||||
self.moves_dict[move] = gd.available_moves[move]
|
||||
|
||||
def _useMove(self, move, opponent):
|
||||
if move['PP'] > 0:
|
||||
if random.random() < move['accuracy']:
|
||||
if move['category'] == 'physical':
|
||||
attack = self.baseStats['attack']
|
||||
defense = opponent.baseStats['defense']
|
||||
else:
|
||||
attack = self.baseStats['special']
|
||||
defense = opponent.baseStats['special']
|
||||
stability = 1.5 if move['type'] in self.types else 1
|
||||
effect = 1
|
||||
critical = 2 if random.random() < self.baseStats['speed']/512 else 1
|
||||
luck = random.uniform(0.85, 1.0)
|
||||
modifier = stability * effect * critical * luck
|
||||
damage = math.floor(((2*self.level+10)/250 * (attack/defense) * move['power'] + 2) * modifier)
|
||||
opponent.curr_hp -= damage
|
||||
if opponent.curr_hp < 0:
|
||||
opponent.curr_hp = 0
|
||||
print(f"{self.name} used {move['name']} and dealt {damage} damage to {opponent.name}!")
|
||||
move['PP'] = move['PP'] - 1
|
||||
else:
|
||||
print(f"{self.name}'s attack missed!")
|
||||
move['PP'] = move['PP'] - 1
|
||||
else:
|
||||
print(f"{self.name} has no PP left for {move['name']}!")
|
||||
pass
|
||||
|
||||
def useMove(self, move_name, opponent):
|
||||
if move_name not in self.moves_dict:
|
||||
raise ValueError(f"{self.name} does not know the move {move_name}.")
|
||||
else:
|
||||
self._useMove(self.moves_dict[move_name], opponent)
|
||||
|
||||
def print_move(self,move):
|
||||
print(f"Move: {self.moves_dict[move]['name']}")
|
||||
print(f"Type: {self.moves_dict[move]['type']}")
|
||||
print(f"Category: {self.moves_dict[move]['category']}")
|
||||
print(f"Power: {self.moves_dict[move]['power']}")
|
||||
print(f"Accuracy: {self.moves_dict[move]['accuracy']}")
|
||||
print(f"PP: {self.moves_dict[move]['PP']}")
|
||||
|
||||
def get_moves(self):
|
||||
return list(self.moves_dict.keys())
|
||||
|
||||
def checkout_move(self, move_name):
|
||||
if move_name not in self.moves_dict:
|
||||
raise ValueError(f"{self.name} does not know the move {move_name}.")
|
||||
else:
|
||||
self.print_move(move_name)
|
||||
|
||||
def _status(self):
|
||||
print(f"Pokemon: {self.name}")
|
||||
print(f"Level: {self.level}")
|
||||
print(f"Types: {self.types}")
|
||||
print(f"Base Stats: {self.baseStats}")
|
||||
print(f"Current HP: {self.curr_hp}")
|
||||
print(f"Moves: {self.moves_dict}")
|
||||
|
||||
def print_pokemon_info(self):
|
||||
self._status()
|
||||
|
||||
|
||||
class Trainer:
|
||||
def __init__(self, name, starter_name, items = {"potions": 0, "pokeball": 0}, is_CPU = False):
|
||||
self.name = name
|
||||
if is_CPU:
|
||||
if starter_name not in gd.available_wild_pokemons:
|
||||
raise ValueError(f"{starter_name} is not an available wild Pokemon.")
|
||||
else:
|
||||
self.starter = starter_name
|
||||
self.active_pokemon = Pokemon(**gd.available_wild_pokemons[starter_name])
|
||||
self.pokemon_list = []
|
||||
self.add_pokemon(self.active_pokemon)
|
||||
else:
|
||||
if starter_name not in gd.available_starters:
|
||||
raise ValueError(f"{starter_name} is not an available starter Pokemon.")
|
||||
else:
|
||||
self.starter = starter_name
|
||||
self.active_pokemon = Pokemon(**gd.available_starters[starter_name])
|
||||
self.pokemon_list = []
|
||||
self.add_pokemon(self.active_pokemon)
|
||||
|
||||
self.items = items
|
||||
self.is_CPU = is_CPU
|
||||
|
||||
def add_pokemon(self, pokemon):
|
||||
if len(self.pokemon_list) >= 6:
|
||||
raise ValueError("A trainer can only have 6 Pokemon.")
|
||||
else:
|
||||
self.pokemon_list.append(pokemon)
|
||||
|
||||
def get_pokemon_list(self):
|
||||
return [pok.name for pok in self.pokemon_list]
|
||||
|
||||
def get_pokemon(self, name):
|
||||
for pokemon in self.pokemon_list:
|
||||
if pokemon.name == name:
|
||||
return pokemon
|
||||
raise ValueError(f"{name} is not in the trainer's Pokemon list.")
|
||||
|
||||
def can_battle(self):
|
||||
for pokemon in self.pokemon_list:
|
||||
if pokemon.can_battle():
|
||||
return True
|
||||
return False
|
||||
|
||||
def active_pokemon_can_battle(self):
|
||||
return self.active_pokemon.can_battle()
|
||||
|
||||
def _change_active_pokemon(self,new_pokemon):
|
||||
self.active_pokemon = new_pokemon
|
||||
|
||||
def get_active_pokemon(self):
|
||||
return self.active_pokemon
|
||||
|
||||
def change_active_pokemon(self,pokemon_name):
|
||||
try:
|
||||
new_pokemon = self.get_pokemon(pokemon_name)
|
||||
self._change_active_pokemon(new_pokemon)
|
||||
print("Pokemon change successfull!")
|
||||
except ValueError as e:
|
||||
raise e
|
||||
|
||||
def print_items(self):
|
||||
print(f"1) Potions: {self.items['potions']}")
|
||||
print(f"2) Pokeballs: {self.items['pokeball']}")
|
||||
|
||||
def use_item(self, item_name):
|
||||
if item_name not in self.items:
|
||||
raise ValueError(f"{item_name} is not an available item.")
|
||||
else:
|
||||
if self.items[item_name] > 0:
|
||||
self.items[item_name] -= 1 #use the item
|
||||
print(f"Used {item_name}. Remaining: {self.items[item_name]}")
|
||||
if item_name == "potions":
|
||||
self.active_pokemon.curr_hp += 20
|
||||
if self.active_pokemon.curr_hp > self.active_pokemon.baseStats['hp']:
|
||||
self.active_pokemon.curr_hp = self.active_pokemon.baseStats['hp']
|
||||
print(f"{self.active_pokemon.name} has been healed by 20 HP!")
|
||||
return False
|
||||
elif item_name == "pokeball":
|
||||
return True
|
||||
else:
|
||||
raise ValueError(f"You have no {item_name} left.")
|
||||
|
||||
def update_pokemon_list(self, pokemon):
|
||||
pass
|
||||
|
||||
def _status(self):
|
||||
print('='*30)
|
||||
print(f"Trainer name: {self.name}")
|
||||
print(f"Starter Pokemon: {self.starter}")
|
||||
print(f"Pokemon List: {[pok.name for pok in self.pokemon_list]}")
|
||||
print("Active Pokemon info:")
|
||||
self.active_pokemon.print_pokemon_info()
|
||||
print("Detailed info of Pokemons in your list:")
|
||||
print("-"*30)
|
||||
for pokemon in self.pokemon_list:
|
||||
pokemon.print_pokemon_info()
|
||||
print("-"*30)
|
||||
print(f"Items: {self.items}")
|
||||
print('='*30)
|
||||
|
||||
def print_trainer_info(self):
|
||||
self._status()
|
||||
@@ -0,0 +1,120 @@
|
||||
##########################
|
||||
#known moves
|
||||
##########################
|
||||
tackle = {
|
||||
'name': 'tackle',
|
||||
'type': 'normal',
|
||||
'category': 'physical',
|
||||
'power': 35,
|
||||
'accuracy': 0.95,
|
||||
'PP': 35
|
||||
}
|
||||
|
||||
razor_leaf = {
|
||||
'name': 'razor leaf',
|
||||
'type': 'grass',
|
||||
'category': 'physical',
|
||||
'power': 55,
|
||||
'accuracy': 0.95,
|
||||
'PP': 25
|
||||
}
|
||||
|
||||
ember = {
|
||||
'name': 'ember',
|
||||
'type': 'fire',
|
||||
'category': 'special',
|
||||
'power': 40,
|
||||
'accuracy': 1.0,
|
||||
'PP': 25
|
||||
}
|
||||
|
||||
water_gun = {
|
||||
'name': 'water gun',
|
||||
'type': 'water',
|
||||
'category': 'special',
|
||||
'power': 40,
|
||||
'accuracy': 1.0,
|
||||
'PP': 25
|
||||
}
|
||||
|
||||
peck = {
|
||||
"name": "peck",
|
||||
"type": "flying",
|
||||
"category": "physical",
|
||||
"power": 35,
|
||||
"accuracy": 1.0,
|
||||
"PP": 35
|
||||
}
|
||||
|
||||
twineedle = {
|
||||
"name": "twineedle",
|
||||
"type": "bug",
|
||||
"category": "physical",
|
||||
"power": 25,
|
||||
"accuracy": 1.0,
|
||||
"PP": 20
|
||||
}
|
||||
|
||||
available_moves = {'tackle': tackle, 'razor leaf': razor_leaf, 'ember': ember, 'water gun': water_gun, 'peck': peck, 'twineedle': twineedle}
|
||||
###########################
|
||||
#starter pokemon
|
||||
###########################
|
||||
bulbasaur = {
|
||||
'national_pokedex_number': 1,
|
||||
'name': "bulbasaur",
|
||||
'types': ["grass", "poison"],
|
||||
'baseStats': {"hp": 45, "attack": 49, "defense": 49, "speed": 45, "special": 65},
|
||||
'moves': ["tackle", "razor leaf"]
|
||||
}
|
||||
|
||||
charmender = {
|
||||
'national_pokedex_number': 4,
|
||||
'name': "charmander",
|
||||
'types': ["fire"],
|
||||
'baseStats': {"hp": 39, "attack": 52, "defense": 43, "speed": 65, "special": 50},
|
||||
'moves': ["tackle", "ember"]
|
||||
}
|
||||
|
||||
squirtle = {
|
||||
'national_pokedex_number': 7,
|
||||
'name': "squirtle",
|
||||
'types': ["water"],
|
||||
'baseStats': {"hp": 44, "attack": 48, "defense": 65, "speed": 43, "special": 50},
|
||||
'moves': ["tackle", "water gun"]
|
||||
}
|
||||
|
||||
available_starters = {'bulbasaur': bulbasaur, 'charmander': charmender, 'squirtle': squirtle}
|
||||
available_starter_names = list(available_starters.keys())
|
||||
############################
|
||||
|
||||
############################
|
||||
#wild pokemons
|
||||
############################
|
||||
|
||||
caterpie = {
|
||||
"national_pokedex_number": 10,
|
||||
"name": "caterpie",
|
||||
"types": ["bug"],
|
||||
"baseStats": {"hp": 45, "attack": 30, "defense": 35, "speed": 45, "special": 20},
|
||||
"moves" : ["twineedle"]
|
||||
}
|
||||
|
||||
pidgey = {
|
||||
"national_pokedex_number": 16,
|
||||
"name": "pidgey",
|
||||
"types": ["normal", "flying"],
|
||||
"baseStats": {"hp": 40, "attack": 45, "defense": 40, "speed": 56, "special": 35},
|
||||
"moves" : ["tackle", "peck"]
|
||||
|
||||
}
|
||||
|
||||
rattata = {
|
||||
"national_pokedex_number": 19,
|
||||
"name": "rattata",
|
||||
"types": ["normal"],
|
||||
"baseStats": {"hp": 30, "attack": 56, "defense": 35, "speed": 72, "special": 25},
|
||||
"moves" : ["tackle"]
|
||||
}
|
||||
|
||||
available_wild_pokemons = {'caterpie':caterpie, 'pidgey':pidgey, 'rattata':rattata}
|
||||
available_wild_pokemon_names = list(available_wild_pokemons.keys())
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
from core import Trainer
|
||||
import game_data as gd
|
||||
import random
|
||||
import copy
|
||||
|
||||
game_status = 'story'
|
||||
game_active_flag = True
|
||||
|
||||
def Battle(trainer,cpu_trainer):
|
||||
global game_status
|
||||
global game_active_flag
|
||||
print("You are in battle!")
|
||||
battle_active = True
|
||||
|
||||
while battle_active:
|
||||
player_battle_action_selected = False
|
||||
while not player_battle_action_selected:
|
||||
print("Type the number of one of the following actions:")
|
||||
print(f"1) Attack - [Your active Pokemon - {trainer.get_active_pokemon().name}]")
|
||||
print("2) Change pokemon")
|
||||
print("3) Use item")
|
||||
print("4) Run away")
|
||||
print('5) Check status')
|
||||
|
||||
try:
|
||||
action = int(input("Choose an action (1-5): ").strip())
|
||||
player_battle_action_selected = True
|
||||
except ValueError:
|
||||
print("Invalid input. Please enter a number between 1 and 5.")
|
||||
continue
|
||||
|
||||
if action == 1:
|
||||
#check if the player can sustain a battle: first check the active pokemon,
|
||||
#then check the pokemons in the list
|
||||
if not trainer.active_pokemon_can_battle():
|
||||
print("Your active pokemon cannot battle!")
|
||||
if not trainer.can_battle():
|
||||
print("You have no more pokemon that can battle! You lost the battle!")
|
||||
battle_active = False
|
||||
game_status = 'pokemon_center'
|
||||
break
|
||||
else:
|
||||
print("You have other pokemon that can battle! Please change your active pokemon!")
|
||||
continue
|
||||
|
||||
selected_combat_move_flag = False
|
||||
while not selected_combat_move_flag:
|
||||
active_pokemon = trainer.get_active_pokemon()
|
||||
cpu_active_pokemon = cpu_trainer.get_active_pokemon()
|
||||
print(f"Choose a move for {active_pokemon.name} to use against {cpu_active_pokemon.name}:\n", active_pokemon.get_moves())
|
||||
player_move_name = input("Choose:")
|
||||
try:
|
||||
active_pokemon.useMove(player_move_name,cpu_active_pokemon)
|
||||
selected_combat_move_flag = True
|
||||
#check if the opponent has been defeated
|
||||
if not cpu_trainer.active_pokemon_can_battle():
|
||||
print(f"{cpu_trainer.get_active_pokemon().name} has been defeated!")
|
||||
battle_active = False
|
||||
game_status = 'story'
|
||||
break
|
||||
|
||||
#if the opponent has not been defeated, then its the CPU turn to play
|
||||
cpu_active_pokemon_selected_move_name = random.choice(cpu_active_pokemon.get_moves())
|
||||
print(f"CPU's {cpu_active_pokemon.name} is using {cpu_active_pokemon_selected_move_name} against your {active_pokemon.name}!")
|
||||
cpu_active_pokemon.useMove(cpu_active_pokemon_selected_move_name, active_pokemon)
|
||||
|
||||
#update the player pokemon list
|
||||
trainer.update_pokemon_list(active_pokemon)
|
||||
#check if the player has been defeated
|
||||
if not trainer.active_pokemon_can_battle():
|
||||
print(f"Your {active_pokemon.name} has been defeated!")
|
||||
if not trainer.can_battle():
|
||||
print("You have no more Pokemons that can battle! You lost!")
|
||||
battle_active = False
|
||||
game_status = 'pokemon_center'
|
||||
break
|
||||
else:
|
||||
print("You have other Pokemons that can battle!")
|
||||
continue
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
print("Please try again...")
|
||||
|
||||
elif action == 2:
|
||||
print('='*30)
|
||||
print("Change active pokemon")
|
||||
print('-'*30)
|
||||
change_pokemon_success = False
|
||||
while not change_pokemon_success:
|
||||
try:
|
||||
print("Select the name of a pokemon in your list:")
|
||||
print(trainer.get_pokemon_list())
|
||||
chosen_new_pokemon_name = input('Choose...')
|
||||
trainer.change_active_pokemon(chosen_new_pokemon_name)
|
||||
change_pokemon_success = True
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
|
||||
elif action == 3:
|
||||
print("Select the item index to use:")
|
||||
trainer.print_items()
|
||||
item_selected_flag = False
|
||||
while not item_selected_flag:
|
||||
try:
|
||||
avail_items = list(trainer.items.keys())
|
||||
item_index = int(input("Choose an item index (1-2): ").strip())
|
||||
item_selected_flag = True
|
||||
is_pokeball = trainer.use_item(item_name=avail_items[item_index - 1])
|
||||
if is_pokeball:
|
||||
catch_prob = 1 - (cpu_trainer.get_active_pokemon().get_current_hp() / cpu_trainer.get_active_pokemon().baseStats['hp'])
|
||||
random_value = random.uniform(0, 1)
|
||||
if random_value < catch_prob:
|
||||
print(f"You caught {cpu_trainer.get_active_pokemon().name}!")
|
||||
trainer.add_pokemon(cpu_trainer.get_active_pokemon())
|
||||
battle_active = False
|
||||
game_status = 'story'
|
||||
else:
|
||||
print(f"{cpu_trainer.get_active_pokemon().name} escaped your pokeball!")
|
||||
except ValueError:
|
||||
print("Please enter a number between 1 and 2.")
|
||||
continue
|
||||
|
||||
elif action == 4:
|
||||
runaway_prob = 0.6
|
||||
random_value = random.uniform(0, 1)
|
||||
if random_value < runaway_prob:
|
||||
print("You successfully ran away from the battle!")
|
||||
battle_active = False
|
||||
game_status = 'story'
|
||||
else:
|
||||
print("You could not run away from the battle!")
|
||||
|
||||
elif action == 5:
|
||||
print('='*30)
|
||||
print("BATTLE INFO")
|
||||
print('-'*30)
|
||||
print("Your items:")
|
||||
trainer.print_items()
|
||||
print("Your pokemon list info:")
|
||||
for pokemon in trainer.pokemon_list:
|
||||
pokemon.print_pokemon_info()
|
||||
print("-"*30)
|
||||
print("CPU active pokemon info:")
|
||||
cpu_trainer.get_active_pokemon().print_pokemon_info()
|
||||
print('='*30)
|
||||
else:
|
||||
print("Invalid action. Please choose again.")
|
||||
|
||||
def Main():
|
||||
global game_status
|
||||
global game_active_flag
|
||||
player_created_flag = False
|
||||
while not player_created_flag:
|
||||
try:
|
||||
trainer_name = input("Enter your trainer name: ")
|
||||
print("Available starter Pokemon: ", gd.available_starter_names)
|
||||
starter_name = input("Choose your starter Pokemon: ")
|
||||
trainer = Trainer(name=trainer_name, starter_name=starter_name)
|
||||
print(f"{trainer.name} has chosen {trainer.starter} as their starter Pokemon!")
|
||||
print("Adding potions and pokeballs to your inventory...")
|
||||
trainer.items = {"potions": 10, "pokeball": 10}
|
||||
print("Your character is ready!")
|
||||
trainer.print_trainer_info()
|
||||
player_created_flag = True
|
||||
print(f"Welcome {trainer.name}! Your adventure begins now!")
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
print("Please try again...")
|
||||
continue
|
||||
|
||||
while game_active_flag:
|
||||
if game_status == 'story':
|
||||
print("Type the number of one of the following actions:")
|
||||
print("1) Explore ")
|
||||
print("2) Pokemon Center")
|
||||
print("3) Pokemon Store")
|
||||
print("4) Show trainer data")
|
||||
print("5) Exit")
|
||||
|
||||
try:
|
||||
action = int(input("Choose an action (1-5): ").strip())
|
||||
except ValueError:
|
||||
print("Invalid input. Please enter a number between 1 and 5.")
|
||||
continue
|
||||
if action == 1:
|
||||
game_status = 'explore'
|
||||
elif action == 2:
|
||||
game_status = 'pokemon_center'
|
||||
elif action == 3:
|
||||
game_status = 'pokemon_store'
|
||||
elif action == 4:
|
||||
print("Showing trainer data:")
|
||||
trainer.print_trainer_info()
|
||||
elif action == 5:
|
||||
print("Exiting the game. Goodbye!")
|
||||
game_active_flag = False
|
||||
else:
|
||||
print("Invalid action. Please choose again.")
|
||||
elif game_status == 'explore':
|
||||
print("You are exploring")
|
||||
battle_prob = random.uniform(0, 1)
|
||||
print(f"Battle probability: {battle_prob:.2f}")
|
||||
if battle_prob < 0.8:
|
||||
print("A wild Pokemon appeared!")
|
||||
cpu_trainer = Trainer(name='CPU',starter_name=gd.available_wild_pokemon_names[random.randint(0,len(gd.available_wild_pokemon_names)-1)],is_CPU=True)
|
||||
print(cpu_trainer.get_active_pokemon().print_pokemon_info())
|
||||
game_status = 'battle'
|
||||
Battle(trainer,cpu_trainer)
|
||||
else:
|
||||
print('-'*30)
|
||||
print("No wild Pokemon appeared.")
|
||||
game_status = 'story'
|
||||
|
||||
elif game_status == 'pokemon_center':
|
||||
print("You are at the Pokemon Center. You can heal your Pokemon here.")
|
||||
heal_flag = input("Type 'yes' to heal your Pokemons: ").strip().lower()
|
||||
if heal_flag == 'yes':
|
||||
for pokemon in trainer.pokemon_list:
|
||||
pokemon.curr_hp = pokemon.baseStats['hp']
|
||||
for move in pokemon.moves_dict.keys():
|
||||
pokemon.moves_dict[move]['PP'] = copy.deepcopy(gd.available_moves[move]['PP'])
|
||||
print("All your Pokemon have been healed!")
|
||||
game_status = 'story'
|
||||
else:
|
||||
print("You exited the Pokemon Center.")
|
||||
game_status = 'story'
|
||||
# Add Pokemon Center logic here
|
||||
elif game_status == 'pokemon_store':
|
||||
print("You are in the Pokemon Store. You can buy items here.")
|
||||
restore_items_flag = input("Type 'yes' to restore your items: ").strip().lower()
|
||||
if restore_items_flag == 'yes':
|
||||
trainer.items = {"potions": 10, "pokeball": 10}
|
||||
print("Your items have been restored!")
|
||||
game_status = 'story'
|
||||
else:
|
||||
print("You exited the Pokemon Store.")
|
||||
game_status = 'story'
|
||||
else:
|
||||
print("Unknown game status. Try again.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
Main()
|
||||
Reference in New Issue
Block a user