Skip to content

Problem 2.3: Player and Enemy Classes (150pts)

Problem

In this problem, you will implement specific character classes that inherit from Character: the Player class and the enemy hierarchy (Enemy, TA, Boss).

在这个问题中,你将实现继承自 Character 的特定角色类:Player 类和敌人层级结构(EnemyTABoss)。

Player Class

The Player class extends Character with equipment, leveling, and inventory systems.

  • level: Current level (starts at 1)
  • experience: Current experience points
  • gold: Currency for buying items
  • equipped_weapon: Currently equipped weapon (or None)
  • equipped_armor: Currently equipped armor (or None)
  • potions: Number of health potions

You need to implement the following methods:

Player 类扩展了 Character 类,增加了装备、升级和库存系统。

  • level: 当前等级(从 1 开始)
  • experience: 当前经验值
  • gold: 用于购买物品的货币
  • equipped_weapon: 当前装备的武器(或 None
  • equipped_armor: 当前装备的护甲(或 None
  • potions: 生命药水的数量

你需要实现以下方法:

1. Override get_attack() and get_defense()

Include equipment bonuses: 包含装备加成:

    def get_attack(self):
        """Override to include weapon bonus.
        >>> player = Player("Student")
        >>> sword = Weapon("Sword", attack_bonus=10)
        >>> player.equip_weapon(sword)
        >>> player.get_attack()
        25
        """
        """YOUR CODE HERE"""

    def get_defense(self):
        """Override to include armor bonus.
        >>> player = Player("Student")
        >>> shield = Armor("Shield", defense_bonus=8)
        >>> player.equip_armor(shield)
        >>> player.get_defense()
        13
        """
        """YOUR CODE HERE"""

2. spend_gold(amount)

Spend gold if player has enough: 如果玩家拥有足够的金币则花费金币:

    def spend_gold(self, amount):
        """Spend gold. Returns True if successful, False if not enough gold.
        >>> player = Player("Student")
        >>> player.spend_gold(30)
        True
        >>> player.gold
        20
        """
        """YOUR CODE HERE"""

3. use_potion()

Use a health potion to restore 50 HP: 使用一瓶生命药水恢复 50 点生命值:

    def use_potion(self):
        """Use a health potion.
        >>> player = Player("Student")
        >>> player.current_hp = 40
        >>> player.use_potion()
        'Used a potion! Restored 50 HP.'
        >>> player.current_hp
        90
        >>> player.potions
        2
        """
        """YOUR CODE HERE"""
        return f"Used a potion! Restored {healed} HP."

4. add_experience(amount)

Add experience and level up if threshold reached: 添加经验值,如果达到阈值则升级:

    def add_experience(self, amount):
        """Add experience and check for level up.
        Return a string if leveled up, else None.
        >>> player = Player("Student")
        >>> player.current_hp = 80
        >>> player.add_experience(60)
        'Level Up! You are now level 2!'
        >>> player.level
        2
        >>> player.current_hp
        120
        """
        """YOUR CODE HERE"""
        return f"Level Up! You are now level {self.level}!"

Level-up requirements:

  • Suppose the current level of the player is level, the threshold to level up is level * 50 experience points. That is, to get to level 2 from level 1 requires 50 experience, and to get to level 3 from level 2 requires another 100 experience.
  • When leveling up:
    • Increment level by 1
    • Fully restore HP to new max
    • Increase max_hp by 20, base_attack by 5, base_defense by 2

升级要求:

  • 假设玩家当前等级为 level,升级所需的阈值为 level * 50 经验值。 也就是说,从 1 级升到 2 级需要 50 经验,而从 2 级升到 3 级则需要额外 100 经验。
  • 升级时:
    • 等级增加 1
    • 生命值完全恢复至新的最大值
    • max_hp 增加 20,base_attack 增加 5,base_defense 增加 2

Enemy Classes

Enemies inherit from Character and have specific behaviors. For the enemies, TAs have implemented themselves, and you only need to implement the Boss class.

敌人继承自 Character 并具有特定的行为。 对于敌人,助教(TA)已经实现了自己,你只需要实现 Boss 类。

class Boss(Enemy):
    """
    Final boss character with enhanced abilities.
    """

    def __init__(self):
        super().__init__(
            name="Professor Lambda",
            max_hp=300,
            attack=25,
            defense=10,
            exp_reward=200,
            gold_reward=500
        )
        self.description = "The legendary SICP professor who has mastered all paradigms!"
        # If needed, you can add more attributes here.
        """YOUR CODE HERE"""

    def choose_action(self, player):
        """Choose action based on current HP and buffs.
        Return a string describing the action taken.
        >>> boss = Boss()
        >>> player = Player("Student")
        >>> boss.current_hp = 210
        >>> boss.choose_action(player)
        'Professor Lambda attacks Student for 20 damage!'
        >>> player.current_hp
        80
        >>> boss.current_hp = 200
        >>> boss.choose_action(player)
        'Professor Lambda enters a frenzy! (ATK +40, DEF -20)'
        >>> boss.choose_action(player)
        'Professor Lambda uses magic attack on Student for 80 damage!'
        >>> player.current_hp
        0
        """
        """YOUR CODE HERE"""
        return f"{self.name} enters a frenzy! (ATK +40, DEF -20)"

Requirements: The boss has two phases. It starts in phase 1, and enters phase 2 when its HP drops below 70% (exclude 70%) of the max HP.

  • When in phase 1, on each turn, the boss only uses basic attacks.
  • When entering phase 2, the boss takes a turn to apply the "Frenzy" buff (ATK +40, DEF -20) to itself for the rest of the battle. Note that in this turn, you need to return a string describing this action. The buff should be constructed as Buff("Frenzy", attack_bonus=40, defense_bonus=-20, duration=999).
  • In phase 2, on each turn, the boss uses magic attacks only.
  • Once the boss has entered phase 2, it won't switch back to phase 1.

Boss 有两个阶段。它从阶段 1 开始,当其生命值低于最大生命值的 70%(不包括 70%)时进入阶段 2。

  • 在阶段 1 时,在每个回合中,Boss 只使用基本攻击。
  • 进入阶段 2 时,Boss 会花费一个回合给自己施加“狂暴”(Frenzy)增益效果(攻击力 +40,防御力 -20),持续到战斗结束。请注意,在这个回合中,你需要返回一个描述该行动的字符串。该增益应构建为 Buff("Frenzy", attack_bonus=40, defense_bonus=-20, duration=999)
  • 在阶段 2 时,在每个回合中,Boss 只使用魔法攻击。
  • 一旦 Boss 进入阶段 2,它就不会切换回阶段 1。

Hints

Hint:

Call super().get_attack() to get base attack with buffs, then add weapon bonus if equipped. A similar approach applies to get_defense() as well.

You cannot spend more gold than you have; return False in that case.

  • 调用 super().get_attack() 以获取包含增益效果的基础攻击力,然后如果装备了武器,则加上武器加成。类似的方法也适用于 get_defense()

  • 你不能花费超过你拥有的金币;在这种情况下返回 False

  • add_experience 中,升级的时候会扣除升级所需的经验。OJ 的测试点只包含一次升一级的情况,不需要考虑一回合内多次升级。

  • 你可能没有装备武器,不要忘记考虑这种情况。

  • Boss 恰好进入阶段 2 的回合不会攻击。