homework commit
This commit is contained in:
Binary file not shown.
Binary file not shown.
+215
@@ -0,0 +1,215 @@
|
|||||||
|
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])
|
||||||
|
print(gd.available_moves[move]['PP'])
|
||||||
|
print("TYPE", type(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())
|
||||||
+71
@@ -0,0 +1,71 @@
|
|||||||
|
import random
|
||||||
|
import math
|
||||||
|
|
||||||
|
import game_data as gd
|
||||||
|
|
||||||
|
from core import Trainer
|
||||||
|
|
||||||
|
def Main():
|
||||||
|
setup_complete = False
|
||||||
|
trainer_name = input("Enter your trainer name: ")
|
||||||
|
while not setup_complete:
|
||||||
|
try:
|
||||||
|
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.get_active_pokemon().name} as their starter Pokemon!")
|
||||||
|
setup_complete = True
|
||||||
|
except ValueError as e:
|
||||||
|
print(e)
|
||||||
|
print("Please try again...")
|
||||||
|
continue
|
||||||
|
trainer.print_trainer_info()
|
||||||
|
|
||||||
|
cpu_trainer = Trainer(name="CPU", starter_name=random.choice(gd.available_starter_names))
|
||||||
|
print(f"CPU has chosen {cpu_trainer.get_active_pokemon().name} as their starter Pokemon!")
|
||||||
|
cpu_trainer.print_trainer_info()
|
||||||
|
continue_playing = True
|
||||||
|
while continue_playing:
|
||||||
|
selected_pokemon_combat_flag = False
|
||||||
|
while not selected_pokemon_combat_flag:
|
||||||
|
print("Choose a Pokemon from your list to battle with:\n", trainer.get_pokemon_list())
|
||||||
|
player_pokemon = input("Choose:")
|
||||||
|
try:
|
||||||
|
player_pokemon = trainer.get_pokemon(player_pokemon)
|
||||||
|
selected_pokemon_combat_flag = True
|
||||||
|
except ValueError as e:
|
||||||
|
print(e)
|
||||||
|
print("Please try again...")
|
||||||
|
|
||||||
|
selected_combat_move_flag = False
|
||||||
|
while not selected_combat_move_flag:
|
||||||
|
print(f"Choose a move for {player_pokemon.name} to use against {cpu_trainer.get_active_pokemon().name}:\n", player_pokemon.get_moves())
|
||||||
|
player_move_name = input("Choose:")
|
||||||
|
try:
|
||||||
|
#print the move selected by the player
|
||||||
|
print("Your selected move: ")
|
||||||
|
player_pokemon.checkout_move(player_move_name)
|
||||||
|
selected_combat_move_flag = True
|
||||||
|
except ValueError as e:
|
||||||
|
print(e)
|
||||||
|
print("Please try again...")
|
||||||
|
|
||||||
|
#make a combat
|
||||||
|
print('='*30)
|
||||||
|
print("BATTLE RESULTS:")
|
||||||
|
print("Your move:")
|
||||||
|
player_pokemon.useMove(player_move_name, cpu_trainer.get_active_pokemon())
|
||||||
|
player_pokemon.checkout_move(player_move_name)
|
||||||
|
print('-'*30)
|
||||||
|
print("CPU's pokemon")
|
||||||
|
cpu_trainer.get_active_pokemon().print_pokemon_info()
|
||||||
|
print('='*30)
|
||||||
|
|
||||||
|
print("Continue playing? (yes/no)")
|
||||||
|
response = input().strip().lower()
|
||||||
|
if response != "yes":
|
||||||
|
continue_playing = False
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
Main()
|
||||||
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()
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"python-envs.defaultEnvManager": "ms-python.python:conda",
|
||||||
|
"python-envs.defaultPackageManager": "ms-python.python:conda"
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
+220
@@ -0,0 +1,220 @@
|
|||||||
|
import random
|
||||||
|
import math
|
||||||
|
import copy
|
||||||
|
import game_data as gd
|
||||||
|
|
||||||
|
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.keys():
|
||||||
|
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 get_current_hp_percent(self):
|
||||||
|
return self.curr_hp / self.baseStats['hp']
|
||||||
|
|
||||||
|
def can_battle(self):
|
||||||
|
condition1 = self.curr_hp > 0
|
||||||
|
condition2 = False
|
||||||
|
for move in self.moves_dict:
|
||||||
|
move_usage_avail = True #disregard pp in random battle
|
||||||
|
#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] = copy.deepcopy(gd.available_moves[move])
|
||||||
|
|
||||||
|
def _compute_effect(self, move, opponent):
|
||||||
|
#check the move type (attack) and the defending
|
||||||
|
#pokemon type (defend) and look at effectiveness list.
|
||||||
|
#this should be done for all type of the defending pokemon
|
||||||
|
attack_move_type = move['type']
|
||||||
|
defending_types = opponent.get_types()
|
||||||
|
|
||||||
|
effect = 1
|
||||||
|
|
||||||
|
for def_t in defending_types:
|
||||||
|
for effectiveness_dataset in gd.type_effectiveness:
|
||||||
|
if effectiveness_dataset['attack'] == attack_move_type and effectiveness_dataset['defend'] == def_t:
|
||||||
|
effect = effect * effectiveness_dataset['effectiveness']
|
||||||
|
break
|
||||||
|
return effect
|
||||||
|
|
||||||
|
def _useMove(self, move, opponent):
|
||||||
|
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 = self._compute_effect(move,opponent)
|
||||||
|
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}!")
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
#print(f"{self.name}'s attack missed!")
|
||||||
|
|
||||||
|
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 get_types(self):
|
||||||
|
return self.types
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
self.starter = starter_name
|
||||||
|
self.active_pokemon = Pokemon(**gd.pokemons_dict[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,48 @@
|
|||||||
|
import json
|
||||||
|
import random
|
||||||
|
|
||||||
|
#load moves from json file
|
||||||
|
#eclude moves with power equal to null,
|
||||||
|
# do not consider the effect,effects or changes fields
|
||||||
|
available_moves = dict()
|
||||||
|
keys_to_skip = ['effect','effects','changes']
|
||||||
|
with open('moves.json', 'r') as file:
|
||||||
|
for line in file:
|
||||||
|
m = json.loads(line)
|
||||||
|
if m['power'] == None or m['accuracy'] == None:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
available_moves[m['name']] = {}
|
||||||
|
m_keys = list(m.keys())
|
||||||
|
for k in m_keys:
|
||||||
|
if k in keys_to_skip:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
available_moves[m['name']][k] = m[k]
|
||||||
|
|
||||||
|
#loading pokemons from json file
|
||||||
|
#assume levell = 1 for all
|
||||||
|
pokemons_dict = dict()
|
||||||
|
with open('pokemons.json', 'r') as file:
|
||||||
|
for line in file:
|
||||||
|
p = json.loads(line)
|
||||||
|
pokemons_dict[p['name']] = p
|
||||||
|
pokemons_dict[p['name']]['level'] = 1
|
||||||
|
current_pokemon_types = p['types'] + ['normal']
|
||||||
|
compatible_moves = []
|
||||||
|
for m in available_moves.keys():
|
||||||
|
if available_moves[m]['type'] in current_pokemon_types:
|
||||||
|
compatible_moves.append(m)
|
||||||
|
#select two random moves
|
||||||
|
selected_moves = [random.choice(compatible_moves) for _ in range(2)]
|
||||||
|
pokemons_dict[p['name']]['moves'] = selected_moves
|
||||||
|
|
||||||
|
|
||||||
|
available_pokemon_names = list(pokemons_dict.keys())
|
||||||
|
available_starters = ['bulbasaur', 'charmander', 'squirtle']
|
||||||
|
|
||||||
|
#type effectiveness
|
||||||
|
type_effectiveness = []
|
||||||
|
with open('type_effectiveness.json', 'r') as file:
|
||||||
|
for line in file:
|
||||||
|
type_effectiveness.append(json.loads(line))
|
||||||
+182
@@ -0,0 +1,182 @@
|
|||||||
|
from core import Trainer
|
||||||
|
|
||||||
|
import random
|
||||||
|
import copy
|
||||||
|
import game_data as gd
|
||||||
|
import pickle
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def RandomBattle(trainer,cpu_trainer):
|
||||||
|
#print(f"You are in battle against {cpu_trainer.name}!")
|
||||||
|
battle_active = True
|
||||||
|
|
||||||
|
active_pokemon = trainer.get_active_pokemon()
|
||||||
|
cpu_active_pokemon = cpu_trainer.get_active_pokemon()
|
||||||
|
|
||||||
|
did_player_won = False
|
||||||
|
battle_turns_num = 0
|
||||||
|
|
||||||
|
while battle_active:
|
||||||
|
player_move_name = random.choice(active_pokemon.get_moves())
|
||||||
|
#print(f"{active_pokemon.name} selected {player_move_name} to use against {cpu_active_pokemon.name}:\n")
|
||||||
|
try:
|
||||||
|
|
||||||
|
active_pokemon.useMove(player_move_name,cpu_active_pokemon)
|
||||||
|
battle_turns_num += 1
|
||||||
|
#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! You win!")
|
||||||
|
did_player_won = True
|
||||||
|
battle_active = False
|
||||||
|
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)
|
||||||
|
battle_turns_num += 1
|
||||||
|
#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 lose!")
|
||||||
|
did_player_won=False
|
||||||
|
battle_active = False
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
#print("You have other Pokemons that can battle!")
|
||||||
|
continue
|
||||||
|
|
||||||
|
except ValueError as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
player_residual_hp_percent = trainer.get_active_pokemon().get_current_hp_percent()
|
||||||
|
|
||||||
|
battle_results = {
|
||||||
|
'encountered_pokemon':cpu_trainer.get_active_pokemon().name,
|
||||||
|
'result':did_player_won,
|
||||||
|
'battle_turns_num':battle_turns_num,
|
||||||
|
'player_residual_hp_percent':player_residual_hp_percent
|
||||||
|
}
|
||||||
|
return battle_results
|
||||||
|
|
||||||
|
def Main(starter_choice,Nbattles):
|
||||||
|
try:
|
||||||
|
starter_name = starter_choice
|
||||||
|
trainer = Trainer(name='edo', 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!")
|
||||||
|
#print(f"Welcome {trainer.name}! Your adventure begins now!")
|
||||||
|
except ValueError as e:
|
||||||
|
print(e)
|
||||||
|
print("Something went wrong!")
|
||||||
|
|
||||||
|
game_active_flag = True
|
||||||
|
while game_active_flag:
|
||||||
|
all_battle_results = []
|
||||||
|
for i in range(0,Nbattles):
|
||||||
|
#print("You entered the Random Battle mode")
|
||||||
|
#print("Battle #",i)
|
||||||
|
cpu_trainer = Trainer(name='CPU',starter_name=gd.available_pokemon_names[random.randint(0,len(gd.available_pokemon_names)-1)],is_CPU=True)
|
||||||
|
battle_results = RandomBattle(trainer,cpu_trainer)
|
||||||
|
all_battle_results.append(battle_results)
|
||||||
|
heal_flag = 'yes'
|
||||||
|
if heal_flag == 'yes':
|
||||||
|
for pokemon in trainer.pokemon_list:
|
||||||
|
pokemon.curr_hp = pokemon.baseStats['hp']
|
||||||
|
#print("All your Pokemon have been healed!")
|
||||||
|
|
||||||
|
game_active_flag = False
|
||||||
|
#save all battle results
|
||||||
|
return all_battle_results
|
||||||
|
|
||||||
|
def make_plots(Ngames,Nbattles):
|
||||||
|
#SIMPLE PLOT
|
||||||
|
cumulative_victories = np.zeros((Ngames,Nbattles))
|
||||||
|
plt.figure(figsize=(10, 6))
|
||||||
|
for starter_choice in gd.available_starters:
|
||||||
|
for ng in range(Ngames):
|
||||||
|
pickle_in = open(f"results/{starter_choice}_game_{ng}_{Nbattles}_battles.pickle",'rb')
|
||||||
|
all_battle_results = pickle.load(pickle_in)
|
||||||
|
pickle_in.close()
|
||||||
|
this_game_victory_number = 0
|
||||||
|
for j, battle_result in enumerate(all_battle_results):
|
||||||
|
if battle_result['result'] == True:
|
||||||
|
this_game_victory_number += 1
|
||||||
|
cumulative_victories[ng,j] = this_game_victory_number
|
||||||
|
|
||||||
|
avg_cumulative_victories = np.mean(cumulative_victories,axis=0)
|
||||||
|
|
||||||
|
plt.plot(avg_cumulative_victories, label=f"{starter_choice}")
|
||||||
|
plt.xlabel("Battle number")
|
||||||
|
plt.ylabel("Average number of victories")
|
||||||
|
plt.title(f"Cumulative number of victories over {Nbattles} battles average over {Ngames} games")
|
||||||
|
plt.legend()
|
||||||
|
plt.savefig(f'plots/battle_victories_plot.pdf')
|
||||||
|
|
||||||
|
#BOX PLOT - turns
|
||||||
|
plt.figure(figsize=(10, 6))
|
||||||
|
boxes_to_plot = []
|
||||||
|
for m,starter_choice in enumerate(gd.available_starters):
|
||||||
|
all_battle_turns = np.zeros((Ngames,Nbattles))
|
||||||
|
for i in range(Ngames):
|
||||||
|
pickle_in = open(f"results/{starter_choice}_game_{i}_{Nbattles}_battles.pickle",'rb')
|
||||||
|
all_battle_results = pickle.load(pickle_in)
|
||||||
|
pickle_in.close()
|
||||||
|
for j in range(Nbattles):
|
||||||
|
all_battle_turns[i,j] = all_battle_results[j]['battle_turns_num']
|
||||||
|
|
||||||
|
boxes_to_plot.append(all_battle_turns.flatten())
|
||||||
|
plt.boxplot(boxes_to_plot)
|
||||||
|
|
||||||
|
plt.xticks(np.arange(1,len(gd.available_starters)+1), gd.available_starters, fontsize=15)
|
||||||
|
plt.xlabel("Starter names", fontsize=15)
|
||||||
|
plt.yticks(fontsize=15)
|
||||||
|
plt.ylabel("Number of turns", fontsize=15)
|
||||||
|
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig(f'plots/battle_turns_boxplot.pdf')
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
#BOX PLOT - health
|
||||||
|
boxes_to_plot = []
|
||||||
|
plt.figure(figsize=(10, 6))
|
||||||
|
for m,starter_choice in enumerate(gd.available_starters):
|
||||||
|
all_battle_health = np.zeros((Ngames,Nbattles))
|
||||||
|
for i in range(Ngames):
|
||||||
|
pickle_in = open(f"results/{starter_choice}_game_{i}_{Nbattles}_battles.pickle",'rb')
|
||||||
|
all_battle_results = pickle.load(pickle_in)
|
||||||
|
pickle_in.close()
|
||||||
|
for j in range(Nbattles):
|
||||||
|
all_battle_health[i,j] = all_battle_results[j]['player_residual_hp_percent']*100
|
||||||
|
boxes_to_plot.append(all_battle_health.flatten())
|
||||||
|
plt.boxplot(boxes_to_plot)
|
||||||
|
|
||||||
|
plt.xlabel("Starter names", fontsize=15)
|
||||||
|
plt.xticks(np.arange(1,len(gd.available_starters)+1), gd.available_starters,fontsize=15)
|
||||||
|
plt.yticks(fontsize=15)
|
||||||
|
plt.ylabel("Player residual HP (%)", fontsize=15)
|
||||||
|
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig(f'plots/battle_health_boxplot.pdf')
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
Ngames = 500
|
||||||
|
Nbattles = 100
|
||||||
|
for starter_choice in gd.available_starters:
|
||||||
|
for i in range(Ngames):
|
||||||
|
print(f"Generating data for {starter_choice}, game {i}...")
|
||||||
|
results = Main(starter_choice = starter_choice, Nbattles=Nbattles)
|
||||||
|
pickle_out = open(f"results/{starter_choice}_game_{i}_{Nbattles}_battles.pickle",'wb')
|
||||||
|
pickle.dump(results,pickle_out)
|
||||||
|
pickle_out.close()
|
||||||
|
|
||||||
|
make_plots(Ngames, Nbattles)
|
||||||
+165
@@ -0,0 +1,165 @@
|
|||||||
|
{"name": "absorb", "type": "grass", "category": "special", "power": 20, "accuracy": 1.0, "pp": 20, "effects": ["Absorb deals damage and the user will recover 50% of the HP drained."]}
|
||||||
|
{"name": "acid", "type": "poison", "category": "physical", "power": 40, "accuracy": 1.0, "pp": 30, "effect": {"chance": 0.1, "stat": "defense", "stages": -1}}
|
||||||
|
{"name": "acid armor", "type": "poison", "category": "status", "power": null, "accuracy": null, "pp": 40, "effect": {"stat": "defense", "stages": 2}}
|
||||||
|
{"name": "agility", "type": "psychic", "category": "status", "power": null, "accuracy": null, "pp": 30, "effect": {"stat": "speed", "stages": 2}}
|
||||||
|
{"name": "amnesia", "type": "psychic", "category": "status", "power": null, "accuracy": null, "pp": 20, "effect": {"stat": "special", "stages": 2}}
|
||||||
|
{"name": "aurora beam", "type": "ice", "category": "special", "power": 65, "accuracy": 1.0, "pp": 20, "effect": {"chance": 0.1, "stat": "attack", "stages": -1}}
|
||||||
|
{"name": "barrage", "type": "normal", "category": "physical", "power": 15, "accuracy": 0.85, "pp": 20, "changes": ["In Generations 1-3, Barrage ends immediately if any hit breaks a Substitute.", "In Generation 1, each hit will always deal the same damage - if the first critical hits, so will the rest."]}
|
||||||
|
{"name": "barrier", "type": "psychic", "category": "status", "power": null, "accuracy": null, "pp": 30, "effect": {"stat": "defense", "stages": 2}}
|
||||||
|
{"name": "bide", "type": "normal", "category": "physical", "power": null, "accuracy": null, "pp": 10, "effects": ["The user of Bide stores energy for 2 turns. At the end of the second turn the Pokémon unleashes energy, dealing twice the HP damage it received.", "Bide deals fixed, typeless damage, so will hit Ghost-type Pokémon. It also ignores changes to the Accuracy and Evasion stats and can hit Pokémon in the invulnerable stage of Bounce, Dig, Dive, Fly, Shadow Force or Sky Drop."], "changes": ["In Generations 1-3, Bide is not an increased priority move. It also stores energy for 2-3 turns."]}
|
||||||
|
{"name": "bind", "type": "normal", "category": "physical", "power": 15, "accuracy": 0.85, "pp": 20, "effects": ["Bind inflicts damage on the first turn then traps the opponent, causing them to lose 1⁄16 of their maximum HP after each turn, for 4-5 turns."], "changes": ["In Generations 1-4, Bind has 75% accuracy. Its after-effects last for 2-5 turns instead of 4-5.", "In Generation 1, Bind simply inflicts its base power damage for 2-5 turns. While in effect, the target is unable to attack."]}
|
||||||
|
{"name": "bite", "type": "normal", "category": "physical", "power": 60, "accuracy": 1.0, "pp": 25, "effect": {"chance": 0.3, "statusCondition": "flinch"}}
|
||||||
|
{"name": "blizzard", "type": "ice", "category": "special", "power": 120, "accuracy": 0.9, "pp": 5, "effect": {"chance": 0.1, "statusCondition": "freeze"}}
|
||||||
|
{"name": "body slam", "type": "normal", "category": "physical", "power": 85, "accuracy": 1.0, "pp": 15, "effect": {"chance": 0.3, "statusCondition": "paralysis"}}
|
||||||
|
{"name": "bone club", "type": "ground", "category": "physical", "power": 65, "accuracy": 0.85, "pp": 20, "effect": {"chance": 0.1, "statusCondition": "flinch"}}
|
||||||
|
{"name": "bonemerang", "type": "ground", "category": "physical", "power": 50, "accuracy": 0.9, "pp": 10, "effects": ["Bonemerang deals damage and will strike twice (with 50 base power each time).\nEach strike of Bonemerang is treated like a separate attack:"], "changes": ["In Generations 1-3, Bonemerang ends immediately if any hit breaks a Substitute.", "In Generation 1, each hit will always deal the same damage - if the first critical hits, so will the rest."]}
|
||||||
|
{"name": "bubble", "type": "water", "category": "special", "power": 20, "accuracy": 1.0, "pp": 30, "effect": {"chance": 0.1, "stat": "speed", "stages": -1}}
|
||||||
|
{"name": "bubble beam", "type": "water", "category": "special", "power": 65, "accuracy": 1.0, "pp": 20, "effect": {"chance": 0.1, "stat": "speed", "stages": -1}}
|
||||||
|
{"name": "clamp", "type": "water", "category": "physical", "power": 35, "accuracy": 0.85, "pp": 10, "effects": ["Clamp inflicts damage on the first turn then traps the opponent, causing them to lose 1⁄16 of their maximum HP after each turn, for 4-5 turns. If the user holds a Grip Claw then it is always 5 turns."], "changes": ["In Generations 1-4, Clamp has 75% accuracy. Its after-effects last for 2-5 turns instead of 4-5.", "In Generation 1, Clamp simply inflicts its base power damage for 2-5 turns. While in effect, the target is unable to attack."]}
|
||||||
|
{"name": "comet punch", "type": "normal", "category": "physical", "power": 18, "accuracy": 0.85, "pp": 15, "changes": ["In Generations 1-3, Comet Punch ends immediately if any hit breaks a Substitute.", "In Generation 1, each hit will always deal the same damage - if the first critical hits, so will the rest."]}
|
||||||
|
{"name": "confuse ray", "type": "ghost", "category": "status", "power": null, "accuracy": 1.0, "pp": 10, "effect": {"statusCondition": "confused"}}
|
||||||
|
{"name": "confusion", "type": "psychic", "category": "special", "power": 50, "accuracy": 1.0, "pp": 25, "effect": {"chance": 0.1, "statusCondition": "confused"}}
|
||||||
|
{"name": "constrict", "type": "normal", "category": "physical", "power": 10, "accuracy": 1.0, "pp": 35, "effect": {"chance": 0.1, "stat": "speed", "stages": -1}}
|
||||||
|
{"name": "conversion", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 30, "changes": ["In Generation 1, Conversion changes the user's type to the target Pokémon's type."]}
|
||||||
|
{"name": "counter", "type": "fighting", "category": "physical", "power": null, "accuracy": 1.0, "pp": 20, "priority": -1, "effects": ["When hit by a Physical Attack, user strikes back with 2x power."]}
|
||||||
|
{"name": "crabhammer", "type": "water", "category": "physical", "power": 90, "accuracy": 0.85, "pp": 10, "highCriticalHitRatio": true}
|
||||||
|
{"name": "cut", "type": "normal", "category": "physical", "power": 50, "accuracy": 0.95, "pp": 30}
|
||||||
|
{"name": "defense curl", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 40, "effect": {"stat": "defense", "stages": 1}}
|
||||||
|
{"name": "dig", "type": "ground", "category": "physical", "power": 60, "accuracy": 1.0, "pp": 10, "effects": ["The user of Dig will burrow its way underground on the first turn, disappearing from view and becoming invulnerable to most attacks. On the second turn, Dig deals damage."]}
|
||||||
|
{"name": "disable", "type": "normal", "category": "status", "power": null, "accuracy": 0.55, "pp": 20, "effects": ["Disable causes the previous move the target used to be disabled for 1-8 turns, which prevents the move's use."]}
|
||||||
|
{"name": "dizzy punch", "type": "normal", "category": "physical", "power": 70, "accuracy": 1.0, "pp": 10}
|
||||||
|
{"name": "double kick", "type": "fighting", "category": "physical", "power": 30, "accuracy": 1.0, "pp": 30, "effects": ["Double Kick deals damage and will strike twice (with 30 base power each time).\nEach strike of Double Kick is treated like a separate attack:"], "changes": ["In Generations 1-3, Double Kick ends immediately if any hit breaks a Substitute.", "In Generation 1, each hit will always deal the same damage - if the first critical hits, so will the rest."]}
|
||||||
|
{"name": "double slap", "type": "normal", "category": "physical", "power": 15, "accuracy": 0.85, "pp": 10, "effects": [], "changes": ["In Generations 1-3, Double Slap ends immediately if any hit breaks a Substitute.", "In Generation 1, each hit will always deal the same damage - if the first critical hits, so will the rest.", "In Generations 1-5, this move's name was formatted as DoubleSlap."]}
|
||||||
|
{"name": "double team", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 15, "effect": {"stat": "evasiveness", "stages": 1}}
|
||||||
|
{"name": "double-edge", "type": "normal", "category": "physical", "power": 100, "accuracy": 1.0, "pp": 15, "effects": ["Double-Edge deals damage, but the user receives 1⁄3 of the damage it inflicted in recoil. In other words, if the attack does 90 HP damage to the opponent, the user will lose 30 HP."], "changes": ["In Generations 1-2, the recoil is 1⁄4 of the damage inflicted."]}
|
||||||
|
{"name": "dragon rage", "type": "dragon", "category": "special", "power": null, "accuracy": 1.0, "pp": 10, "effects": ["Dragon Rage always deals 40 HP damage to the target, regardless of typing. It has no additional effect."]}
|
||||||
|
{"name": "dream eater", "type": "psychic", "category": "special", "power": 100, "accuracy": 1.0, "pp": 15, "effects": ["Dream Eater deals damage only on sleeping foes and the user will recover 50% of the HP drained."]}
|
||||||
|
{"name": "drill peck", "type": "flying", "category": "physical", "power": 80, "accuracy": 1.0, "pp": 20}
|
||||||
|
{"name": "earthquake", "type": "ground", "category": "physical", "power": 100, "accuracy": 1.0, "pp": 10}
|
||||||
|
{"name": "egg bomb", "type": "normal", "category": "physical", "power": 100, "accuracy": 0.75, "pp": 10}
|
||||||
|
{"name": "ember", "type": "fire", "category": "special", "power": 40, "accuracy": 1.0, "pp": 25, "effect": {"chance": 0.1, "statusCondition": "burn"}}
|
||||||
|
{"name": "explosion", "type": "normal", "category": "physical", "power": 170, "accuracy": 1.0, "pp": 5, "effects": ["Explosion deals high damage, but causes the user to faint."], "changes": ["In Generations 1-4, the opponent's defense stat is temporarily halved when calculating the damage. This gives Explosion an effective power of 340."]}
|
||||||
|
{"name": "fire blast", "type": "fire", "category": "special", "power": 120, "accuracy": 0.85, "pp": 5, "effect": {"chance": 0.1, "statusCondition": "burn"}}
|
||||||
|
{"name": "fire punch", "type": "fire", "category": "physical", "power": 75, "accuracy": 1.0, "pp": 15, "effect": {"chance": 0.1, "statusCondition": "burn"}}
|
||||||
|
{"name": "fire spin", "type": "fire", "category": "special", "power": 35, "accuracy": 0.85, "pp": 15, "effects": ["Fire Spin inflicts damage on the first turn then traps the opponent, causing them to lose 1⁄16 of their maximum HP after each turn, for 4-5 turns. If the user holds a Grip Claw then it is always 5 turns."], "changes": ["In Generations 1-4, Fire Spin has a base power of 15 and 70% accuracy. Its after-effects last for 2-5 turns instead of 4-5.", "In Generation 1, Fire Spin simply inflicts its base power damage for 2-5 turns. While in effect, the target is unable to attack."]}
|
||||||
|
{"name": "fissure", "type": "ground", "category": "physical", "power": null, "accuracy": null, "pp": 5, "effects": ["If it hits, Fissure is guaranteed to make the opponent faint. It is more likely to hit Pokémon that are of a lower level than the user.", "Its accuracy (as a percentage) is calculated as below, ignoring all other accuracy and evasion modifiers:"], "changes": ["In Generation 1, Fissure has 30% accuracy and can hit Pokémon of any level, but does not affect Pokémon faster than the user."]}
|
||||||
|
{"name": "flamethrower", "type": "fire", "category": "special", "power": 95, "accuracy": 1.0, "pp": 15, "effect": {"chance": 0.1, "statusCondition": "burn"}}
|
||||||
|
{"name": "flash", "type": "normal", "category": "status", "power": null, "accuracy": 0.7, "pp": 20, "effect": {"stat": "accuracy", "stages": -1}}
|
||||||
|
{"name": "fly", "type": "flying", "category": "physical", "power": 70, "accuracy": 0.95, "pp": 15, "effects": ["The user of Fly will fly up high on the first turn, disappearing from view and becoming invulnerable to most attacks. On the second turn, Fly deals damage.", "While in the air, the Pokémon can only be hit by the moves Gust, Twister, Thunder, Sky Uppercut and Smack Down, with Gust and Twister dealing twice normal damage. Moves from No Guard Pokémon, or any move following an identify move can also hit for regular power."]}
|
||||||
|
{"name": "focus energy", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 30, "highCriticalHitRatio": true}
|
||||||
|
{"name": "fury attack", "type": "normal", "category": "physical", "power": 15, "accuracy": 0.85, "pp": 20, "effects": [], "changes": ["In Generations 1-3, Fury Attack ends immediately if any hit breaks a Substitute.", "In Generation 1, each hit will always deal the same damage - if the first critical hits, so will the rest."]}
|
||||||
|
{"name": "fury swipes", "type": "normal", "category": "physical", "power": 18, "accuracy": 0.8, "pp": 15, "effects": [], "changes": ["In Generations 1-3, Fury Swipes ends immediately if any hit breaks a Substitute.", "In Generation 1, each hit will always deal the same damage - if the first critical hits, so will the rest."]}
|
||||||
|
{"name": "glare", "type": "normal", "category": "status", "power": null, "accuracy": 0.75, "pp": 30, "effect": {"statusCondition": "paralysis"}}
|
||||||
|
{"name": "growl", "type": "normal", "category": "status", "power": null, "accuracy": 1.0, "pp": 40, "effect": {"stat": "attack", "stages": -1}}
|
||||||
|
{"name": "growth", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 40, "effect": {"stat": "special", "stages": 1}}
|
||||||
|
{"name": "guillotine", "type": "normal", "category": "physical", "power": null, "accuracy": null, "pp": 5, "effects": ["If it hits, Guillotine is guaranteed to make the opponent faint. It is more likely to hit Pokémon that are of a lower level than the user.", "Its accuracy (as a percentage) is calculated as below, ignoring all other accuracy and evasion modifiers:"], "changes": ["In Generation 1, Guillotine has 30% accuracy, but does not affect opponents faster than the user."]}
|
||||||
|
{"name": "gust", "type": "normal", "category": "special", "power": 40, "accuracy": 1.0, "pp": 35}
|
||||||
|
{"name": "harden", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 30, "effect": {"stat": "defense", "stages": 1}}
|
||||||
|
{"name": "haze", "type": "ice", "category": "status", "power": null, "accuracy": null, "pp": 30, "effects": ["Resets all stat changes."]}
|
||||||
|
{"name": "headbutt", "type": "normal", "category": "physical", "power": 70, "accuracy": 1.0, "pp": 15, "effect": {"chance": 0.3, "statusCondition": "flinch"}}
|
||||||
|
{"name": "high jump kick", "type": "fighting", "category": "physical", "power": 85, "accuracy": 0.9, "pp": 20, "effects": ["High Jump Kick deals damage, however, if it misses the user keeps going and crashes, losing 1⁄2 of its maximum HP. High Jump Kick cannot be used if Gravity is in effect."], "changes": ["In Generation 1, the crash damage is always 1 HP."]}
|
||||||
|
{"name": "horn attack", "type": "normal", "category": "physical", "power": 65, "accuracy": 1.0, "pp": 25}
|
||||||
|
{"name": "horn drill", "type": "normal", "category": "physical", "power": null, "accuracy": null, "pp": 5, "effects": ["If it hits, Horn Drill is guaranteed to make the opponent faint. It is more likely to hit Pokémon that are of a lower level than the user.", "Its accuracy (as a percentage) is calculated as below, ignoring all other accuracy and evasion modifiers:"], "changes": ["In Generation 1, Horn Drill has 30% accuracy, but does not affect opponents faster than the user."]}
|
||||||
|
{"name": "hydro pump", "type": "water", "category": "special", "power": 120, "accuracy": 0.8, "pp": 5}
|
||||||
|
{"name": "hyper beam", "type": "normal", "category": "special", "power": 150, "accuracy": 0.9, "pp": 5, "effects": ["Hyper Beam deals damage, but the user must recharge on the next turn (bringing its effective power down to 75 per turn)."], "changes": ["In Generation 1, if Hyper Beam KOs a Pokemon, it does not need to recharge."]}
|
||||||
|
{"name": "hyper fang", "type": "normal", "category": "physical", "power": 80, "accuracy": 0.9, "pp": 15, "effect": {"chance": 0.1, "statusCondition": "flinch"}}
|
||||||
|
{"name": "hypnosis", "type": "psychic", "category": "status", "power": null, "accuracy": 0.6, "pp": 20, "effect": {"statusCondition": "sleep"}}
|
||||||
|
{"name": "ice beam", "type": "ice", "category": "special", "power": 95, "accuracy": 1.0, "pp": 10, "effect": {"chance": 0.1, "statusCondition": "freeze"}}
|
||||||
|
{"name": "ice punch", "type": "ice", "category": "physical", "power": 75, "accuracy": 1.0, "pp": 15, "effect": {"chance": 0.1, "statusCondition": "freeze"}}
|
||||||
|
{"name": "jump kick", "type": "fighting", "category": "physical", "power": 70, "accuracy": 0.95, "pp": 25, "effects": ["Jump Kick deals damage, however, if it misses the user keeps going and crashes, losing 1⁄2 of its maximum HP. Jump Kick cannot be used if Gravity is in effect."], "changes": ["In Generation 1, the crash damage is always 1 HP. From Generation 2 to Generation 4, the crash damage is 1⁄8 of the damage the attack would have inflicted (which could be all of the user's own HP)."]}
|
||||||
|
{"name": "karate chop", "type": "normal", "category": "physical", "power": 50, "accuracy": 1.0, "pp": 25, "highCriticalHitRatio": true}
|
||||||
|
{"name": "kinesis", "type": "psychic", "category": "status", "power": null, "accuracy": 0.8, "pp": 15, "effect": {"stat": "accuracy", "stages": -1}}
|
||||||
|
{"name": "leech life", "type": "bug", "category": "physical", "power": 20, "accuracy": 1.0, "pp": 15, "effects": ["Leech Life deals damage and the user will recover 50% of the HP drained."]}
|
||||||
|
{"name": "leech seed", "type": "grass", "category": "status", "power": null, "accuracy": 0.9, "pp": 10, "effects": ["Leech Seed plants a seed on the target that drains 1⁄8 of its maximum HP at the end of each turn and restores it to the user, or any Pokemon that takes its place. It does not work on Grass-type Pokemon; it does technically work against Pokemon with the Magic Guard ability, but no HP will be sapped."], "changes": ["In Generation 1, Leech Seed saps 1⁄16 of the target's HP. If the target is also badly poisoned, the damage increases by 1⁄16 each turn, in the same way as bad poison (and in addition to poison damage).", "In Generation 1 and Generation 2 only, Haze will also clear the effects of Leech Seed."]}
|
||||||
|
{"name": "leer", "type": "normal", "category": "status", "power": null, "accuracy": 1.0, "pp": 30, "effect": {"stat": "defense", "stages": -1}}
|
||||||
|
{"name": "lick", "type": "ghost", "category": "physical", "power": 20, "accuracy": 1.0, "pp": 30, "effect": {"chance": 0.3, "statusCondition": "paralysis"}}
|
||||||
|
{"name": "light screen", "type": "psychic", "category": "status", "power": null, "accuracy": null, "pp": 30, "effects": ["Light Screen reduces damage from Special attacks by 50%, for 5 turns. Its effects apply to all Pokémon on the user's side of the field."]}
|
||||||
|
{"name": "lovely kiss", "type": "normal", "category": "status", "power": null, "accuracy": 0.75, "pp": 10, "effect": {"statusCondition": "sleep"}}
|
||||||
|
{"name": "low kick", "type": "fighting", "category": "physical", "power": 50, "accuracy": 0.9, "pp": 20, "effect": {"chance": 0.3, "statusCondition": "flinch"}}
|
||||||
|
{"name": "meditate", "type": "psychic", "category": "status", "power": null, "accuracy": null, "pp": 40, "effect": {"stat": "attack", "stages": 1}}
|
||||||
|
{"name": "mega drain", "type": "grass", "category": "special", "power": 40, "accuracy": 1.0, "pp": 10, "effects": ["Mega Drain deals damage and the user will recover 50% of the HP drained.", "If the user is holding a Big Root, the move instead recovers 65% of the damage dealt (30% more than normal). If used on a Pokemon with the ability Liquid Ooze, the user instead loses the HP it would have otherwise gained."]}
|
||||||
|
{"name": "mega kick", "type": "normal", "category": "physical", "power": 120, "accuracy": 0.75, "pp": 5}
|
||||||
|
{"name": "mega punch", "type": "normal", "category": "physical", "power": 80, "accuracy": 0.85, "pp": 20}
|
||||||
|
{"name": "metronome", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 10, "effects": ["User performs any move in the game at random."]}
|
||||||
|
{"name": "mimic", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 10, "effects": ["Mimic copies the last move used by the target (replacing Mimic). The copied move always has 5 PP. The effect only lasts while the user is in battle: if the user switches out or when the battle ends, the move becomes Mimic again.", "Mimic cannot copy Chatter, Metronome, Sketch or Struggle."], "changes": ["In Generation 1, Mimic allows the user to choose any of the opponent's moves to copy."]}
|
||||||
|
{"name": "minimize", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 20, "effect": {"stat": "evasiveness", "stages": 1}}
|
||||||
|
{"name": "mirror move", "type": "flying", "category": "status", "power": null, "accuracy": null, "pp": 20, "effects": ["User performs the opponent's last move."]}
|
||||||
|
{"name": "mist", "type": "ice", "category": "status", "power": null, "accuracy": null, "pp": 30, "effects": ["User's stats cannot be changed for a period of time."]}
|
||||||
|
{"name": "night shade", "type": "ghost", "category": "special", "power": null, "accuracy": 1.0, "pp": 15, "effects": ["The damage of Night Shade is equal to the user's level. So at level 100 the Pokémon will inflict 100 HP damage."], "changes": ["In Generation 1, Night Shade also hits Normal- and Psychic-type Pokémon despite their immunity to Ghost-type attacks."]}
|
||||||
|
{"name": "pay day", "type": "normal", "category": "physical", "power": 40, "accuracy": 1.0, "pp": 20}
|
||||||
|
{"name": "peck", "type": "flying", "category": "physical", "power": 35, "accuracy": 1.0, "pp": 35}
|
||||||
|
{"name": "petal dance", "type": "grass", "category": "special", "power": 120, "accuracy": 1.0, "pp": 10, "effects": ["The user of Petal Dance attacks for 2-3 turns, during which it cannot switch out, and then becomes confused. Confused Pokémon have a 50% chance of hurting themselves each turn, for 1-4 turns. The damage received is as if the Pokémon attacks itself with a typeless 40 base power Physical attack.", "If Petal Dance is disrupted (e.g. if the move misses or the user cannot attack due to paralysis) then it will stop and not cause confusion.", "Pokémon with the ability Own Tempo or those behind a Substitute cannot be confused."], "changes": ["In Generations 1-3 Petal Dance has a base power of 70. In Generation 4 its base power is 90.", "In Generations 1-4, Petal Dance has 20 PP. Furthermore, sleep, freezing and flinching will pause but not disrupt Petal Dance.", "In Generation 1, Petal Dance lasts for 3-4 turns."]}
|
||||||
|
{"name": "pin missile", "type": "bug", "category": "physical", "power": 14, "accuracy": 0.85, "pp": 20, "changes": ["In Generations 1-3, Pin Missile ends immediately if any hit breaks a Substitute.", "In Generation 1, each hit will always deal the same damage - if the first critical hits, so will the rest."]}
|
||||||
|
{"name": "poison gas", "type": "poison", "category": "status", "power": null, "accuracy": 0.55, "pp": 40, "effect": {"statusCondition": "poison"}}
|
||||||
|
{"name": "poison powder", "type": "poison", "category": "status", "power": null, "accuracy": 0.75, "pp": 35, "effect": {"statusCondition": "poison"}}
|
||||||
|
{"name": "poison sting", "type": "poison", "category": "physical", "power": 15, "accuracy": 1.0, "pp": 35, "effect": {"chance": 0.3, "statusCondition": "poison"}}
|
||||||
|
{"name": "pound", "type": "normal", "category": "physical", "power": 40, "accuracy": 1.0, "pp": 35}
|
||||||
|
{"name": "psybeam", "type": "psychic", "category": "special", "power": 65, "accuracy": 1.0, "pp": 20, "effect": {"chance": 0.1, "statusCondition": "confused"}}
|
||||||
|
{"name": "psychic", "type": "psychic", "category": "special", "power": 90, "accuracy": 1.0, "pp": 10, "effect": {"chance": 0.3, "stat": "special", "stages": -1}}
|
||||||
|
{"name": "psywave", "type": "psychic", "category": "special", "power": null, "accuracy": 0.8, "pp": 15, "effects": ["Psywave inflicts a random amount of HP damage, varying between 50% and 150% of the user's level. In other words, at level 100 the damage will be 50-150 HP.", "The damage is typeless (not affected by type advantages/disadvantages) but it still does not affect Dark type Pokemon."]}
|
||||||
|
{"name": "quick attack", "type": "normal", "category": "physical", "power": 40, "accuracy": 1.0, "pp": 30, "priority": 1}
|
||||||
|
{"name": "rage", "type": "normal", "category": "physical", "power": 20, "accuracy": 1.0, "pp": 20, "effects": ["Rage deals damage, and if the user is hit by a direct attack - any time after Rage is first used but before a different move is used - the user's Attack is raised by one stage. The game will state the Pokemon's rage is building rather than explicitly assert the stat increase. Stats can be raised to a maximum of +6 stages each.", "The Attack increases will continue as long as Rage is the last move used, even if it misses, the user is incapacitated (paralyzed, sleeping, etc) or the player uses an item. The Attack increase activates for every blow of multi-hit moves such as DoubleSlap or Fury Swipes.", "As an example, if a Pokemon uses Rage then the opponent hits the user in the same turn, the user's Attack increases. If the user moves last it will not increase that turn, but will in the next turn if the opponent hits the user again."], "changes": ["In Generation 1, after Rage is selected it will continue to be used until the end of the battle or the user faints.", "In Generations 2-3, if the user is slower than the opponent, the Attack rise only occurs if Rage is selected in that turn - if a different move is selected (or an item used) and the Pokemon is hit before it uses the new move, its Attack does not increase."]}
|
||||||
|
{"name": "razor leaf", "type": "grass", "category": "physical", "power": 55, "accuracy": 0.95, "pp": 25, "highCriticalHitRatio": true}
|
||||||
|
{"name": "razor wind", "type": "normal", "category": "special", "power": 80, "accuracy": 0.75, "pp": 10, "effects": ["The user of Razor Wind will whip up a whirlwind on the first turn. On the second turn, Razor Wind deals damage."]}
|
||||||
|
{"name": "recover", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 20, "effects": ["Recover restores up to 50% of the user's maximum HP."]}
|
||||||
|
{"name": "reflect", "type": "psychic", "category": "status", "power": null, "accuracy": null, "pp": 20, "effects": ["Reflect reduces damage from Physical attacks by 50%, for 5 turns. Its effects apply to all Pokémon on the user's side of the field."]}
|
||||||
|
{"name": "rest", "type": "psychic", "category": "status", "power": null, "accuracy": null, "pp": 10, "effects": ["User sleeps for 2 turns, but user is fully healed."]}
|
||||||
|
{"name": "roar", "type": "normal", "category": "status", "power": null, "accuracy": 1.0, "pp": 20}
|
||||||
|
{"name": "rock slide", "type": "rock", "category": "physical", "power": 75, "accuracy": 0.9, "pp": 10, "effect": {"chance": 0.3, "statusCondition": "flinch"}}
|
||||||
|
{"name": "rock throw", "type": "rock", "category": "physical", "power": 50, "accuracy": 0.65, "pp": 15}
|
||||||
|
{"name": "rolling kick", "type": "fighting", "category": "physical", "power": 60, "accuracy": 0.85, "pp": 15, "effect": {"chance": 0.3, "statusCondition": "flinch"}}
|
||||||
|
{"name": "sand attack", "type": "normal", "category": "status", "power": null, "accuracy": 1.0, "pp": 15, "effect": {"stat": "accuracy", "stages": -1}}
|
||||||
|
{"name": "scratch", "type": "normal", "category": "physical", "power": 40, "accuracy": 1.0, "pp": 35}
|
||||||
|
{"name": "screech", "type": "normal", "category": "status", "power": null, "accuracy": 0.85, "pp": 40, "effect": {"stat": "defense", "stages": -2}}
|
||||||
|
{"name": "seismic toss", "type": "fighting", "category": "physical", "power": null, "accuracy": 1.0, "pp": 20, "effects": ["The damage of Seismic Toss is equal to the user's level. So at level 100 the Pokémon will inflict 100 HP damage."], "changes": ["In Generation 1 Seismic Toss can hit Ghost-type Pokémon despite their immunity to Fighting-type attacks."]}
|
||||||
|
{"name": "self-destruct", "type": "normal", "category": "physical", "power": 200, "accuracy": 1.0, "pp": 5, "effects": ["Self-Destruct deals high damage, but causes the user to faint."]}
|
||||||
|
{"name": "sharpen", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 30, "effect": {"stat": "attack", "stages": 1}}
|
||||||
|
{"name": "sing", "type": "normal", "category": "status", "power": null, "accuracy": 0.55, "pp": 15, "effect": {"statusCondition": "sleep"}}
|
||||||
|
{"name": "skull bash", "type": "normal", "category": "physical", "power": 100, "accuracy": 1.0, "pp": 15, "effects": ["The user of Skull Bash will tuck in its head on the first turn and raise its Defense by one stage. On the second turn, Skull Bash deals damage."], "changes": ["In Generation 1, Skull Bash does not raise the user's Defense."]}
|
||||||
|
{"name": "sky attack", "type": "flying", "category": "physical", "power": 140, "accuracy": 0.9, "pp": 5, "effects": ["The user of Sky Attack will become cloaked in a harsh light on the first turn. On the second turn, Sky Attack deals damage."]}
|
||||||
|
{"name": "slam", "type": "normal", "category": "physical", "power": 80, "accuracy": 0.75, "pp": 20}
|
||||||
|
{"name": "slash", "type": "normal", "category": "physical", "power": 70, "accuracy": 1.0, "pp": 20, "highCriticalHitRatio": true}
|
||||||
|
{"name": "sleep powder", "type": "grass", "category": "status", "power": null, "accuracy": 0.75, "pp": 15, "effect": {"statusCondition": "sleep"}}
|
||||||
|
{"name": "sludge", "type": "poison", "category": "special", "power": 65, "accuracy": 1.0, "pp": 20, "effect": {"chance": 0.3, "statusCondition": "poison"}}
|
||||||
|
{"name": "smog", "type": "poison", "category": "special", "power": 20, "accuracy": 0.7, "pp": 20, "effect": {"chance": 0.4, "statusCondition": "poison"}}
|
||||||
|
{"name": "smokescreen", "type": "normal", "category": "status", "power": null, "accuracy": 1.0, "pp": 20, "effect": {"stat": "accuracy", "stages": -1}}
|
||||||
|
{"name": "soft-boiled", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 10, "effects": ["Soft-Boiled recovers up to 50% of the user's maximum HP."]}
|
||||||
|
{"name": "solar beam", "type": "grass", "category": "special", "power": 120, "accuracy": 1.0, "pp": 10, "effects": ["The user of Solar Beam will absorb light on the first turn. On the second turn, Solar Beam deals damage."]}
|
||||||
|
{"name": "sonic boom", "type": "normal", "category": "special", "power": null, "accuracy": 0.9, "pp": 20, "effects": ["Sonic Boom always deals 20 HP damage to the target, regardless of typing (although Ghost type Pokémon are still immune). It has no additional effect."], "changes": ["In Generation 1, Sonic Boom hits Ghost types regardless of their immunity to Normal type moves."]}
|
||||||
|
{"name": "spike cannon", "type": "normal", "category": "physical", "power": 20, "accuracy": 1.0, "pp": 15, "effects": [], "changes": ["In Generations 1-3, Spike Cannon ends immediately if any hit breaks a Substitute.", "In Generation 1, each hit will always deal the same damage - if the first critical hits, so will the rest."]}
|
||||||
|
{"name": "splash", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 40}
|
||||||
|
{"name": "spore", "type": "grass", "category": "status", "power": null, "accuracy": 1.0, "pp": 15, "effect": {"statusCondition": "sleep"}}
|
||||||
|
{"name": "stomp", "type": "normal", "category": "physical", "power": 65, "accuracy": 1.0, "pp": 20, "effect": {"chance": 0.3, "statusCondition": "flinch"}}
|
||||||
|
{"name": "strength", "type": "normal", "category": "physical", "power": 80, "accuracy": 1.0, "pp": 15}
|
||||||
|
{"name": "string shot", "type": "bug", "category": "status", "power": null, "accuracy": 0.95, "pp": 40, "effect": {"stat": "speed", "stages": -1}}
|
||||||
|
{"name": "struggle", "type": "normal", "category": "physical", "power": 50, "accuracy": 1.0, "pp": null, "effects": ["Only usable when all PP are gone. Hurts the user."]}
|
||||||
|
{"name": "stun spore", "type": "grass", "category": "status", "power": null, "accuracy": 0.75, "pp": 30, "effect": {"statusCondition": "paralysis"}}
|
||||||
|
{"name": "submission", "type": "fighting", "category": "physical", "power": 80, "accuracy": 0.8, "pp": 25, "effects": ["Submission deals damage, but the user receives 1⁄4 of the damage it inflicts in recoil. In other words, if the attack does 100 HP damage to the opponent, the user will lose 25 HP."]}
|
||||||
|
{"name": "substitute", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 10, "effects": ["Uses HP to creates a decoy that takes hits."]}
|
||||||
|
{"name": "super fang", "type": "normal", "category": "physical", "power": null, "accuracy": 0.9, "pp": 10, "effects": ["Always takes off half of the opponent's HP."]}
|
||||||
|
{"name": "supersonic", "type": "normal", "category": "status", "power": null, "accuracy": 0.55, "pp": 20, "effect": {"statusCondition": "confused"}}
|
||||||
|
{"name": "surf", "type": "water", "category": "special", "power": 95, "accuracy": 1.0, "pp": 15}
|
||||||
|
{"name": "swift", "type": "normal", "category": "special", "power": 60, "accuracy": null, "pp": 20, "changes": ["In Generation 1, Swift can hit Pokémon during the invulnerable stage of Dig and Fly."]}
|
||||||
|
{"name": "swords dance", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 30, "effect": {"stat": "attack", "stages": 2}}
|
||||||
|
{"name": "tackle", "type": "normal", "category": "physical", "power": 35, "accuracy": 0.95, "pp": 35}
|
||||||
|
{"name": "tail whip", "type": "normal", "category": "status", "power": null, "accuracy": 1.0, "pp": 30, "effect": {"stat": "defense", "stages": -1}}
|
||||||
|
{"name": "take down", "type": "normal", "category": "physical", "power": 90, "accuracy": 0.85, "pp": 20, "effects": ["Take Down deals damage, but the user receives 1⁄4 of the damage it inflicted in recoil. In other words, if the attack does 100 HP damage to the opponent, the user will lose 25 HP."]}
|
||||||
|
{"name": "teleport", "type": "psychic", "category": "status", "power": null, "accuracy": null, "pp": 20}
|
||||||
|
{"name": "thrash", "type": "normal", "category": "physical", "power": 120, "accuracy": 1.0, "pp": 10, "effects": ["The user of Thrash attacks for 2-3 turns, during which it cannot switch out, and then becomes confused. Confused Pokémon have a 50% chance of hurting themselves each turn, for 1-4 turns. The damage received is as if the Pokémon attacks itself with a typeless 40 base power Physical attack.", "If Thrash is disrupted (e.g. if the move misses or the user cannot attack due to paralysis) then it will stop and not cause confusion.", "Pokémon with the ability Own Tempo or those behind a Substitute cannot be confused."], "changes": ["In Generations 1-4, Thrash has 20 PP and a base power of 90. Furthermore, sleep, freezing and flinching will pause but not disrupt Thrash.", "In Generation 1, Thrash lasts for 3-4 turns."]}
|
||||||
|
{"name": "thunder", "type": "electric", "category": "special", "power": 120, "accuracy": 0.7, "pp": 10, "effect": {"chance": 0.1, "statusCondition": "paralysis"}}
|
||||||
|
{"name": "thunder punch", "type": "electric", "category": "physical", "power": 75, "accuracy": 1.0, "pp": 15, "effect": {"chance": 0.1, "statusCondition": "paralysis"}}
|
||||||
|
{"name": "thunder shock", "type": "electric", "category": "special", "power": 40, "accuracy": 1.0, "pp": 30, "effect": {"chance": 0.1, "statusCondition": "paralysis"}}
|
||||||
|
{"name": "thunder wave", "type": "electric", "category": "status", "power": null, "accuracy": 1.0, "pp": 20, "effect": {"statusCondition": "paralysis"}}
|
||||||
|
{"name": "thunderbolt", "type": "electric", "category": "special", "power": 95, "accuracy": 1.0, "pp": 15, "effect": {"chance": 0.1, "statusCondition": "paralysis"}}
|
||||||
|
{"name": "toxic", "type": "poison", "category": "status", "power": null, "accuracy": 0.85, "pp": 10, "changes": ["In Generation 1, Toxic also increases the damage taken by Leech Seed."], "effect": {"statusCondition": "badly poison"}}
|
||||||
|
{"name": "transform", "type": "normal", "category": "status", "power": null, "accuracy": null, "pp": 10, "effects": ["User takes on the form and attacks of the opponent."]}
|
||||||
|
{"name": "tri attack", "type": "normal", "category": "special", "power": 80, "accuracy": 1.0, "pp": 10}
|
||||||
|
{"name": "twineedle", "type": "bug", "category": "physical", "power": 25, "accuracy": 1.0, "pp": 20, "effects": ["Twineedle deals damage and will strike twice (with 25 base power each time). It has a 20% chance of poisoning the target. Poison or Steel type Pokémon, those with the ability Immunity or those behind a Substitute cannot be poisoned.\nEach strike of Twineedle is treated like a separate attack:"], "changes": ["In Generations 1-2, Twineedle can poison Poison and Steel types.\nIn Generations 2-4, if a Focus Sash or Focus Band activates before the final hit, subsequent hits do not cause the holder to faint.", "In Generations 1-3, Twineedle ends immediately if any hit breaks a Substitute.", "In Generation 1, each hit will always deal the same damage - if the first critical hits, so will the rest."]}
|
||||||
|
{"name": "vice grip", "type": "normal", "category": "physical", "power": 55, "accuracy": 1.0, "pp": 30}
|
||||||
|
{"name": "vine whip", "type": "grass", "category": "physical", "power": 35, "accuracy": 1.0, "pp": 10}
|
||||||
|
{"name": "water gun", "type": "water", "category": "special", "power": 40, "accuracy": 1.0, "pp": 25}
|
||||||
|
{"name": "waterfall", "type": "water", "category": "physical", "power": 80, "accuracy": 1.0, "pp": 15}
|
||||||
|
{"name": "whirlwind", "type": "normal", "category": "status", "power": null, "accuracy": 0.85, "pp": 20}
|
||||||
|
{"name": "wing attack", "type": "flying", "category": "physical", "power": 35, "accuracy": 1.0, "pp": 35}
|
||||||
|
{"name": "withdraw", "type": "water", "category": "status", "power": null, "accuracy": null, "pp": 40, "effect": {"stat": "defense", "stages": 1}}
|
||||||
|
{"name": "wrap", "type": "normal", "category": "physical", "power": 15, "accuracy": 0.9, "pp": 20, "effects": ["Wrap inflicts damage on the first turn then traps the opponent, causing them to lose 1⁄16 of their maximum HP after each turn, for 4-5 turns. If the user holds a Grip Claw then it is always 5 turns."], "changes": ["In Generations 1-4, Wrap has 85% accuracy. Its after-effects last for 2-5 turns instead of 4-5.", "In Generation 1, Wrap simply inflicts its base power damage for 2-5 turns. While in effect, the target is unable to attack."]}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,151 @@
|
|||||||
|
{"national_pokedex_number": 63, "name": "abra", "types": ["psychic"], "baseStats": {"hp": 25, "attack": 20, "defense": 15, "speed": 90, "special": 105}}
|
||||||
|
{"national_pokedex_number": 142, "name": "aerodactyl", "types": ["rock", "flying"], "baseStats": {"hp": 80, "attack": 105, "defense": 65, "speed": 130, "special": 60}}
|
||||||
|
{"national_pokedex_number": 65, "name": "alakazam", "types": ["psychic"], "baseStats": {"hp": 55, "attack": 50, "defense": 45, "speed": 120, "special": 135}}
|
||||||
|
{"national_pokedex_number": 24, "name": "arbok", "types": ["poison"], "baseStats": {"hp": 60, "attack": 85, "defense": 69, "speed": 80, "special": 65}}
|
||||||
|
{"national_pokedex_number": 59, "name": "arcanine", "types": ["fire"], "baseStats": {"hp": 90, "attack": 110, "defense": 80, "speed": 95, "special": 80}}
|
||||||
|
{"national_pokedex_number": 144, "name": "articuno", "types": ["ice", "flying"], "baseStats": {"hp": 90, "attack": 85, "defense": 100, "speed": 85, "special": 125}}
|
||||||
|
{"national_pokedex_number": 15, "name": "beedrill", "types": ["bug", "poison"], "baseStats": {"hp": 65, "attack": 80, "defense": 40, "speed": 75, "special": 45}}
|
||||||
|
{"national_pokedex_number": 69, "name": "bellsprout", "types": ["grass", "poison"], "baseStats": {"hp": 50, "attack": 75, "defense": 35, "speed": 40, "special": 70}}
|
||||||
|
{"national_pokedex_number": 9, "name": "blastoise", "types": ["water"], "baseStats": {"hp": 79, "attack": 83, "defense": 100, "speed": 78, "special": 85}}
|
||||||
|
{"national_pokedex_number": 1, "name": "bulbasaur", "types": ["grass", "poison"], "baseStats": {"hp": 45, "attack": 49, "defense": 49, "speed": 45, "special": 65}}
|
||||||
|
{"national_pokedex_number": 12, "name": "butterfree", "types": ["bug", "flying"], "baseStats": {"hp": 60, "attack": 45, "defense": 50, "speed": 70, "special": 80}}
|
||||||
|
{"national_pokedex_number": 10, "name": "caterpie", "types": ["bug"], "baseStats": {"hp": 45, "attack": 30, "defense": 35, "speed": 45, "special": 20}}
|
||||||
|
{"national_pokedex_number": 113, "name": "chansey", "types": ["normal"], "baseStats": {"hp": 250, "attack": 5, "defense": 5, "speed": 50, "special": 105}}
|
||||||
|
{"national_pokedex_number": 6, "name": "charizard", "types": ["fire", "flying"], "baseStats": {"hp": 78, "attack": 84, "defense": 78, "speed": 100, "special": 85}}
|
||||||
|
{"national_pokedex_number": 4, "name": "charmander", "types": ["fire"], "baseStats": {"hp": 39, "attack": 52, "defense": 43, "speed": 65, "special": 50}}
|
||||||
|
{"national_pokedex_number": 5, "name": "charmeleon", "types": ["fire"], "baseStats": {"hp": 58, "attack": 64, "defense": 58, "speed": 80, "special": 65}}
|
||||||
|
{"national_pokedex_number": 36, "name": "clefable", "types": ["fairy"], "baseStats": {"hp": 95, "attack": 70, "defense": 73, "speed": 60, "special": 85}}
|
||||||
|
{"national_pokedex_number": 35, "name": "clefairy", "types": ["fairy"], "baseStats": {"hp": 70, "attack": 45, "defense": 48, "speed": 35, "special": 60}}
|
||||||
|
{"national_pokedex_number": 91, "name": "cloyster", "types": ["water", "ice"], "baseStats": {"hp": 50, "attack": 95, "defense": 180, "speed": 70, "special": 85}}
|
||||||
|
{"national_pokedex_number": 104, "name": "cubone", "types": ["ground"], "baseStats": {"hp": 50, "attack": 50, "defense": 95, "speed": 35, "special": 40}}
|
||||||
|
{"national_pokedex_number": 87, "name": "dewgong", "types": ["water", "ice"], "baseStats": {"hp": 90, "attack": 70, "defense": 80, "speed": 70, "special": 95}}
|
||||||
|
{"national_pokedex_number": 50, "name": "diglett", "types": ["ground"], "baseStats": {"hp": 10, "attack": 55, "defense": 25, "speed": 95, "special": 45}}
|
||||||
|
{"national_pokedex_number": 132, "name": "ditto", "types": ["normal"], "baseStats": {"hp": 48, "attack": 48, "defense": 48, "speed": 48, "special": 48}}
|
||||||
|
{"national_pokedex_number": 85, "name": "dodrio", "types": ["normal", "flying"], "baseStats": {"hp": 60, "attack": 110, "defense": 70, "speed": 100, "special": 60}}
|
||||||
|
{"national_pokedex_number": 84, "name": "doduo", "types": ["normal", "flying"], "baseStats": {"hp": 35, "attack": 85, "defense": 45, "speed": 75, "special": 35}}
|
||||||
|
{"national_pokedex_number": 148, "name": "dragonair", "types": ["dragon"], "baseStats": {"hp": 61, "attack": 84, "defense": 65, "speed": 70, "special": 70}}
|
||||||
|
{"national_pokedex_number": 149, "name": "dragonite", "types": ["dragon", "flying"], "baseStats": {"hp": 91, "attack": 134, "defense": 95, "speed": 80, "special": 100}}
|
||||||
|
{"national_pokedex_number": 147, "name": "dratini", "types": ["dragon"], "baseStats": {"hp": 41, "attack": 64, "defense": 45, "speed": 50, "special": 50}}
|
||||||
|
{"national_pokedex_number": 96, "name": "drowzee", "types": ["psychic"], "baseStats": {"hp": 60, "attack": 48, "defense": 45, "speed": 42, "special": 90}}
|
||||||
|
{"national_pokedex_number": 51, "name": "dugtrio", "types": ["ground"], "baseStats": {"hp": 35, "attack": 80, "defense": 50, "speed": 120, "special": 70}}
|
||||||
|
{"national_pokedex_number": 133, "name": "eevee", "types": ["normal"], "baseStats": {"hp": 55, "attack": 55, "defense": 50, "speed": 55, "special": 65}}
|
||||||
|
{"national_pokedex_number": 23, "name": "ekans", "types": ["poison"], "baseStats": {"hp": 35, "attack": 60, "defense": 44, "speed": 55, "special": 40}}
|
||||||
|
{"national_pokedex_number": 125, "name": "electabuzz", "types": ["electric"], "baseStats": {"hp": 65, "attack": 83, "defense": 57, "speed": 105, "special": 85}}
|
||||||
|
{"national_pokedex_number": 101, "name": "electrode", "types": ["electric"], "baseStats": {"hp": 60, "attack": 50, "defense": 70, "speed": 140, "special": 80}}
|
||||||
|
{"national_pokedex_number": 102, "name": "exeggcute", "types": ["grass", "psychic"], "baseStats": {"hp": 60, "attack": 40, "defense": 80, "speed": 40, "special": 60}}
|
||||||
|
{"national_pokedex_number": 103, "name": "exeggutor", "types": ["grass", "psychic"], "baseStats": {"hp": 95, "attack": 95, "defense": 85, "speed": 55, "special": 125}}
|
||||||
|
{"national_pokedex_number": 83, "name": "farfetch'd", "types": ["normal", "flying"], "baseStats": {"hp": 52, "attack": 65, "defense": 55, "speed": 60, "special": 58}}
|
||||||
|
{"national_pokedex_number": 22, "name": "fearow", "types": ["normal", "flying"], "baseStats": {"hp": 65, "attack": 90, "defense": 65, "speed": 100, "special": 61}}
|
||||||
|
{"national_pokedex_number": 136, "name": "flareon", "types": ["fire"], "baseStats": {"hp": 65, "attack": 130, "defense": 60, "speed": 65, "special": 110}}
|
||||||
|
{"national_pokedex_number": 92, "name": "gastly", "types": ["ghost", "poison"], "baseStats": {"hp": 30, "attack": 35, "defense": 30, "speed": 80, "special": 100}}
|
||||||
|
{"national_pokedex_number": 94, "name": "gengar", "types": ["ghost", "poison"], "baseStats": {"hp": 60, "attack": 65, "defense": 60, "speed": 110, "special": 130}}
|
||||||
|
{"national_pokedex_number": 74, "name": "geodude", "types": ["rock", "ground"], "baseStats": {"hp": 40, "attack": 80, "defense": 100, "speed": 20, "special": 30}}
|
||||||
|
{"national_pokedex_number": 44, "name": "gloom", "types": ["grass", "poison"], "baseStats": {"hp": 60, "attack": 65, "defense": 70, "speed": 40, "special": 85}}
|
||||||
|
{"national_pokedex_number": 42, "name": "golbat", "types": ["poison", "flying"], "baseStats": {"hp": 75, "attack": 80, "defense": 70, "speed": 90, "special": 75}}
|
||||||
|
{"national_pokedex_number": 118, "name": "goldeen", "types": ["water"], "baseStats": {"hp": 45, "attack": 67, "defense": 60, "speed": 63, "special": 50}}
|
||||||
|
{"national_pokedex_number": 55, "name": "golduck", "types": ["water"], "baseStats": {"hp": 80, "attack": 82, "defense": 78, "speed": 85, "special": 80}}
|
||||||
|
{"national_pokedex_number": 76, "name": "golem", "types": ["rock", "ground"], "baseStats": {"hp": 80, "attack": 110, "defense": 130, "speed": 45, "special": 55}}
|
||||||
|
{"national_pokedex_number": 75, "name": "graveler", "types": ["rock", "ground"], "baseStats": {"hp": 55, "attack": 95, "defense": 115, "speed": 35, "special": 45}}
|
||||||
|
{"national_pokedex_number": 88, "name": "grimer", "types": ["poison"], "baseStats": {"hp": 80, "attack": 80, "defense": 50, "speed": 25, "special": 40}}
|
||||||
|
{"national_pokedex_number": 58, "name": "growlithe", "types": ["fire"], "baseStats": {"hp": 55, "attack": 70, "defense": 45, "speed": 60, "special": 50}}
|
||||||
|
{"national_pokedex_number": 130, "name": "gyarados", "types": ["water", "flying"], "baseStats": {"hp": 95, "attack": 125, "defense": 79, "speed": 81, "special": 100}}
|
||||||
|
{"national_pokedex_number": 93, "name": "haunter", "types": ["ghost", "poison"], "baseStats": {"hp": 45, "attack": 50, "defense": 45, "speed": 95, "special": 115}}
|
||||||
|
{"national_pokedex_number": 107, "name": "hitmonchan", "types": ["fighting"], "baseStats": {"hp": 50, "attack": 105, "defense": 79, "speed": 76, "special": 35}}
|
||||||
|
{"national_pokedex_number": 106, "name": "hitmonlee", "types": ["fighting"], "baseStats": {"hp": 50, "attack": 120, "defense": 53, "speed": 87, "special": 35}}
|
||||||
|
{"national_pokedex_number": 116, "name": "horsea", "types": ["water"], "baseStats": {"hp": 30, "attack": 40, "defense": 70, "speed": 60, "special": 70}}
|
||||||
|
{"national_pokedex_number": 97, "name": "hypno", "types": ["psychic"], "baseStats": {"hp": 85, "attack": 73, "defense": 70, "speed": 67, "special": 115}}
|
||||||
|
{"national_pokedex_number": 2, "name": "ivysaur", "types": ["grass", "poison"], "baseStats": {"hp": 60, "attack": 62, "defense": 63, "speed": 60, "special": 80}}
|
||||||
|
{"national_pokedex_number": 39, "name": "jigglypuff", "types": ["normal", "fairy"], "baseStats": {"hp": 115, "attack": 45, "defense": 20, "speed": 20, "special": 25}}
|
||||||
|
{"national_pokedex_number": 135, "name": "jolteon", "types": ["electric"], "baseStats": {"hp": 65, "attack": 65, "defense": 60, "speed": 130, "special": 110}}
|
||||||
|
{"national_pokedex_number": 124, "name": "jynx", "types": ["ice", "psychic"], "baseStats": {"hp": 65, "attack": 50, "defense": 35, "speed": 95, "special": 95}}
|
||||||
|
{"national_pokedex_number": 140, "name": "kabuto", "types": ["rock", "water"], "baseStats": {"hp": 30, "attack": 80, "defense": 90, "speed": 55, "special": 45}}
|
||||||
|
{"national_pokedex_number": 141, "name": "kabutops", "types": ["rock", "water"], "baseStats": {"hp": 60, "attack": 115, "defense": 105, "speed": 80, "special": 70}}
|
||||||
|
{"national_pokedex_number": 64, "name": "kadabra", "types": ["psychic"], "baseStats": {"hp": 40, "attack": 35, "defense": 30, "speed": 105, "special": 120}}
|
||||||
|
{"national_pokedex_number": 14, "name": "kakuna", "types": ["bug", "poison"], "baseStats": {"hp": 45, "attack": 25, "defense": 50, "speed": 35, "special": 25}}
|
||||||
|
{"national_pokedex_number": 115, "name": "kangaskhan", "types": ["normal"], "baseStats": {"hp": 105, "attack": 95, "defense": 80, "speed": 90, "special": 40}}
|
||||||
|
{"national_pokedex_number": 99, "name": "kingler", "types": ["water"], "baseStats": {"hp": 55, "attack": 130, "defense": 115, "speed": 75, "special": 50}}
|
||||||
|
{"national_pokedex_number": 109, "name": "koffing", "types": ["poison"], "baseStats": {"hp": 40, "attack": 65, "defense": 95, "speed": 35, "special": 60}}
|
||||||
|
{"national_pokedex_number": 98, "name": "krabby", "types": ["water"], "baseStats": {"hp": 30, "attack": 105, "defense": 90, "speed": 50, "special": 25}}
|
||||||
|
{"national_pokedex_number": 131, "name": "lapras", "types": ["water", "ice"], "baseStats": {"hp": 130, "attack": 85, "defense": 80, "speed": 60, "special": 95}}
|
||||||
|
{"national_pokedex_number": 108, "name": "lickitung", "types": ["normal"], "baseStats": {"hp": 90, "attack": 55, "defense": 75, "speed": 30, "special": 60}}
|
||||||
|
{"national_pokedex_number": 68, "name": "machamp", "types": ["fighting"], "baseStats": {"hp": 90, "attack": 130, "defense": 80, "speed": 55, "special": 65}}
|
||||||
|
{"national_pokedex_number": 67, "name": "machoke", "types": ["fighting"], "baseStats": {"hp": 80, "attack": 100, "defense": 70, "speed": 45, "special": 50}}
|
||||||
|
{"national_pokedex_number": 66, "name": "machop", "types": ["fighting"], "baseStats": {"hp": 70, "attack": 80, "defense": 50, "speed": 35, "special": 35}}
|
||||||
|
{"national_pokedex_number": 129, "name": "magikarp", "types": ["water"], "baseStats": {"hp": 20, "attack": 10, "defense": 55, "speed": 80, "special": 20}}
|
||||||
|
{"national_pokedex_number": 126, "name": "magmar", "types": ["fire"], "baseStats": {"hp": 65, "attack": 95, "defense": 57, "speed": 93, "special": 85}}
|
||||||
|
{"national_pokedex_number": 81, "name": "magnemite", "types": ["electric", "steel"], "baseStats": {"hp": 25, "attack": 35, "defense": 70, "speed": 45, "special": 95}}
|
||||||
|
{"national_pokedex_number": 82, "name": "magneton", "types": ["electric", "steel"], "baseStats": {"hp": 50, "attack": 60, "defense": 95, "speed": 70, "special": 120}}
|
||||||
|
{"national_pokedex_number": 56, "name": "mankey", "types": ["fighting"], "baseStats": {"hp": 40, "attack": 80, "defense": 35, "speed": 70, "special": 35}}
|
||||||
|
{"national_pokedex_number": 105, "name": "marowak", "types": ["ground"], "baseStats": {"hp": 60, "attack": 80, "defense": 110, "speed": 45, "special": 50}}
|
||||||
|
{"national_pokedex_number": 52, "name": "meowth", "types": ["normal"], "baseStats": {"hp": 40, "attack": 45, "defense": 35, "speed": 90, "special": 40}}
|
||||||
|
{"national_pokedex_number": 11, "name": "metapod", "types": ["bug"], "baseStats": {"hp": 50, "attack": 20, "defense": 55, "speed": 30, "special": 25}}
|
||||||
|
{"national_pokedex_number": 151, "name": "mew", "types": ["psychic"], "baseStats": {"hp": 100, "attack": 100, "defense": 100, "speed": 100, "special": 100}}
|
||||||
|
{"national_pokedex_number": 150, "name": "mewtwo", "types": ["psychic"], "baseStats": {"hp": 106, "attack": 110, "defense": 90, "speed": 130, "special": 154}}
|
||||||
|
{"national_pokedex_number": 146, "name": "moltres", "types": ["fire", "flying"], "baseStats": {"hp": 90, "attack": 100, "defense": 90, "speed": 90, "special": 125}}
|
||||||
|
{"national_pokedex_number": 122, "name": "mr. mime", "types": ["psychic", "fairy"], "baseStats": {"hp": 40, "attack": 45, "defense": 65, "speed": 90, "special": 100}}
|
||||||
|
{"national_pokedex_number": 89, "name": "muk", "types": ["poison"], "baseStats": {"hp": 105, "attack": 105, "defense": 75, "speed": 50, "special": 65}}
|
||||||
|
{"national_pokedex_number": 34, "name": "nidoking", "types": ["poison", "ground"], "baseStats": {"hp": 81, "attack": 92, "defense": 77, "speed": 85, "special": 75}}
|
||||||
|
{"national_pokedex_number": 31, "name": "nidoqueen", "types": ["poison", "ground"], "baseStats": {"hp": 90, "attack": 82, "defense": 87, "speed": 76, "special": 75}}
|
||||||
|
{"national_pokedex_number": 29, "name": "nidoran♀", "types": ["poison"], "baseStats": {"hp": 55, "attack": 47, "defense": 52, "speed": 41, "special": 40}}
|
||||||
|
{"national_pokedex_number": 32, "name": "nidoran♂", "types": ["poison"], "baseStats": {"hp": 46, "attack": 57, "defense": 40, "speed": 50, "special": 40}}
|
||||||
|
{"national_pokedex_number": 30, "name": "nidorina", "types": ["poison"], "baseStats": {"hp": 70, "attack": 62, "defense": 67, "speed": 56, "special": 55}}
|
||||||
|
{"national_pokedex_number": 33, "name": "nidorino", "types": ["poison"], "baseStats": {"hp": 61, "attack": 72, "defense": 57, "speed": 65, "special": 55}}
|
||||||
|
{"national_pokedex_number": 38, "name": "ninetales", "types": ["fire"], "baseStats": {"hp": 73, "attack": 76, "defense": 75, "speed": 100, "special": 100}}
|
||||||
|
{"national_pokedex_number": 43, "name": "oddish", "types": ["grass", "poison"], "baseStats": {"hp": 45, "attack": 50, "defense": 55, "speed": 30, "special": 75}}
|
||||||
|
{"national_pokedex_number": 138, "name": "omanyte", "types": ["rock", "water"], "baseStats": {"hp": 35, "attack": 40, "defense": 100, "speed": 35, "special": 90}}
|
||||||
|
{"national_pokedex_number": 139, "name": "omastar", "types": ["rock", "water"], "baseStats": {"hp": 70, "attack": 60, "defense": 125, "speed": 55, "special": 115}}
|
||||||
|
{"national_pokedex_number": 95, "name": "onix", "types": ["rock", "ground"], "baseStats": {"hp": 35, "attack": 45, "defense": 160, "speed": 70, "special": 30}}
|
||||||
|
{"national_pokedex_number": 46, "name": "paras", "types": ["bug", "grass"], "baseStats": {"hp": 35, "attack": 70, "defense": 55, "speed": 25, "special": 55}}
|
||||||
|
{"national_pokedex_number": 47, "name": "parasect", "types": ["bug", "grass"], "baseStats": {"hp": 60, "attack": 95, "defense": 80, "speed": 30, "special": 80}}
|
||||||
|
{"national_pokedex_number": 53, "name": "persian", "types": ["normal"], "baseStats": {"hp": 65, "attack": 70, "defense": 60, "speed": 115, "special": 65}}
|
||||||
|
{"national_pokedex_number": 18, "name": "pidgeot", "types": ["normal", "flying"], "baseStats": {"hp": 83, "attack": 80, "defense": 75, "speed": 91, "special": 70}}
|
||||||
|
{"national_pokedex_number": 17, "name": "pidgeotto", "types": ["normal", "flying"], "baseStats": {"hp": 63, "attack": 60, "defense": 55, "speed": 71, "special": 50}}
|
||||||
|
{"national_pokedex_number": 16, "name": "pidgey", "types": ["normal", "flying"], "baseStats": {"hp": 40, "attack": 45, "defense": 40, "speed": 56, "special": 35}}
|
||||||
|
{"national_pokedex_number": 25, "name": "pikachu", "types": ["electric"], "baseStats": {"hp": 35, "attack": 55, "defense": 30, "speed": 90, "special": 50}}
|
||||||
|
{"national_pokedex_number": 127, "name": "pinsir", "types": ["bug"], "baseStats": {"hp": 65, "attack": 125, "defense": 100, "speed": 85, "special": 55}}
|
||||||
|
{"national_pokedex_number": 60, "name": "poliwag", "types": ["water"], "baseStats": {"hp": 40, "attack": 50, "defense": 40, "speed": 90, "special": 40}}
|
||||||
|
{"national_pokedex_number": 61, "name": "poliwhirl", "types": ["water"], "baseStats": {"hp": 65, "attack": 65, "defense": 65, "speed": 90, "special": 50}}
|
||||||
|
{"national_pokedex_number": 62, "name": "poliwrath", "types": ["water", "fighting"], "baseStats": {"hp": 90, "attack": 85, "defense": 95, "speed": 70, "special": 70}}
|
||||||
|
{"national_pokedex_number": 77, "name": "ponyta", "types": ["fire"], "baseStats": {"hp": 50, "attack": 85, "defense": 55, "speed": 90, "special": 65}}
|
||||||
|
{"national_pokedex_number": 137, "name": "porygon", "types": ["normal"], "baseStats": {"hp": 65, "attack": 60, "defense": 70, "speed": 40, "special": 75}}
|
||||||
|
{"national_pokedex_number": 57, "name": "primeape", "types": ["fighting"], "baseStats": {"hp": 65, "attack": 105, "defense": 60, "speed": 95, "special": 60}}
|
||||||
|
{"national_pokedex_number": 54, "name": "psyduck", "types": ["water"], "baseStats": {"hp": 50, "attack": 52, "defense": 48, "speed": 55, "special": 50}}
|
||||||
|
{"national_pokedex_number": 26, "name": "raichu", "types": ["electric"], "baseStats": {"hp": 60, "attack": 90, "defense": 55, "speed": 100, "special": 90}}
|
||||||
|
{"national_pokedex_number": 78, "name": "rapidash", "types": ["fire"], "baseStats": {"hp": 65, "attack": 100, "defense": 70, "speed": 105, "special": 80}}
|
||||||
|
{"national_pokedex_number": 20, "name": "raticate", "types": ["normal"], "baseStats": {"hp": 55, "attack": 81, "defense": 60, "speed": 97, "special": 50}}
|
||||||
|
{"national_pokedex_number": 19, "name": "rattata", "types": ["normal"], "baseStats": {"hp": 30, "attack": 56, "defense": 35, "speed": 72, "special": 25}}
|
||||||
|
{"national_pokedex_number": 112, "name": "rhydon", "types": ["ground", "rock"], "baseStats": {"hp": 105, "attack": 130, "defense": 120, "speed": 40, "special": 45}}
|
||||||
|
{"national_pokedex_number": 111, "name": "rhyhorn", "types": ["ground", "rock"], "baseStats": {"hp": 80, "attack": 85, "defense": 95, "speed": 25, "special": 30}}
|
||||||
|
{"national_pokedex_number": 27, "name": "sandshrew", "types": ["ground"], "baseStats": {"hp": 50, "attack": 75, "defense": 85, "speed": 40, "special": 30}}
|
||||||
|
{"national_pokedex_number": 28, "name": "sandslash", "types": ["ground"], "baseStats": {"hp": 75, "attack": 100, "defense": 110, "speed": 65, "special": 55}}
|
||||||
|
{"national_pokedex_number": 123, "name": "scyther", "types": ["bug", "flying"], "baseStats": {"hp": 70, "attack": 110, "defense": 80, "speed": 105, "special": 55}}
|
||||||
|
{"national_pokedex_number": 117, "name": "seadra", "types": ["water"], "baseStats": {"hp": 55, "attack": 65, "defense": 95, "speed": 85, "special": 95}}
|
||||||
|
{"national_pokedex_number": 119, "name": "seaking", "types": ["water"], "baseStats": {"hp": 80, "attack": 92, "defense": 65, "speed": 68, "special": 80}}
|
||||||
|
{"national_pokedex_number": 86, "name": "seel", "types": ["water"], "baseStats": {"hp": 65, "attack": 45, "defense": 55, "speed": 45, "special": 70}}
|
||||||
|
{"national_pokedex_number": 90, "name": "shellder", "types": ["water"], "baseStats": {"hp": 30, "attack": 65, "defense": 100, "speed": 40, "special": 45}}
|
||||||
|
{"national_pokedex_number": 80, "name": "slowbro", "types": ["water", "psychic"], "baseStats": {"hp": 95, "attack": 75, "defense": 110, "speed": 30, "special": 80}}
|
||||||
|
{"national_pokedex_number": 79, "name": "slowpoke", "types": ["water", "psychic"], "baseStats": {"hp": 90, "attack": 65, "defense": 65, "speed": 15, "special": 40}}
|
||||||
|
{"national_pokedex_number": 143, "name": "snorlax", "types": ["normal"], "baseStats": {"hp": 160, "attack": 110, "defense": 65, "speed": 30, "special": 65}}
|
||||||
|
{"national_pokedex_number": 21, "name": "spearow", "types": ["normal", "flying"], "baseStats": {"hp": 40, "attack": 60, "defense": 30, "speed": 70, "special": 31}}
|
||||||
|
{"national_pokedex_number": 7, "name": "squirtle", "types": ["water"], "baseStats": {"hp": 44, "attack": 48, "defense": 65, "speed": 43, "special": 50}}
|
||||||
|
{"national_pokedex_number": 121, "name": "starmie", "types": ["water", "psychic"], "baseStats": {"hp": 60, "attack": 75, "defense": 85, "speed": 115, "special": 100}}
|
||||||
|
{"national_pokedex_number": 120, "name": "staryu", "types": ["water"], "baseStats": {"hp": 30, "attack": 45, "defense": 55, "speed": 85, "special": 70}}
|
||||||
|
{"national_pokedex_number": 114, "name": "tangela", "types": ["grass"], "baseStats": {"hp": 65, "attack": 55, "defense": 115, "speed": 60, "special": 100}}
|
||||||
|
{"national_pokedex_number": 128, "name": "tauros", "types": ["normal"], "baseStats": {"hp": 75, "attack": 100, "defense": 95, "speed": 110, "special": 70}}
|
||||||
|
{"national_pokedex_number": 72, "name": "tentacool", "types": ["water", "poison"], "baseStats": {"hp": 40, "attack": 40, "defense": 35, "speed": 70, "special": 100}}
|
||||||
|
{"national_pokedex_number": 73, "name": "tentacruel", "types": ["water", "poison"], "baseStats": {"hp": 80, "attack": 70, "defense": 65, "speed": 100, "special": 120}}
|
||||||
|
{"national_pokedex_number": 134, "name": "vaporeon", "types": ["water"], "baseStats": {"hp": 130, "attack": 65, "defense": 60, "speed": 65, "special": 110}}
|
||||||
|
{"national_pokedex_number": 49, "name": "venomoth", "types": ["bug", "poison"], "baseStats": {"hp": 70, "attack": 65, "defense": 60, "speed": 90, "special": 90}}
|
||||||
|
{"national_pokedex_number": 48, "name": "venonat", "types": ["bug", "poison"], "baseStats": {"hp": 60, "attack": 55, "defense": 50, "speed": 45, "special": 40}}
|
||||||
|
{"national_pokedex_number": 3, "name": "venusaur", "types": ["grass", "poison"], "baseStats": {"hp": 80, "attack": 82, "defense": 83, "speed": 80, "special": 100}}
|
||||||
|
{"national_pokedex_number": 71, "name": "victreebel", "types": ["grass", "poison"], "baseStats": {"hp": 80, "attack": 105, "defense": 65, "speed": 70, "special": 100}}
|
||||||
|
{"national_pokedex_number": 45, "name": "vileplume", "types": ["grass", "poison"], "baseStats": {"hp": 75, "attack": 80, "defense": 85, "speed": 50, "special": 100}}
|
||||||
|
{"national_pokedex_number": 100, "name": "voltorb", "types": ["electric"], "baseStats": {"hp": 40, "attack": 30, "defense": 50, "speed": 100, "special": 55}}
|
||||||
|
{"national_pokedex_number": 37, "name": "vulpix", "types": ["fire"], "baseStats": {"hp": 38, "attack": 41, "defense": 40, "speed": 65, "special": 65}}
|
||||||
|
{"national_pokedex_number": 8, "name": "wartortle", "types": ["water"], "baseStats": {"hp": 59, "attack": 63, "defense": 80, "speed": 58, "special": 65}}
|
||||||
|
{"national_pokedex_number": 13, "name": "weedle", "types": ["bug", "poison"], "baseStats": {"hp": 40, "attack": 35, "defense": 30, "speed": 50, "special": 20}}
|
||||||
|
{"national_pokedex_number": 70, "name": "weepinbell", "types": ["grass", "poison"], "baseStats": {"hp": 65, "attack": 90, "defense": 50, "speed": 55, "special": 85}}
|
||||||
|
{"national_pokedex_number": 110, "name": "weezing", "types": ["poison"], "baseStats": {"hp": 65, "attack": 90, "defense": 120, "speed": 60, "special": 85}}
|
||||||
|
{"national_pokedex_number": 40, "name": "wigglytuff", "types": ["normal", "fairy"], "baseStats": {"hp": 140, "attack": 70, "defense": 45, "speed": 45, "special": 50}}
|
||||||
|
{"national_pokedex_number": 145, "name": "zapdos", "types": ["electric", "flying"], "baseStats": {"hp": 90, "attack": 90, "defense": 85, "speed": 100, "special": 125}}
|
||||||
|
{"national_pokedex_number": 41, "name": "zubat", "types": ["poison", "flying"], "baseStats": {"hp": 40, "attack": 45, "defense": 35, "speed": 55, "special": 40}}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user