patternpythonMinor
Pokemon battle simulator
Viewed 0 times
battlesimulatorpokemon
Problem
I learned Python and Pygame and now have coded a few games. For the last few months I have been working on this "luck free" pokemon battle simulator. I feel my program runs well in the current state and at the same time is being semi spaghetti-coded because as I try to improve the game I find it more challenging than it should.
I know there are some things done wrong or improperly. Any constructive criticism you have to input is appreciated. There are multiple more files you can find here.
Here's the game.py file where the majority of the battle code is:
```
from __future__ import division
import pygame, Functions, math, time, computer_move
from yo_buttons import Button
from pokemon import *
from vision import *
from pokemon_types import *
class Game():
home_screen = Home_Screen()
team_builder_screen = Team_Builder_Screen()
play_screen = Play_Screen()
options_screen = Options_Screen()
gym_leaders_screen = Gym_Leaders_Screen()
screens = []
screens.append(home_screen)
screens.append(team_builder_screen)
screens.append(play_screen)
screens.append(options_screen)
screens.append(gym_leaders_screen)
current_screen_number = 0
Pokemon_Team = test_team
Pokemon_List = Pokemon_Team.list
opponent = test_opponent
Opponent_Pokemon_List = opponent.list
current_pokemon_number = 0
current_opponent_number = 0
current_turn_text = set([])
turn_text = set([])
battle_text = []
current_turn = 0
turn_index = -1
dead_text = ""
current_turn_sprites = [Pokemon_List[0], Opponent_Pokemon_List[0]]
turn_sprites = set([])
battle_sprites = []
current_sprites = [Pokemon_List[0], Opponent_Pokemon_List[0]]
battle_sprites.append(current_sprites)
pause = False
previous_screen = None
square_info = ["","","",""]
show_party = False
Pokemon_Party = [1, 2, 3, 4]
Opponent_Party = [1, 2, 3, 4]
Pokemon_Fainted = False
switched_in = False
switching = F
I know there are some things done wrong or improperly. Any constructive criticism you have to input is appreciated. There are multiple more files you can find here.
Here's the game.py file where the majority of the battle code is:
```
from __future__ import division
import pygame, Functions, math, time, computer_move
from yo_buttons import Button
from pokemon import *
from vision import *
from pokemon_types import *
class Game():
home_screen = Home_Screen()
team_builder_screen = Team_Builder_Screen()
play_screen = Play_Screen()
options_screen = Options_Screen()
gym_leaders_screen = Gym_Leaders_Screen()
screens = []
screens.append(home_screen)
screens.append(team_builder_screen)
screens.append(play_screen)
screens.append(options_screen)
screens.append(gym_leaders_screen)
current_screen_number = 0
Pokemon_Team = test_team
Pokemon_List = Pokemon_Team.list
opponent = test_opponent
Opponent_Pokemon_List = opponent.list
current_pokemon_number = 0
current_opponent_number = 0
current_turn_text = set([])
turn_text = set([])
battle_text = []
current_turn = 0
turn_index = -1
dead_text = ""
current_turn_sprites = [Pokemon_List[0], Opponent_Pokemon_List[0]]
turn_sprites = set([])
battle_sprites = []
current_sprites = [Pokemon_List[0], Opponent_Pokemon_List[0]]
battle_sprites.append(current_sprites)
pause = False
previous_screen = None
square_info = ["","","",""]
show_party = False
Pokemon_Party = [1, 2, 3, 4]
Opponent_Party = [1, 2, 3, 4]
Pokemon_Fainted = False
switched_in = False
switching = F
Solution
-
if you use variable/attibute names like move1 or type2 it is almost always a sign that it wants to be a list (moves, types)
sprites = [
[pokemon.back_image, (225, 250)],
[opponent.front_image, (475, 50)],
[pokemon.type.image, (495, 265)],
[opponent.type.image, (75, 40)],
]
if opponent.type2 != None:
type2 = (opponent.type2.image, (107, 40))
sprites.append(type2)
if pokemon.type2 != None:
type2 = (pokemon.type2.image, (527, 265))
sprites.append(type2)
sprites = [
[pokemon.back_image, (225, 250)],
[opponent.front_image, (475, 50)],
]
for current_pokemon,locations in [
(pokemon,[(495, 265),(527, 265)]),
(opponent,[(75, 40),(107, 40)])
]:
for type,location in zip(current_pokemon.types,locations):
sprites.append([(type.image,location)]
-
use list literals, instead of:
screens = []
screens.append(home_screen)
screens.append(team_builder_screen)
screens.append(play_screen)
screens.append(options_screen)
screens.append(gym_leaders_screen)
use:
screens = [
home_screen,
team_builder_screen,
play_screen,
options_screen,
gym_leaders_screen
]
-
misleading variable name:
next_move_text is actually an image
-
avoid repetition at almost all costs
let the computer do the repetition
repeated code makes it much harder to change/improve code
whenever there are multiple lines after each other that are almost the same,
you found a place to improve
next_move_text = pygame.image.load('images/next_move.png')
next_pokemon_text = pygame.image.load('images/next_pokemon.png')
exit_text = pygame.image.load('images/exit_text.png')
continue_text = pygame.image.load('images/continue.png')
game_over_text = pygame.image.load('images/game_over.png')
text_bubbles = [next_move_text, next_pokemon_text, exit_text, continue_text, game_over_text]
to
image_filename_list = [
'images/next_move.png',
'images/next_pokemon.png',
'images/exit_text.png',
'images/continue.png',
'images/game_over.png',
]
text_bubbles = [pygame.image.load(filename) for file_name in image_filename_list]
player_field = {
"stealth rock": False,
"spikes": 0,
"toxic spikes": 0,
}
opponent_field = {
"stealth rock": False,
"spikes": 0,
"toxic spikes": 0,
}
to
def get_empty_field():
return {
"stealth rock": False,
"spikes": 0,
"toxic spikes": 0,
}
player_field = get_empty_field()
opponent_field = get_empty_field()
x_axis = 470
Lose, Win = True, True
Game.can_switch = False
for pokemon in Game.Pokemon_List:
pokeball = [Pokemon.Pokeball, (x_axis, 334)]
sprites.append(pokeball)
if pokemon != Game.current_pokemon:
Game.Pokemon_Party[x] = pokemon
x+=1
if pokemon.current_health > 0:
Game.can_switch = True
if pokemon.current_health > 0:
Lose = False
else:
icon = [Pokemon.icon_x, (x_axis, 334)]
sprites.append(icon)
x_axis += 24
x = 0
x_axis = 50
Game.opponent_can_switch = False
for pokemon in Game.Opponent_Pokemon_List:
pokeball = [Pokemon.Pokeball, (x_axis, 109)]
sprites.append(pokeball)
if pokemon != Game.opponent.pokemon:
Game.Opponent_Party[x] = pokemon
x+=1
if pokemon.current_health > 0:
Game.opponent_can_switch = True
if pokemon.current_health > 0:
Win = False
else:
icon = [Pokemon.icon_x, (x_axis, 109)]
sprites.append(icon)
x_axis += 24
to
def check_pokemon_party(x_axis,y_axis,pokemons,current_pokemon,pokemon_party):
party_defeated = True
can_switch = False
for pokemon in pokemons:
pokeball = [Pokemon.Pokeball, (x_axis, y_axis)]
sprites.append(pokeball)
if pokemon != current_pokemon:
pokemon_party[x] = pokemon
x+=1
if pokemon.current_health > 0:
can_switch = True
if pokemon.current_health > 0:
party_defeated = False
else:
icon = [Pokemon.icon_x, (x_axis, y_axis)]
sprites.append(icon)
x_axis += 24
return party_alive,can_switch
Lose, Game.can_switch = check_pokemon_party(
470,
334,
Game.Pokemon_List,
Game.current_pokemon,
Game.Pokemon_Party
)
Win, Game.opponent_can_switch = check_pokemon_party(
50,
109,
Game.Opponent_Pokemon_List,
Game.opponent.pokemon,
Game.Opponent_Party
)
-
dont use an index to remember the current_item but use the item itself (unneeded complexity):
Game.current_pokemon_number = new_number
to
Game.current_pokemon = Game.Pokemon_List[new_number]
Game.help_text_number = 3
to
Game.help_text = Game.text_bubbles[3]
-
using a dictionary instead of a list can make things much more readable:
image_filename_list = [
'images/next_move.png',
'images/next_pokemon.png',
'images/exit_text.png',
'images/continue.png',
'images/game_over.png',
]
text_bubbles = [pygame.image.load(f
if you use variable/attibute names like move1 or type2 it is almost always a sign that it wants to be a list (moves, types)
sprites = [
[pokemon.back_image, (225, 250)],
[opponent.front_image, (475, 50)],
[pokemon.type.image, (495, 265)],
[opponent.type.image, (75, 40)],
]
if opponent.type2 != None:
type2 = (opponent.type2.image, (107, 40))
sprites.append(type2)
if pokemon.type2 != None:
type2 = (pokemon.type2.image, (527, 265))
sprites.append(type2)
sprites = [
[pokemon.back_image, (225, 250)],
[opponent.front_image, (475, 50)],
]
for current_pokemon,locations in [
(pokemon,[(495, 265),(527, 265)]),
(opponent,[(75, 40),(107, 40)])
]:
for type,location in zip(current_pokemon.types,locations):
sprites.append([(type.image,location)]
-
use list literals, instead of:
screens = []
screens.append(home_screen)
screens.append(team_builder_screen)
screens.append(play_screen)
screens.append(options_screen)
screens.append(gym_leaders_screen)
use:
screens = [
home_screen,
team_builder_screen,
play_screen,
options_screen,
gym_leaders_screen
]
-
misleading variable name:
next_move_text is actually an image
-
avoid repetition at almost all costs
let the computer do the repetition
repeated code makes it much harder to change/improve code
whenever there are multiple lines after each other that are almost the same,
you found a place to improve
next_move_text = pygame.image.load('images/next_move.png')
next_pokemon_text = pygame.image.load('images/next_pokemon.png')
exit_text = pygame.image.load('images/exit_text.png')
continue_text = pygame.image.load('images/continue.png')
game_over_text = pygame.image.load('images/game_over.png')
text_bubbles = [next_move_text, next_pokemon_text, exit_text, continue_text, game_over_text]
to
image_filename_list = [
'images/next_move.png',
'images/next_pokemon.png',
'images/exit_text.png',
'images/continue.png',
'images/game_over.png',
]
text_bubbles = [pygame.image.load(filename) for file_name in image_filename_list]
player_field = {
"stealth rock": False,
"spikes": 0,
"toxic spikes": 0,
}
opponent_field = {
"stealth rock": False,
"spikes": 0,
"toxic spikes": 0,
}
to
def get_empty_field():
return {
"stealth rock": False,
"spikes": 0,
"toxic spikes": 0,
}
player_field = get_empty_field()
opponent_field = get_empty_field()
x_axis = 470
Lose, Win = True, True
Game.can_switch = False
for pokemon in Game.Pokemon_List:
pokeball = [Pokemon.Pokeball, (x_axis, 334)]
sprites.append(pokeball)
if pokemon != Game.current_pokemon:
Game.Pokemon_Party[x] = pokemon
x+=1
if pokemon.current_health > 0:
Game.can_switch = True
if pokemon.current_health > 0:
Lose = False
else:
icon = [Pokemon.icon_x, (x_axis, 334)]
sprites.append(icon)
x_axis += 24
x = 0
x_axis = 50
Game.opponent_can_switch = False
for pokemon in Game.Opponent_Pokemon_List:
pokeball = [Pokemon.Pokeball, (x_axis, 109)]
sprites.append(pokeball)
if pokemon != Game.opponent.pokemon:
Game.Opponent_Party[x] = pokemon
x+=1
if pokemon.current_health > 0:
Game.opponent_can_switch = True
if pokemon.current_health > 0:
Win = False
else:
icon = [Pokemon.icon_x, (x_axis, 109)]
sprites.append(icon)
x_axis += 24
to
def check_pokemon_party(x_axis,y_axis,pokemons,current_pokemon,pokemon_party):
party_defeated = True
can_switch = False
for pokemon in pokemons:
pokeball = [Pokemon.Pokeball, (x_axis, y_axis)]
sprites.append(pokeball)
if pokemon != current_pokemon:
pokemon_party[x] = pokemon
x+=1
if pokemon.current_health > 0:
can_switch = True
if pokemon.current_health > 0:
party_defeated = False
else:
icon = [Pokemon.icon_x, (x_axis, y_axis)]
sprites.append(icon)
x_axis += 24
return party_alive,can_switch
Lose, Game.can_switch = check_pokemon_party(
470,
334,
Game.Pokemon_List,
Game.current_pokemon,
Game.Pokemon_Party
)
Win, Game.opponent_can_switch = check_pokemon_party(
50,
109,
Game.Opponent_Pokemon_List,
Game.opponent.pokemon,
Game.Opponent_Party
)
-
dont use an index to remember the current_item but use the item itself (unneeded complexity):
Game.current_pokemon_number = new_number
to
Game.current_pokemon = Game.Pokemon_List[new_number]
Game.help_text_number = 3
to
Game.help_text = Game.text_bubbles[3]
-
using a dictionary instead of a list can make things much more readable:
image_filename_list = [
'images/next_move.png',
'images/next_pokemon.png',
'images/exit_text.png',
'images/continue.png',
'images/game_over.png',
]
text_bubbles = [pygame.image.load(f
Context
StackExchange Code Review Q#148486, answer score: 5
Revisions (0)
No revisions yet.