人狗大战Ⅳ

核心玩法设计

  1. 团队组建

    • 玩家A和玩家B各自从「6个人类角色」中选2个,从「4种狗角色」中选1个,组成3人团队
    • 每个角色有独特属性(生命值、攻击力、防御力、技能)
  2. 回合制对战

    • 玩家轮流操作(玩家A→玩家B→玩家A...)
    • 每次操作可选择:「攻击敌方成员」「治疗己方成员」「使用技能」(部分角色有专属技能)
  3. 胜负规则

    • 一方团队所有成员生命值归0则失败,另一方获胜

完整代码实现

import random
from typing import List, Dict


# 基础生物类(继承父类)
class Creature:
    def __init__(self, name: str, hp: int, attack: int, defense: int):
        self.name = name  # 名称
        self.max_hp = hp  # 最大生命值
        self.current_hp = hp  # 当前生命值
        self.attack = attack  # 攻击力
        self.defense = defense  # 防御力
        self.is_alive = True  # 是否存活

    def take_damage(self, damage: int) -> str:
        """受到伤害(防御减免部分伤害)"""
        actual_damage = max(1, damage - self.defense)  # 至少造成1点伤害
        self.current_hp -= actual_damage
        if self.current_hp <= 0:
            self.current_hp = 0
            self.is_alive = False
            return f"{self.name}受到{actual_damage}点伤害,已倒下!"
        return f"{self.name}受到{actual_damage}点伤害,剩余生命值:{self.current_hp}/{self.max_hp}"

    def heal(self, amount: int) -> str:
        """治疗生命值"""
        self.current_hp = min(self.max_hp, self.current_hp + amount)
        return f"{self.name}恢复了{amount}点生命值,当前生命值:{self.current_hp}/{self.max_hp}"


# 人类角色(继承Creature)
class Human(Creature):
    ROLES = {  # 6个人类角色模板
        "战士": {"hp": 150, "attack": 25, "defense": 10, "skill": "狂怒一击(双倍伤害)"},
        "法师": {"hp": 80, "attack": 35, "defense": 5, "skill": "火球术(无视5点防御)"},
        "牧师": {"hp": 100, "attack": 15, "defense": 8, "skill": "强效治疗(恢复50点生命)"},
        "刺客": {"hp": 90, "attack": 30, "defense": 7, "skill": "偷袭(优先攻击,伤害+10)"},
        "骑士": {"hp": 130, "attack": 20, "defense": 15, "skill": "护盾(本回合减伤50%)"},
        "猎人": {"hp": 110, "attack": 28, "defense": 6, "skill": "精准射击(必中,伤害+5)"}
    }

    def __init__(self, name: str, role: str):
        role_data = self.ROLES[role]
        super().__init__(name, role_data["hp"], role_data["attack"], role_data["defense"])
        self.role = role  # 职业
        self.skill = role_data["skill"]  # 技能描述
        self.weapon = None  # 武器(聚合关系)

    def use_skill(self, target) -> str:
        """使用职业技能(不同职业效果不同)"""
        if not target.is_alive:
            return f"目标{target.name}已倒下,技能无效!"
        
        if self.role == "战士":
            damage = self.attack * 2 + (self.weapon.attack_buff if self.weapon else 0)
            return f"{self.name}使用狂怒一击!" + target.take_damage(damage)
        elif self.role == "法师":
            damage = self.attack + (self.weapon.attack_buff if self.weapon else 0)
            actual_damage = damage - max(0, target.defense - 5)  # 无视5点防御
            return f"{self.name}使用火球术!" + target.take_damage(actual_damage)
        elif self.role == "牧师":
            return self.heal(50)  # 牧师技能是治疗自己
        elif self.role == "刺客":
            damage = self.attack + 10 + (self.weapon.attack_buff if self.weapon else 0)
            return f"{self.name}使用偷袭!" + target.take_damage(damage)
        elif self.role == "骑士":
            self.defense += 5  # 本回合减伤(临时提升防御)
            return f"{self.name}开启护盾!本回合防御+5!"
        elif self.role == "猎人":
            damage = self.attack + 5 + (self.weapon.attack_buff if self.weapon else 0)
            return f"{self.name}使用精准射击!" + target.take_damage(damage)

    def attack_target(self, target) -> str:
        """普通攻击"""
        if not target.is_alive:
            return f"目标{target.name}已倒下,无法攻击!"
        base_damage = self.attack + (self.weapon.attack_buff if self.weapon else 0)
        return f"{self.name}攻击{target.name}!" + target.take_damage(base_damage)


# 狗角色(继承Creature)
class Dog(Creature):
    BREEDS = {  # 4种狗角色模板
        "狼狗": {"hp": 120, "attack": 22, "defense": 8, "skill": "撕咬(造成流血,持续伤害)"},
        "藏獒": {"hp": 180, "attack": 18, "defense": 12, "skill": "冲撞(击退,降低目标防御2点)"},
        "边牧": {"hp": 90, "attack": 15, "defense": 6, "skill": "辅助(提升己方随机成员攻击3点)"},
        "杜宾": {"hp": 110, "attack": 25, "defense": 7, "skill": "突袭(无视目标3点防御)"}
    }

    def __init__(self, name: str, breed: str):
        breed_data = self.BREEDS[breed]
        super().__init__(name, breed_data["hp"], breed_data["attack"], breed_data["defense"])
        self.breed = breed  # 品种
        self.skill = breed_data["skill"]  # 技能描述
        self.collar = None  # 项圈(聚合关系,减伤)

    def use_skill(self, target, ally_team=None) -> str:
        """使用狗类技能(部分需要队友信息)"""
        if not target.is_alive and self.breed != "边牧":
            return f"目标{target.name}已倒下,技能无效!"
        
        if self.breed == "狼狗":
            # 撕咬:造成伤害+持续流血(下回合额外5点伤害)
            base_damage = self.attack + (self.collar.defense_buff if self.collar else 0)
            result = f"{self.name}使用撕咬!" + target.take_damage(base_damage)
            target.bleed = True  # 标记流血状态
            return result + "(目标进入流血状态,下回合额外受5点伤害)"
        elif self.breed == "藏獒":
            base_damage = self.attack + (self.collar.defense_buff if self.collar else 0)
            result = f"{self.name}使用冲撞!" + target.take_damage(base_damage)
            target.defense -= 2  # 降低目标防御
            return result + "(目标防御降低2点)"
        elif self.breed == "边牧":
            # 辅助队友:随机提升己方1名成员攻击
            if not ally_team:
                return "边牧技能需要队友信息!"
            ally = random.choice([m for m in ally_team if m.is_alive])
            ally.attack += 3
            return f"{self.name}使用辅助!{ally.name}攻击+3(当前攻击:{ally.attack})"
        elif self.breed == "杜宾":
            base_damage = self.attack + (self.collar.defense_buff if self.collar else 0)
            actual_damage = base_damage - max(0, target.defense - 3)  # 无视3点防御
            return f"{self.name}使用突袭!" + target.take_damage(actual_damage)

    def attack_target(self, target) -> str:
        """普通攻击(项圈提供防御加成,但不直接提升攻击)"""
        if not target.is_alive:
            return f"目标{target.name}已倒下,无法攻击!"
        base_damage = self.attack
        return f"{self.name}攻击{target.name}!" + target.take_damage(base_damage)


# 武器(聚合到Human)
class Weapon:
    def __init__(self, name: str, attack_buff: int):
        self.name = name
        self.attack_buff = attack_buff  # 攻击加成

    def __str__(self):
        return f"{self.name}(攻击+{self.attack_buff})"


# 项圈(聚合到Dog)
class Collar:
    def __init__(self, name: str, defense_buff: int):
        self.name = name
        self.defense_buff = defense_buff  # 防御加成

    def __str__(self):
        return f"{self.name}项圈(防御+{self.defense_buff})"


# 药水(依赖关系,用完即弃)
class Potion:
    def __init__(self, heal_amount: int, name: str = "治疗药水"):
        self.heal_amount = heal_amount
        self.name = name

    def __str__(self):
        return f"{self.name}(恢复{self.heal_amount}点生命)"


# 玩家团队类
class PlayerTeam:
    def __init__(self, player_name: str):
        self.player_name = player_name  # 玩家名称
        self.members = []  # 团队成员(2个人类+1只狗)

    def add_member(self, member: Creature) -> str:
        """添加团队成员"""
        if len(self.members) >= 3:
            return "团队已满(最多3人)!"
        self.members.append(member)
        return f"{self.player_name}的团队加入了:{member.name}({member.role if isinstance(member, Human) else member.breed})"

    def is_defeated(self) -> bool:
        """判断团队是否全灭"""
        return all(not m.is_alive for m in self.members)

    def show_status(self) -> str:
        """显示团队当前状态"""
        status = f"\n【{self.player_name}的团队状态】\n"
        for i, member in enumerate(self.members, 1):
            alive_tag = "存活" if member.is_alive else "已倒下"
            status += f"{i}. {member.name}({member.role if isinstance(member, Human) else member.breed}):"
            status += f"生命{member.current_hp}/{member.max_hp},攻击{member.attack},防御{member.defense},{alive_tag}\n"
        return status


# 游戏主控制器
class Game:
    def __init__(self):
        self.player_a = None  # 玩家A团队
        self.player_b = None  # 玩家B团队
        self.turn = 0  # 回合数

    def create_teams(self):
        """创建玩家团队(选择角色)"""
        print("=== 欢迎来到人狗大战回合制游戏 ===")
        # 玩家A创建团队
        print("\n【玩家A创建团队】")
        player_a_name = input("请输入你的名称:")
        self.player_a = PlayerTeam(player_a_name)
        self._choose_members(self.player_a)

        # 玩家B创建团队(可改为真人或AI,这里默认真人)
        print("\n【玩家B创建团队】")
        player_b_name = input("请输入你的名称:")
        self.player_b = PlayerTeam(player_b_name)
        self._choose_members(self.player_b)

    def _choose_members(self, team: PlayerTeam):
        """选择团队成员(2人类+1狗)"""
        # 选择人类角色
        print("\n可选人类角色:", list(Human.ROLES.keys()))
        for i in range(2):
            while True:
                role = input(f"请选择第{i+1}个人类角色(输入角色名):")
                if role in Human.ROLES:
                    name = input(f"给{role}起个名字:")
                    human = Human(name, role)
                    # 随机分配武器
                    weapons = [Weapon("长剑", 5), Weapon("斧头", 6), Weapon("法杖", 4)]
                    human.weapon = random.choice(weapons)
                    print(team.add_member(human))
                    print(f"{name}装备了:{human.weapon}")
                    break
                else:
                    print("角色不存在,请重新输入!")

        # 选择狗角色
        print("\n可选狗角色:", list(Dog.BREEDS.keys()))
        while True:
            breed = input("请选择1只狗角色(输入品种名):")
            if breed in Dog.BREEDS:
                name = input(f"给{breed}起个名字:")
                dog = Dog(name, breed)
                # 随机分配项圈
                collars = [Collar("皮革", 2), Collar("金属", 3), Collar("魔法", 4)]
                dog.collar = random.choice(collars)
                print(team.add_member(dog))
                print(f"{name}戴上了:{dog.collar}")
                break
            else:
                print("狗品种不存在,请重新输入!")

    def parse_command(self, command: str, attacker_team, defender_team) -> str:
        """解析玩家输入的指令(格式:操作 目标)"""
        command = command.strip().lower()
        # 攻击指令:"攻击 玩家b的1号" 或 "攻击 2"(简化:直接输入目标序号)
        if command.startswith("攻击"):
            try:
                target_idx = int(command.split()[-1]) - 1  # 目标序号(1-based→0-based)
                if 0 <= target_idx < len(defender_team.members):
                    target = defender_team.members[target_idx]
                    # 选择己方存活成员进行攻击
                    attacker = self._choose_attacker(attacker_team)
                    if attacker:
                        return attacker.attack_target(target)
                    else:
                        return "己方已无存活成员,无法攻击!"
                else:
                    return "目标序号无效!"
            except (ValueError, IndexError):
                return "指令格式错误!攻击指令示例:'攻击 1'(攻击敌方1号成员)"

        # 技能指令:"技能 玩家b的2号" 或 "技能 1"
        elif command.startswith("技能"):
            try:
                target_idx = int(command.split()[-1]) - 1
                if 0 <= target_idx < len(defender_team.members) or (attacker_team.members[0].breed == "边牧" and target_idx == -1):
                    target = defender_team.members[target_idx] if target_idx != -1 else None
                    attacker = self._choose_attacker(attacker_team)
                    if attacker:
                        if isinstance(attacker, Dog) and attacker.breed == "边牧":
                            return attacker.use_skill(target, attacker_team.members)  # 边牧技能需要队友
                        else:
                            return attacker.use_skill(target)
                    else:
                        return "己方已无存活成员,无法使用技能!"
                else:
                    return "目标序号无效!"
            except (ValueError, IndexError):
                return "指令格式错误!技能指令示例:'技能 1'(对敌方1号使用技能)"

        # 治疗指令:"治疗 己方2号" 或 "治疗 1"
        elif command.startswith("治疗"):
            try:
                ally_idx = int(command.split()[-1]) - 1
                if 0 <= ally_idx < len(attacker_team.members):
                    ally = attacker_team.members[ally_idx]
                    if not ally.is_alive:
                        return "目标已倒下,无法治疗!"
                    # 随机使用药水(依赖关系)
                    potion = Potion(random.randint(20, 40))
                    return f"{ally.name}使用了{potion}!" + ally.heal(potion.heal_amount)
                else:
                    return "己方成员序号无效!"
            except (ValueError, IndexError):
                return "指令格式错误!治疗指令示例:'治疗 1'(治疗己方1号成员)"

        else:
            return "无效指令!支持指令:攻击 目标序号 / 技能 目标序号 / 治疗 己方序号(序号从1开始)"

    def _choose_attacker(self, team: PlayerTeam) -> Creature:
        """选择己方一个存活成员执行操作(这里简化为随机,可改为玩家指定)"""
        alive_members = [m for m in team.members if m.is_alive]
        if not alive_members:
            return None
        # 显示可选攻击者,让玩家选择(增强交互)
        print(f"\n请选择执行操作的成员(序号):")
        for i, m in enumerate(alive_members, 1):
            print(f"{i}. {m.name}({m.role if isinstance(m, Human) else m.breed},生命{m.current_hp}/{m.max_hp})")
        while True:
            try:
                idx = int(input("输入序号:")) - 1
                return alive_members[idx]
            except (ValueError, IndexError):
                print("序号无效,请重新输入!")

    def handle_bleed(self, members: List[Creature]) -> str:
        """处理流血状态(狼狗技能效果)"""
        result = ""
        for member in members:
            if hasattr(member, "bleed") and member.bleed and member.is_alive:
                member.take_damage(5)
                result += f"{member.name}流血了,额外受到5点伤害!当前生命:{member.current_hp}/{member.max_hp}\n"
                member.bleed = False  # 重置流血状态
        return result

    def start_battle(self):
        """开始战斗回合"""
        print("\n=== 战斗开始! ===")
        current_player = self.player_a  # 先手玩家A
        opponent = self.player_b

        while True:
            self.turn += 1
            print(f"\n===== 第{self.turn}回合:{current_player.player_name}的回合 =====")
            
            # 显示双方状态
            print(current_player.show_status())
            print(opponent.show_status())

            # 处理上回合流血状态
            bleed_result = self.handle_bleed(current_player.members)
            if bleed_result:
                print(f"\n【状态触发】{bleed_result}")

            # 检查是否有一方已全灭
            if current_player.is_defeated():
                print(f"\n{current_player.player_name}的团队全灭!{opponent.player_name}获胜!")
                break
            if opponent.is_defeated():
                print(f"\n{opponent.player_name}的团队全灭!{current_player.player_name}获胜!")
                break

            # 玩家输入指令
            command = input(f"\n{current_player.player_name},请输入操作指令(攻击/技能/治疗 + 目标序号):")
            action_result = self.parse_command(command, current_player, opponent)
            print(f"\n【操作结果】{action_result}")

            # 切换回合
            current_player, opponent = opponent, current_player


# 启动游戏
if __name__ == "__main__":
    game = Game()
    game.create_teams()
    game.start_battle()

游戏亮点与玩法说明

  1. 角色多样性

    • 6个人类职业(战士/法师/牧师等)和4种狗(狼狗/藏獒等),各有专属技能(如战士的双倍伤害、边牧的队友 buff)
    • 随机分配武器/项圈,增加每次游戏的差异性
  2. 策略性操作

    • 攻击:选择敌方成员进行普通攻击
    • 技能:使用职业专属技能(如牧师治疗、狼狗流血)
    • 治疗:使用药水恢复己方成员生命
    • 需根据战场状态决策(优先集火敌方输出?治疗残血队友?)
  3. 文本交互流程

    • 团队创建时选择角色并命名
    • 回合中输入指令(如“攻击 2”表示攻击敌方2号成员)
    • 实时显示双方生命值、攻击/防御变化,清晰掌握战局
  4. 状态机制

    • 流血效果(狼狗技能):下回合额外受伤
    • 防御/攻击临时加成(骑士护盾、边牧辅助)
    • 武器/项圈提供固定加成(聚合关系体现)

示例操作流程

  1. 玩家A和B分别输入名称,选择2个人类+1只狗组成团队
  2. 回合开始,显示双方成员状态(生命值、职业等)
  3. 玩家A输入指令(如“技能 1”,用战士的狂怒一击攻击敌方1号)
  4. 系统执行操作并显示结果(如“Alice使用狂怒一击!Bob受到50点伤害...”)
  5. 切换到玩家B回合,重复操作
  6. 一方全灭则游戏结束,显示获胜方

这个版本保留了原有的面向对象设计(继承、聚合、依赖),同时通过团队系统、技能机制和文本交互大幅提升了游戏性,支持双人对战和策略决策,适合作为入门级回合制游戏案例扩展。

posted @ 2025-11-05 17:54  wangya216  阅读(17)  评论(0)    收藏  举报