我刚刚开始学习python,所以我不熟悉各种技巧或工具,也不是表达我的问题的正确方法。因此,我无法找到以前要解决的问题。
我这里概述了一个工作代码:
import random
class UserGroup:
def __init__(self, users):
self.user_list = users
def random_users(self):
self.random_1 = random.choice(self.user_list)
self.random_2 = self.random_1
while self.random_2 == self.random_1:
self.random_2 = random.choice(self.user_list)
return self.random_1, self.random_2
class User:
def __init__(self, nickname, stats):
self.nickname = nickname
self.strength = stats['strength']
self.constitution = stats['constitution']
self.dexterity = stats['dexterity']
self.intelligence = stats['intelligence']
self.wisdom = stats['wisdom']
self.charisma = stats['charisma']
def __repr__(self):
return self.nickname
class Jared(User):
def fight_stat(self):
self.attack = self.strength + self.intelligence
self.defense = self.constitution * 2
self.speed = self.dexterity / 2
class Poptart(User):
def fight_stat(self):
self.attack = self.strength + self.dexterity
self.defense = self.dexterity
self.speed = self.dexterity + self.charisma
class Kaos(User):
def fight_stat(self):
self.attack = self.dexterity + self.wisdom
self.defense = self.wisdom * 2
self.speed = self.dexterity
class Magda(User):
def fight_stat(self):
self.attack = self.intelligence + self.charisma
self.defense = self.dexterity + self.charisma
self.speed = self.dexterity + self.constitution / 2
class Battle:
def __init__(self, user1, user2):
self.user1 = user1
self.user2 = user2
print(user1, "and", user2, "have entered the fight!")
def fight(self):
self.user1.fight_stat()
self.user2.fight_stat()
if self.user1.speed > self.user2.speed:
self.attacker = self.user1
self.defender = self.user2
elif self.user2.speed > self.user1.speed:
self.attacker = self.user2
self.defender = self.user1
elif self.user1.dexterity > self.user2.dexterity:
self.attacker = self.user1
self.defender = self.user2
else:
self.attacker = self.user2
self.defender = self.user1
if self.attacker.attack > self.defender.defense:
return self.attacker
elif self.defender.attack > self.attacker.defense:
return self.defender
else:
return "Draw"
# HERE STARTS BATTLE CODE
jared = Jared('Jarebear', {'strength': 7, 'constitution': 6, 'dexterity': 6, 'intelligence': 8, 'wisdom': 5, 'charisma': 5})
poptart = Poptart('Yung SLizzy', {'strength': 4, 'constitution': 5, 'dexterity': 10, 'intelligence': 7, 'wisdom': 5, 'charisma': 7})
kaos = Kaos('Kung Cows', {'strength': 8, 'constitution': 7, 'dexterity': 6, 'intelligence': 4, 'wisdom': 7, 'charisma': 4})
magda = Magda('Meghan M', {'strength': 7, 'constitution': 5, 'dexterity': 7, 'intelligence': 8, 'wisdom': 5, 'charisma': 5})
users = UserGroup([jared, poptart, kaos, magda])
for i in range(1,4):
print("Battle number", i)
battle = Battle(*users.random_users())
print("The winner is: ", battle.fight())
示例输出如下所示:
Battle number 1
Jarebear and Kung Cows have entered the fight!
The winner is: Kung Cows
Battle number 2
Jarebear and Kung Cows have entered the fight!
The winner is: Kung Cows
Battle number 3
正如我所写,代码按预期执行。但是,我担心在fight()
类中实现Battle
方法的方式。我认为if
语句的较大顺序不是说“首先攻击速度较高的用户”的正确方法。从逻辑上讲,我只需要一个类似于self.attacker = max(self.user1.speed, self.user2.speed)
的语句,但攻击者是用户,而不是用户的速度。但是,我不知道如何在python中的一两行代码中完成此操作。
答案 0 :(得分:3)
min
和max
函数接受一个key
函数,该函数告诉他们如何比较输入。键接受每个输入并返回实际值以进行比较:
max(self.user1, self.user2, key=lambda item: item.speed)
对于大量比较,可以将其重写为
from operator import attrgetter
speed_key = attrgetter('speed')
max(self.user1, self.user2, key=speed_key)
如果速度相等,则可以决定使用其他属性进行比较。这是通过理解Python序列按字典顺序进行比较来完成的。用字符串最容易理解,因为它基本上只是字典顺序: 'abc' > 'abb'
,因为每个元素都是按顺序比较的。列表和元组也是如此:[1, 2, 3] > [1, 2, 2]
。
因此要使用dexterity
属性作为等速的备用,请执行
max(self.user1, self.user2, key=lambda item: (item.speed, item.dexterity))
OR
speedex_key = attrgetter('speed', 'dexterity')
max(self.user1, self.user2, key=speedex_key)
答案 1 :(得分:1)
创建集中逻辑的小型方法不是“开销”。它们易于理解,并且不需要出于很多原因而进行更改-因此,它们在大多数情况下都可以完成,运行并保持不变。
class Battle:
# snipped some code
@staticmethod
def get_attacker_defender(u1, u2):
"""Returs tuple (attacker,defender) based on given user."""
if u1.speed > u2.speed:
return u1,u2
elif u2.speed > u1.speed:
return u2,u1
# probably cleaner to stay with elif: ... else ... but this is shorter
return (u1,u2) if u1.dexterity > u2.dexterity else (u2,u1)
def fight(self):
self.user1.fight_stat()
self.user2.fight_stat()
self.attacker, self.defender = Battle.get_attacker_defender(self.user1,self.user2)
if self.attacker.attack > self.defender.defense:
return self.attacker
elif self.defender.attack > self.attacker.defense:
return self.defender
else:
return "Draw"
如果您喜欢脑筋急转弯,也可以这样做:
@staticmethod
def get_attacker_defender(u1,u2):
return sorted( [u1,u2], key = lambda u:(u.speed,u.dexterity), reverse=True)
利用元组排序,该排序基于元组的第一个元素,当元组的第二个元素上的第一个元素相等时进行排序。如果两者相等,则顺序保持不变(使用Timsort进行稳定排序)。
Doku:
return .. if ... else ...
)答案 2 :(得分:1)
如果要对对象使用max
,则可以实现__gt__
com比较它们(和__eq__
以获得一致性)。因此,您的User
类可能如下所示:
class User:
def __init__(self, nickname, stats):
self.nickname = nickname
self.strength = stats['strength']
self.constitution = stats['constitution']
self.dexterity = stats['dexterity']
self.intelligence = stats['intelligence']
self.wisdom = stats['wisdom']
self.charisma = stats['charisma']
def __repr__(self):
return self.nickname
def __eq__(self, other):
return self.speed == other.speed and self.dexterity == other.dexterity
def __gt__(self, other):
return self.speed > other.speed or self.dexterity > other.dexterity
此实现将允许您使用max
和min
在attacker
类中定义defender
和Battle
。
class Battle:
def __init__(self, user1, user2):
self.user1 = user1
self.user2 = user2
print(user1, "and", user2, "have entered the fight!")
def fight(self):
self.user1.fight_stat()
self.user2.fight_stat()
self.attacker = max(self.user1, self.user2)
self.defender = min(self.user1, self.user2)
if self.attacker.attack > self.defender.defense:
return self.attacker
elif self.defender.attack > self.attacker.defense:
return self.defender
else:
return "Draw"
答案 3 :(得分:0)
您确实可以使用max()以最快的速度获取user
。
这样做的方法是使用key
参数,您可以使用该参数传递自定义评分函数,该函数将获取每个对象并返回可排序的值,例如float或int。
def score(user):
return user.speed
fastest_user = max(list_of_users, key=score)
最常见的方法是传递使用以下语法定义的匿名lambda函数:
lambda var1, var2: expression
因此代码如下:
fastest_user = max(list_of_users, key=lambda user: user.speed)
答案 4 :(得分:0)
我只需要一个类似于self.attacker =的语句 max(self.user1.speed,self.user2.speed),但攻击者设置为 用户,而不是用户的速度。
您可以使用
$("#calendar").fullCalendar({
events: {
url: "https://www.hebcal.com/hebcal/?cfg=fc&v=1&i=off&maj=on&min=on&nx=on&mf=on&ss=on&mod=on&lg=s&s=off&d=on",
cache: true
}
});
这将返回最大为from operator import attrgetter
...
self.attacker = max(self.user1, self.user2, key=attrgetter('speed'))
的{{1}}(不是user
)
如果您有2个以上的用户,则还可以通过列表
答案 5 :(得分:0)
这是一个答案,它如上所述分离逻辑,并使用您的原始最大期望。该解决方案的好处在于,可以轻松地重构确定首次攻击的逻辑。只需更改顺序(或向其中添加属性)attribute_priority_order
class Battle:
def __init__(self, user1, user2):
self.user1 = user1
self.user2 = user2
print(user1, "and", user2, "have entered the fight!")
@staticmethod
def _compare_attributes(user1: User, user2: User, attribute: str):
if getattr(user1, attribute) != getattr(user2, attribute):
return max(
[user1, user2],
key=lambda user: getattr(user, attribute)
)
def get_attacker(self):
"""
Returns attacker based on attribute comparison
:return: User
"""
default_attacker = self.user2
attribute_priority_order = [
'speed',
'dexterity'
]
for attribute in attribute_priority_order:
attacker = self._compare_attributes(
user1=self.user1,
user2=self.user2,
attribute=attribute
)
if attacker:
return attacker
return default_attacker
def get_defender(self):
"""
User in the battle that isn't the attacker.
:return: User
"""
for user in [self.user1, self.user2]:
if str(user) != str(self.attacker):
return user
def fight(self):
self.user1.fight_stat()
self.user2.fight_stat()
self.attacker = self.get_attacker()
self.defender = self.get_defender()
if self.attacker.attack > self.defender.defense:
return self.attacker
elif self.defender.attack > self.attacker.defense:
return self.defender
else:
return "Draw"
有了一些额外的抽象,_compare_attributes
方法也可以被回收以确定获奖者,也许还有第二个可选属性。如果没有关系,则此方法的返回值可以是用户(可选)。
答案 6 :(得分:0)
如何利用python列表进行比较的事实,以便您的能力测度为:
def ability(user):
return (user.speed, user.dexterity)
您的获胜标准是:
def winner(attacker, defender):
return attacker.attack > defender.defense
战斗变成:
def fight(a, b):
return winner(a, b) if ability(a) >= ability(b) else winner(b, a)