有没有办法缩短我的口袋妖怪游戏的伤害计算?我不断重复代码行
Is there a way to shorten the damage calculation for my Pokemon game? I am constantly repeating lines of code
如您所见,当我计算造成的伤害时,我重复了口袋妖怪的输入。只是想知道是否有更简单的方法来编写这段代码。我想知道您是否可以使用某种 table,但不确定如何实现。
我已经提供了大部分 class 以防万一。
class Pokemon:
def __init__(self, name, types, max_health, health, attack, defense):
self.name = name
self.types = types
self.max_health = max_health
self.health = health
self.attack = attack
self.defense = defense
#Calculates the damage output depending on their attack and defense attributes
def move(self, opponent):
raw_dmg = 0
choice = int(input("Choose your move: "))
if choice == 1:
raw_dmg = int((self.attack / opponent.defense) * 25)
elif choice == 2:
if accuracy(70):
raw_dmg = int((self.attack / opponent.defense) * 40)
else:
raw_dmg = 0
elif choice == 3:
if accuracy(20):
raw_dmg = int((self.attack / opponent.defense) * 200)
else:
raw_dmg = 0
#Increases or decereases the damage depending on the type of both pokemon
if self.types == "Fire":
if opponent.types == "Water":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Grass":
raw_dmg = raw_dmg * 2
elif self.types == "Water":
if opponent.types == "Grass":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Fire":
raw_dmg = raw_dmg * 2
elif self.types == "Grass":
if opponent.types == "Fire":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Water":
raw_dmg = raw_dmg * 2
elif self.types == "Light":
if opponent.types == "Dark":
raw_dmg = raw_dmg * 2
elif self.types == "Dark":
if opponent.types == "Light":
raw_dmg = raw_dmg * 2
#The final damage is randomised by multiplying it by a value between 0.8 and 1.2
final_dmg = round(raw_dmg * (random.randint(80, 120)) / 100)
print(final_dmg)
opponent.health -= final_dmg
if opponent.health <= 0:
opponent.health = 0
return final_dmg
只要合理可能,将代码转换为数据通常是好的:
之前:
if self.types == "Fire":
if opponent.types == "Water":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Grass":
raw_dmg = raw_dmg * 2
elif self.types == "Water":
if opponent.types == "Grass":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Fire":
raw_dmg = raw_dmg * 2
elif self.types == "Grass":
if opponent.types == "Fire":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Water":
raw_dmg = raw_dmg * 2
elif self.types == "Light":
if opponent.types == "Dark":
raw_dmg = raw_dmg * 2
elif self.types == "Dark":
if opponent.types == "Light":
raw_dmg = raw_dmg * 2
之后:
# ahead of time in the global namespace
SUPER_EFFECTIVE = {
("Fire", "Grass"),
("Water", "Fire"),
...
}
NOT_VERY_EFFECTIVE = {
("Fire", "Water"),
("Water", "Grass"),
...
}
...
# in the move function
if (self.types, opponent.types) in SUPER_EFFECTIVE:
raw_dmg *= 2.0
elif (self.types, opponent.types) in NOT_VERY_EFFECTIVE:
raw_dmg *= 0.5
正在关注 , I would go a step further and make a dictionary where you can just lookup the multiplier according to the type combination. Then with .get()
, you can use a default of 1. That makes the code inside the class flat instead of nested。
TYPE_MULTIPLIERS = {
0.5: [
("Fire", "Water"),
("Water", "Grass"),
("Grass", "Fire"),
],
2: [
("Fire", "Grass"),
("Water", "Fire"),
("Grass", "Water"),
("Light", "Dark"),
("Dark", "Light"),
],
}
_MULTIPLIER_LOOKUP = {
types: multiplier
for multiplier, type_combos in TYPE_MULTIPLIERS.items()
for types in type_combos}
# ... later
raw_dmg *= _MULTIPLIER_LOOKUP.get((self.types, opponent.types), 1)
如您所见,当我计算造成的伤害时,我重复了口袋妖怪的输入。只是想知道是否有更简单的方法来编写这段代码。我想知道您是否可以使用某种 table,但不确定如何实现。 我已经提供了大部分 class 以防万一。
class Pokemon:
def __init__(self, name, types, max_health, health, attack, defense):
self.name = name
self.types = types
self.max_health = max_health
self.health = health
self.attack = attack
self.defense = defense
#Calculates the damage output depending on their attack and defense attributes
def move(self, opponent):
raw_dmg = 0
choice = int(input("Choose your move: "))
if choice == 1:
raw_dmg = int((self.attack / opponent.defense) * 25)
elif choice == 2:
if accuracy(70):
raw_dmg = int((self.attack / opponent.defense) * 40)
else:
raw_dmg = 0
elif choice == 3:
if accuracy(20):
raw_dmg = int((self.attack / opponent.defense) * 200)
else:
raw_dmg = 0
#Increases or decereases the damage depending on the type of both pokemon
if self.types == "Fire":
if opponent.types == "Water":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Grass":
raw_dmg = raw_dmg * 2
elif self.types == "Water":
if opponent.types == "Grass":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Fire":
raw_dmg = raw_dmg * 2
elif self.types == "Grass":
if opponent.types == "Fire":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Water":
raw_dmg = raw_dmg * 2
elif self.types == "Light":
if opponent.types == "Dark":
raw_dmg = raw_dmg * 2
elif self.types == "Dark":
if opponent.types == "Light":
raw_dmg = raw_dmg * 2
#The final damage is randomised by multiplying it by a value between 0.8 and 1.2
final_dmg = round(raw_dmg * (random.randint(80, 120)) / 100)
print(final_dmg)
opponent.health -= final_dmg
if opponent.health <= 0:
opponent.health = 0
return final_dmg
只要合理可能,将代码转换为数据通常是好的:
之前:
if self.types == "Fire":
if opponent.types == "Water":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Grass":
raw_dmg = raw_dmg * 2
elif self.types == "Water":
if opponent.types == "Grass":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Fire":
raw_dmg = raw_dmg * 2
elif self.types == "Grass":
if opponent.types == "Fire":
raw_dmg = raw_dmg * 0.5
elif opponent.types == "Water":
raw_dmg = raw_dmg * 2
elif self.types == "Light":
if opponent.types == "Dark":
raw_dmg = raw_dmg * 2
elif self.types == "Dark":
if opponent.types == "Light":
raw_dmg = raw_dmg * 2
之后:
# ahead of time in the global namespace
SUPER_EFFECTIVE = {
("Fire", "Grass"),
("Water", "Fire"),
...
}
NOT_VERY_EFFECTIVE = {
("Fire", "Water"),
("Water", "Grass"),
...
}
...
# in the move function
if (self.types, opponent.types) in SUPER_EFFECTIVE:
raw_dmg *= 2.0
elif (self.types, opponent.types) in NOT_VERY_EFFECTIVE:
raw_dmg *= 0.5
正在关注 .get()
, you can use a default of 1. That makes the code inside the class flat instead of nested。
TYPE_MULTIPLIERS = {
0.5: [
("Fire", "Water"),
("Water", "Grass"),
("Grass", "Fire"),
],
2: [
("Fire", "Grass"),
("Water", "Fire"),
("Grass", "Water"),
("Light", "Dark"),
("Dark", "Light"),
],
}
_MULTIPLIER_LOOKUP = {
types: multiplier
for multiplier, type_combos in TYPE_MULTIPLIERS.items()
for types in type_combos}
# ... later
raw_dmg *= _MULTIPLIER_LOOKUP.get((self.types, opponent.types), 1)