You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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实例上,让每个蜜蜂自己管理自身的状态效果。具体修改如下:

  1. 给Bee类添加实例属性_effects,用于存储当前生效的效果,同时保留原动作的引用_original_action。
  2. 重写Bee.action方法,优先处理当前效果,效果过期后自动恢复原动作。
  3. 修改make_slow生成带持续时间跟踪的效果,而不是依赖全局列表。
  4. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:09:30