如何为Python中Bee类的动作实现指定回合的减速效果?
问题:为Bee类实现减速效果
需求:施加减速效果后,在持续duration回合内,当colony.time为奇数时蜜蜂不执行任何操作,为偶数时执行原动作。
当前卡壳点:原本想用全局列表暂存施加的效果,但不知道如何正确实现effects.pop(0)的逻辑。仅在Bee.action中检查列表长度并弹出效果不可行,因为make_slow函数需要调用原动作,逻辑互相冲突。
原始代码(思路片段)
class Colony: def __init__(self, bee, ant): self.bee = bee self.ant = ant self.time = 0 class Bee: name = 'bee' def __init__(self, armor=5): self.armor = armor def action(self, colony): self.sting(colony.ant) def sting(self, target): target.reduce_armor(1) def reduce_armor(self, n): self.armor -= n if self.armor <= 0: self.armor = 0 class Ant: name = 'ant' def __init__(self, armor=5): self.armor = armor def throw_at(self, target): target.reduce_armor(1) def action(self, colony): self.throw_at(colony.bee) def reduce_armor(self, n): self.armor -= n if self.armor <= 0: self.armor = 0 effects = [] # 想用这个列表存效果,但可能有更好的方式 def make_slow(action): """返回一个新的动作方法,每隔一回合调用一次原ACTION。 生效期间,colony.time为奇数时蜜蜂不行动,偶数时执行原动作。 action -- Bee类的某个动作方法 """ def f(duration): # 待完善 a = lambda colony: action(colony) if not colony.time % 2 else None effects.extend([a] * 2 * duration) return f def apply_effect(effect, bee, duration): """给BEE施加持续DURATION回合的状态效果。""" effect(bee.action)(duration) class ThrowerAnt(Ant): """能给蜜蜂施加减速效果的ThrowerAnt。""" def throw_at(self, target): if target: apply_effect(make_slow, target, 2) bee = Bee() ant = ThrowerAnt() colony = Colony(bee, ant) ant.action(colony) # 给蜜蜂施加减速效果 colony.time += 1 bee.action(colony) # colony.time为奇数,蜜蜂不行动 colony.time += 1 bee.action(colony) # colony.time为偶数,执行原动作,第1回合 colony.time += 1 bee.action(colony) # colony.time为奇数,蜜蜂不行动 colony.time += 1 bee.action(colony) # colony.time为偶数,执行原动作,第2回合 colony.time += 1 bee.action(colony) # 效果结束,执行原动作
解决思路与修改后的代码
核心问题是全局效果列表无法对应单个Bee的状态,应该把效果绑定到Bee实例上,让每个蜜蜂自己管理自身的状态效果。具体修改如下:
- 给
Bee类添加实例属性_effects,用于存储当前生效的效果,同时保留原动作的引用_original_action。 - 重写
Bee.action方法,优先处理当前效果,效果过期后自动恢复原动作。 - 修改
make_slow生成带持续时间跟踪的效果,而不是依赖全局列表。 - 修改
apply_effect将效果注入到Bee实例的_effects中。
修改后的完整代码:
class Colony: def __init__(self, bee, ant): self.bee = bee self.ant = ant self.time = 0 class Bee: name = 'bee' def __init__(self, armor=5): self.armor = armor # 保存原动作引用,用于效果结束后恢复 self._original_action = self.action # 存储当前生效的效果,每个元素是(效果函数, 剩余持续回合数) self._effects = [] def action(self, colony): self.sting(colony.ant) def sting(self, target): target.reduce_armor(1) def reduce_armor(self, n): self.armor -= n if self.armor <= 0: self.armor = 0 def _effect_wrapper(self, colony): """包装后的动作方法,处理当前所有效果""" # 先处理效果,更新剩余回合数,移除过期效果 remaining_effects = [] for effect_func, duration in self._effects: # 执行当前效果逻辑 effect_func(colony) # 剩余回合数减1,大于0则保留 if duration - 1 > 0: remaining_effects.append((effect_func, duration - 1)) self._effects = remaining_effects # 如果没有生效的效果,恢复原动作 if not self._effects: self.action = self._original_action self.action(colony) class Ant: name = 'ant' def __init__(self, armor=5): self.armor = armor def throw_at(self, target): target.reduce_armor(1) def action(self, colony): self.throw_at(colony.bee) def reduce_armor(self, n): self.armor -= n if self.armor <= 0: self.armor = 0 def make_slow(original_action): """生成减速效果的函数:奇数回合不行动,偶数回合执行原动作""" def slow_effect(colony): if colony.time % 2 == 0: original_action(colony) return slow_effect def apply_effect(effect_func, bee, duration): """给Bee实例施加持续duration回合的效果""" # 将动作替换为效果包装器 bee.action = bee._effect_wrapper # 添加效果到实例的效果列表 bee._effects.append((effect_func, duration)) class ThrowerAnt(Ant): """能给蜜蜂施加减速效果的ThrowerAnt""" def throw_at(self, target): if target: # 生成减速效果并施加 slow_effect = make_slow(target._original_action) apply_effect(slow_effect, target, 2) # 测试逻辑 bee = Bee() ant = ThrowerAnt() colony = Colony(bee, ant) ant.action(colony) # 给蜜蜂施加减速效果,持续2回合 colony.time += 1 bee.action(colony) # colony.time=1(奇数),不行动 colony.time += 1 bee.action(colony) # colony.time=2(偶数),执行原动作,减速剩余1回合 colony.time += 1 bee.action(colony) # colony.time=3(奇数),不行动 colony.time += 1 bee.action(colony) # colony.time=4(偶数),执行原动作,减速效果结束 colony.time += 1 bee.action(colony) # 效果过期,恢复原动作,正常执行
关键逻辑说明
- 每个
Bee实例自己管理_effects列表,存储(效果函数, 剩余回合数)的元组,避免全局列表的混乱。 _effect_wrapper作为临时的action方法,每次执行时会遍历效果列表,执行效果逻辑并更新剩余回合数,移除过期效果。- 当效果全部过期后,自动将
action恢复为_original_action,保证逻辑回归正常。 make_slow专注于生成减速的逻辑函数,不依赖全局状态,耦合度更低。
内容的提问来源于stack exchange,提问作者Leonard
相关产品推荐
相关产品推荐

