20244302刘家瑞《Python程序设计》实验四报告

《Python程序设计》实验四报告>
课程:《Python程序设计》

班级:2443

姓名:刘家瑞

学号:20244302

实验教师:王志强

实验日期:2025年6月1日

必修/选修:公选课

引言

本次实验通过 Python 面向对象编程实现一款文本冒险游戏《神秘城堡探险》。游戏开发的动机源于对角色扮演游戏的热爱,希望通过代码构建一个充满探索与战斗元素的虚拟世界。本报告将详细介绍游戏的设计思路、实现过程及技术要点,该游戏融合了角色系统、物品系统、战斗系统和任务系统等核心机制,可作为学习 Python 面向对象编程的典型案例。

一、实验内容

设计并实现一个基于文本的冒险游戏,包含角色、物品、敌人、NPC 和房间等游戏元素
实现完整的游戏逻辑,包括探索、战斗、任务系统和交易系统
采用面向对象编程思想,将游戏元素抽象为类并建立合理的类间关系
实现游戏世界的构建与导航系统

二、实验演示

游戏运行效果演示:






三、实验过程

  1. 实验分析
    本实验采用分模块开发策略,将游戏系统划分为以下核心模块:
    角色系统:管理玩家角色的属性、状态与成长
    物品系统:实现各类物品的效果与使用逻辑
    战斗系统:设计回合制战斗机制与 AI 逻辑
    任务系统:管理任务的接取、进度与奖励
    NPC 系统:实现非玩家角色的对话与交易功能
    地图系统:构建游戏世界与房间导航逻辑

  2. 实验设计
    类设计与继承关系

    核心机制设计
    战斗机制:采用回合制,玩家可选择攻击、使用物品或逃跑,敌人 AI 随机选择攻击方式
    任务系统:支持物品收集、敌人击杀等任务类型,完成后自动发放奖励
    房间交互:包含物品拾取、敌人遭遇、NPC 对话和门锁机制等交互元素
    角色成长:通过击败敌人获取经验值,升级后提升属性

  3. 详细实现过程
    (1)角色系统实现
    角色类Character是游戏的核心类,负责管理玩家的所有状态:

    角色升级时会按固定规则提升属性,并通过gain_xp方法实现经验值累积与升级逻辑。
    (2)物品系统实现
    物品类Item通过effect属性区分不同类型物品的效果:

    物品使用时根据effect执行对应操作,如治疗、属性提升等。
    (3)战斗系统实现
    战斗在Room类的battle方法中实现,采用回合制逻辑:

    战斗中会计算实际伤害(考虑防御值),并在敌人被击败后发放奖励与任务进度检查。
    (4)任务系统实现
    任务类Quest管理任务的进度与奖励:

    每次击败敌人或拾取物品后,会自动检查相关任务的完成状态并发放奖励。
    (5)游戏世界构建
    通过create_game_world函数构建完整的游戏地图与元素:

    每个房间包含描述、出口、物品、敌人和 NPC 等元素,形成完整的游戏探索空间。

四、源代码

gitee:
https://gitee.com/eswindous/python/blob/9a27c03100810e8f245a2ee112841dbb7db4b89f/castle_adventure.py
神秘城堡探险游戏源码:
import random
import time

class Character:
def init(self, name, health, attack, defense):
self.name = name
self.max_health = health
self.health = health
self.attack = attack
self.defense = defense
self.inventory = []
self.gold = 0
self.quests = []
self.level = 1
self.xp = 0
self.xp_to_next_level = 100
self.killed_enemies = [] # 记录击杀的敌人

def is_alive(self):
    return self.health > 0

def take_damage(self, damage):
    actual_damage = max(1, damage - self.defense)
    self.health -= actual_damage
    print(f"{self.name}受到了{actual_damage}点伤害!")
    if not self.is_alive():
        self.health = 0
        print(f"{self.name}已死亡!")
    return actual_damage

def heal(self, amount):
    self.health = min(self.max_health, self.health + amount)
    print(f"{self.name}恢复了{amount}点生命值!")

def attack_enemy(self, enemy):
    damage = random.randint(self.attack // 2, self.attack)
    print(f"{self.name}对{enemy.name}发动攻击,造成{damage}点伤害!")
    return enemy.take_damage(damage)

def add_item(self, item):
    self.inventory.append(item)
    print(f"{self.name}获得了物品:{item.name}!")

def use_item(self, item_index):
    if 0 <= item_index < len(self.inventory):
        item = self.inventory.pop(item_index)
        item.use(self)
    else:
        print("无效的物品索引!")

def show_status(self):
    print(f"\n{self.name}的状态:")
    print(f"等级:{self.level} ({self.xp}/{self.xp_to_next_level} XP)")
    print(f"生命值:{self.health}/{self.max_health}")
    print(f"攻击力:{self.attack}")
    print(f"防御力:{self.defense}")
    print(f"金币:{self.gold}")
    print("物品:", end="")
    if not self.inventory:
        print("无")
    else:
        print(", ".join([f"{i}.{item.name}" for i, item in enumerate(self.inventory)]))

    print("任务:")
    if not self.quests:
        print("无")
    else:
        for i, quest in enumerate(self.quests):
            status = "已完成" if quest.completed else "进行中"
            print(f"{i + 1}. {quest.name} - {status}")

def gain_xp(self, amount):
    self.xp += amount
    print(f"获得了{amount}点经验值!")
    while self.xp >= self.xp_to_next_level:
        self.level_up()

def level_up(self):
    self.level += 1
    self.xp -= self.xp_to_next_level
    self.xp_to_next_level = int(self.xp_to_next_level * 1.5)
    self.max_health += 10
    self.health = self.max_health
    self.attack += 3
    self.defense += 2
    print(f"恭喜!等级提升到{self.level}!")
    print(f"生命值上限增加10点,攻击力增加3点,防御力增加2点!")

class Item:
def init(self, name, description, effect, value=0):
self.name = name
self.description = description
self.effect = effect
self.value = value

def use(self, character):
    if self.effect == "heal":
        character.heal(20)
    elif self.effect == "big_heal":
        character.heal(50)
    elif self.effect == "attack_up":
        character.attack += 5
        print(f"{character.name}的攻击力永久提升了5点!")
    elif self.effect == "defense_up":
        character.defense += 5
        print(f"{character.name}的防御力永久提升了5点!")
    elif self.effect == "key":
        print(f"你使用了{self.name},打开了一扇门!")
    elif self.effect == "xp":
        character.gain_xp(50)
    else:
        print(f"使用了{self.name},但没有任何效果...")

class Quest:
def init(self, name, description, target_item=None, target_enemy=None, reward_item=None, reward_xp=0,
reward_gold=0):
self.name = name
self.description = description
self.target_item = target_item
self.target_enemy = target_enemy
self.reward_item = reward_item
self.reward_xp = reward_xp
self.reward_gold = reward_gold
self.completed = False

def check_progress(self, player):
    if self.completed:
        return True

    # 检查物品收集类任务
    if self.target_item and self.target_item in [item.name for item in player.inventory]:
        self.completed = True
        return True

    # 检查击杀敌人类任务
    if self.target_enemy and self.target_enemy in player.killed_enemies:
        self.completed = True
        return True

    return False

def complete(self, player):
    if not self.completed:
        self.completed = True
        print(f"任务完成:{self.name}!")
        if self.reward_item:
            player.add_item(self.reward_item)
        if self.reward_xp > 0:
            player.gain_xp(self.reward_xp)
        if self.reward_gold > 0:
            player.gold += self.reward_gold
            print(f"获得了{self.reward_gold}金币!")
        return True
    return False

class Enemy:
def init(self, name, health, attack, defense, gold_reward, xp_reward, item_drop=None):
self.name = name
self.max_health = health
self.health = health
self.attack = attack
self.defense = defense
self.gold_reward = gold_reward
self.xp_reward = xp_reward
self.item_drop = item_drop

def is_alive(self):
    return self.health > 0

def take_damage(self, damage):
    actual_damage = max(1, damage - self.defense)
    self.health -= actual_damage
    print(f"{self.name}受到了{actual_damage}点伤害!")
    if not self.is_alive():
        self.health = 0
        print(f"{self.name}被击败了!")
    return actual_damage

def attack_player(self, player):
    damage = random.randint(self.attack // 2, self.attack)
    print(f"{self.name}对{player.name}发动攻击,造成{damage}点伤害!")
    return player.take_damage(damage)

class NPC:
def init(self, name, dialogue, quest=None, trade_items=None):
self.name = name
self.dialogue = dialogue
self.quest = quest
self.trade_items = trade_items or []

def talk(self, player):
    print(f"\n{self.name}: {self.dialogue}")

    if self.quest and self.quest not in player.quests:
        accept = input(f"{self.name}想要给你一个任务:{self.quest.name}。接受吗?(y/n) ").lower()
        if accept == 'y':
            player.quests.append(self.quest)
            print(f"你接受了任务:{self.quest.name}!")

    if self.trade_items:
        trade = input("想要交易吗?(y/n) ").lower()
        if trade == 'y':
            self.trade(player)

def trade(self, player):
    print(f"\n{self.name}的商店:")
    for i, item in enumerate(self.trade_items):
        print(f"{i + 1}. {item.name} - {item.description} (价格: {item.value}金币)")

    while True:
        choice = input("选择要购买的物品编号(或输入q退出):").lower()
        if choice == 'q':
            break

        try:
            item_index = int(choice) - 1
            if 0 <= item_index < len(self.trade_items):
                item = self.trade_items[item_index]
                if player.gold >= item.value:
                    player.gold -= item.value
                    player.add_item(item)
                    print(f"你购买了{item.name},花费了{item.value}金币!")
                else:
                    print("金币不足!")
            else:
                print("无效的选择!")
        except ValueError:
            print("无效的输入!")

class Room:
def init(self, name, description, exits, items=None, enemy=None, npc=None, locked=False):
self.name = name
self.description = description
self.exits = exits
self.items = items if items else []
self.enemy = enemy
self.npc = npc
self.locked = locked
self.visited = False

def enter(self, player):
    if not self.visited:
        print(f"\n你进入了{self.name}。")
        print(self.description)
        self.visited = True
    else:
        print(f"\n你回到了{self.name}。")

    if self.enemy and self.enemy.is_alive():
        print(f"这里有一个{self.enemy.name}!")
        self.battle(player, self.enemy)

    if self.items:
        print("你发现了以下物品:")
        for i, item in enumerate(self.items):
            print(f"{i + 1}. {item.name} - {item.description}")
        take = input("要拾取这些物品吗?(y/n) ").lower()
        if take == 'y':
            for item in self.items:
                player.add_item(item)
            self.items = []

    if self.npc:
        talk = input(f"这里有一个{self.npc.name}。要和他交谈吗?(y/n) ").lower()
        if talk == 'y':
            self.npc.talk(player)

    if self.locked:
        print("这个出口被锁住了!")
        if any(item.effect == "key" for item in player.inventory):
            use_key = input("你有钥匙,要使用吗?(y/n) ").lower()
            if use_key == 'y':
                for i, item in enumerate(player.inventory):
                    if item.effect == "key":
                        player.use_item(i)
                        self.locked = False
                        print("门被打开了!")
                        break
        else:
            print("你需要找到钥匙才能打开这个门。")

def battle(self, player, enemy):
    print("\n战斗开始!")
    while player.is_alive() and enemy.is_alive():
        print("\n--- 回合开始 ---")
        player.show_status()
        print(f"{enemy.name}的生命值:{enemy.health}/{enemy.max_health}")

        print("\n你的行动:")
        print("1. 攻击")
        print("2. 使用物品")
        print("3. 查看状态")
        print("4. 尝试逃跑")

        choice = input("请选择:").strip()

        if choice == '1':
            player.attack_enemy(enemy)
            if enemy.is_alive():
                enemy.attack_player(player)
        elif choice == '2':
            if not player.inventory:
                print("你没有任何物品!")
                enemy.attack_player(player)
            else:
                print("你的物品:")
                for i, item in enumerate(player.inventory):
                    print(f"{i}. {item.name} - {item.description}")
                item_choice = input("选择要使用的物品索引(或输入q取消):")
                if item_choice.lower() != 'q':
                    try:
                        player.use_item(int(item_choice))
                        if enemy.is_alive():
                            enemy.attack_player(player)
                    except ValueError:
                        print("无效的选择!")
                        enemy.attack_player(player)
        elif choice == '3':
            player.show_status()
            input("按Enter继续...")
        elif choice == '4':
            escape_chance = random.randint(1, 10)
            if escape_chance > 3:
                print("你成功逃脱了战斗!")
                return
            else:
                print("逃跑失败!")
                enemy.attack_player(player)
        else:
            print("无效的选择!")
            if enemy.is_alive():
                enemy.attack_player(player)

        if not enemy.is_alive():
            player.killed_enemies.append(enemy.name)  # 记录击杀的敌人
            print(f"你击败了{enemy.name}!")
            player.gold += enemy.gold_reward
            player.gain_xp(enemy.xp_reward)
            print(f"获得了{enemy.gold_reward}金币和{enemy.xp_reward}点经验值!")
            if enemy.item_drop and random.random() < 0.5:  # 50%几率掉落物品
                dropped_item = enemy.item_drop
                player.add_item(dropped_item)
                print(f"{enemy.name}掉落了{dropped_item.name}!")

            # 检查任务进度
            for quest in player.quests:
                if quest.target_enemy == enemy.name and not quest.completed:
                    quest.check_progress(player)
                    if quest.completed:
                        quest.complete(player)
            break

def create_game_world():
# 创建物品
health_potion = Item("治疗药水", "恢复20点生命值", "heal", 10)
big_health_potion = Item("高级治疗药水", "恢复50点生命值", "big_heal", 25)
strength_potion = Item("力量药水", "永久提升5点攻击力", "attack_up", 30)
defense_potion = Item("防御药水", "永久提升5点防御力", "defense_up", 30)
xp_potion = Item("经验药水", "获得50点经验值", "xp", 20)
key = Item("生锈的钥匙", "可以打开锁住的门", "key")
master_key = Item("城堡主钥匙", "可以打开所有锁住的门", "key")
ancient_map = Item("古老地图", "显示城堡的秘密通道", "map")
treasure = Item("黄金宝藏", "价值连城的宝藏", "treasure", 100)

# 创建敌人
skeleton = Enemy("骷髅", 30, 8, 3, 10, 20)
zombie = Enemy("僵尸", 40, 6, 5, 15, 25)
spider = Enemy("巨型蜘蛛", 25, 10, 2, 12, 20, health_potion)
guard = Enemy("城堡守卫", 60, 12, 8, 30, 40, strength_potion)
mage = Enemy("黑暗法师", 50, 15, 5, 40, 50, xp_potion)
minotaur = Enemy("牛头人", 80, 18, 10, 50, 60, defense_potion)
boss = Enemy("城堡领主", 120, 20, 15, 100, 100, master_key)

# 创建NPC
old_man = NPC(
    "老巫师",
    "欢迎来到这座古老的城堡,年轻的冒险者。我可以给你一些任务,如果你愿意的话。",
    Quest(
        "清除城堡守卫",
        "消灭城堡中的所有守卫",
        target_enemy="城堡守卫",
        reward_item=ancient_map,
        reward_xp=100,
        reward_gold=50
    ),
    [health_potion, strength_potion, defense_potion]
)

merchant = NPC(
    "商人",
    "需要什么装备吗?我这里有各种好东西。",
    trade_items=[health_potion, big_health_potion, strength_potion, defense_potion, xp_potion]
)

# 创建任务
find_treasure = Quest(
    "寻找宝藏",
    "在城堡中找到黄金宝藏",
    target_item="黄金宝藏",
    reward_xp=200,
    reward_gold=200
)

kill_boss = Quest(
    "击败城堡领主",
    "击败城堡领主,结束他的统治",
    target_enemy="城堡领主",
    reward_item=Item("勇者勋章", "证明你是一名伟大的冒险者", "medal"),
    reward_xp=300,
    reward_gold=300
)

# 创建房间
entrance = Room(
    "城堡入口",
    "你站在一座古老城堡的入口。周围是破败的墙壁,前方有一条走廊通向城堡内部。",
    {"北": "走廊", "南": "离开城堡"}
)

corridor = Room(
    "走廊",
    "一条长长的走廊,两侧有几扇门。空气中弥漫着一股霉味。",
    {"北": "大厅", "南": "城堡入口", "东": "储藏室", "西": "武器库"},
    [Item("金币", "5枚金币", "gold")]
)

storage = Room(
    "储藏室",
    "一个堆满杂物的房间。看起来已经很久没有人来过了。",
    {"西": "走廊"},
    [health_potion, Item("金币", "10枚金币", "gold")]
)

armory = Room(
    "武器库",
    "房间里摆满了各种武器和盔甲。",
    {"东": "走廊"},
    [strength_potion],
    skeleton
)

great_hall = Room(
    "大厅",
    "一个宽敞的大厅,天花板很高。大厅中央有一个楼梯通向二楼。",
    {"北": "楼梯", "南": "走廊", "东": "餐厅", "西": "书房"},
    [Item("金币", "15枚金币", "gold")],
    zombie,
    old_man
)

dining_room = Room(
    "餐厅",
    "一张长长的餐桌占据了房间的中央,上面摆满了发霉的食物。",
    {"西": "大厅"},
    [defense_potion]
)

library = Room(
    "书房",
    "房间里有许多书架,上面摆满了古老的书籍。",
    {"东": "大厅"},
    [key]
)

stairs = Room(
    "楼梯",
    "一段古老的楼梯通向二楼。楼梯看起来有些破旧,走在上面会发出咯吱声。",
    {"北": "二楼走廊", "南": "大厅"}
)

second_floor_corridor = Room(
    "二楼走廊",
    "二楼的走廊比一楼窄小,光线也更昏暗。",
    {"北": "主卧", "南": "楼梯", "东": "客房", "西": "阳台"},
    locked=True
)

master_bedroom = Room(
    "主卧",
    "一个豪华的卧室,中央有一张大床。看起来这里曾经住着城堡的主人。",
    {"南": "二楼走廊"},
    [Item("金币", "25枚金币", "gold"), health_potion, strength_potion],
    boss
)

guest_room = Room(
    "客房",
    "一个简单的房间,有一张床和一个衣柜。",
    {"西": "二楼走廊"},
    [health_potion, defense_potion]
)

balcony = Room(
    "阳台",
    "一个小阳台,可以俯瞰城堡外的庭院。",
    {"东": "二楼走廊"},
    [Item("金币", "20枚金币", "gold")],
    spider
)

# 新增区域:地下墓穴
basement_stairs = Room(
    "地下室楼梯",
    "一段陡峭的楼梯通向城堡的地下室。空气中弥漫着一股腐臭味。",
    {"北": "地下墓穴", "南": "大厅"},
    locked=True
)

catacombs = Room(
    "地下墓穴",
    "一个阴暗的墓穴,周围是一排排的棺材。",
    {"北": "墓室", "南": "地下室楼梯", "东": "秘密通道"},
    [xp_potion],
    minotaur
)

tomb = Room(
    "墓室",
    "中央有一个巨大的石棺,上面刻满了神秘的符文。",
    {"南": "地下墓穴"},
    [treasure],
    mage
)

secret_passage = Room(
    "秘密通道",
    "一条狭窄的通道,似乎通向城堡的其他区域。",
    {"西": "地下墓穴", "东": "隐藏宝库"},
    locked=True
)

hidden_treasure = Room(
    "隐藏宝库",
    "一个小房间,里面堆满了金银财宝!",
    {"西": "秘密通道"},
    [
        Item("金币", "50枚金币", "gold"),
        big_health_potion,
        strength_potion,
        defense_potion
    ]
)

# 创建游戏世界字典
world = {
    "城堡入口": entrance,
    "走廊": corridor,
    "储藏室": storage,
    "武器库": armory,
    "大厅": great_hall,
    "餐厅": dining_room,
    "书房": library,
    "楼梯": stairs,
    "二楼走廊": second_floor_corridor,
    "主卧": master_bedroom,
    "客房": guest_room,
    "阳台": balcony,
    "地下室楼梯": basement_stairs,
    "地下墓穴": catacombs,
    "墓室": tomb,
    "秘密通道": secret_passage,
    "隐藏宝库": hidden_treasure
}

# 返回游戏世界和任务
return world, find_treasure, kill_boss

def play_game():
print("欢迎来到《神秘城堡探险》!")
try:
name = input("请输入你的名字:").strip()
if not name:
name = "冒险者"
print(f"\n{name},你的冒险即将开始!")
print("你听说了一座古老城堡的传说,据说里面藏着巨大的宝藏。你决定前来一探究竟...")

    # 创建玩家
    player = Character(name, 100, 15, 5)

    # 创建游戏世界和获取任务
    world, find_treasure, kill_boss = create_game_world()

    # 添加初始任务
    player.quests.append(Quest(
        "探索城堡",
        "探索城堡的各个角落,寻找宝藏和线索",
        reward_xp=50,
        reward_gold=20
    ))
    player.quests.append(find_treasure)
    player.quests.append(kill_boss)

    # 从城堡入口开始游戏
    current_room = world["城堡入口"]
    current_room.enter(player)

    while player.is_alive():
        print("\n---")
        print(f"当前位置:{current_room.name}")
        print("可用的出口:", end="")
        print(", ".join([f"{direction} ({room_name})" for direction, room_name in current_room.exits.items()]))

        if current_room.name == "城堡入口" and "南" in current_room.exits:
            print("输入'南'离开城堡,结束游戏。")

        command = input("\n你想做什么? ").lower().strip()

        if command in ["q", "quit", "exit"]:
            print("你决定放弃探险,离开了城堡。")
            break

        if command == "status":
            player.show_status()
            continue

        if command == "help":
            print("\n可用命令:")
            print("- 方向(北、南、东、西):移动到指定方向的房间")
            print("- status:查看你的状态和物品")
            print("- help:显示帮助信息")
            print("- q/quit/exit:退出游戏")
            continue

        if command in current_room.exits:
            next_room_name = current_room.exits[command]

            if next_room_name == "离开城堡":
                # 检查任务完成情况
                completed_quests = [q for q in player.quests if q.completed]
                print(f"\n你成功离开了城堡!你完成了{len(completed_quests)}/{len(player.quests)}个任务。")
                print(f"你的冒险结束了。你获得了{player.gold}枚金币和以下物品:")
                if player.inventory:
                    for item in player.inventory:
                        print(f"- {item.name}")
                else:
                    print("无")
                break

            next_room = world.get(next_room_name)
            if next_room:
                if next_room.locked:
                    print("这个出口被锁住了!")
                    continue
                current_room = next_room
                current_room.enter(player)
            else:
                print("那个方向没有房间!")
        else:
            print("无效的命令!输入'help'查看可用命令。")

except Exception as e:
    print(f"\n游戏崩溃了!错误信息:{str(e)}")
    import traceback
    print("\n完整错误堆栈:")
    traceback.print_exc()
finally:
    print("\n游戏结束!感谢游玩《神秘城堡探险》!")

if name == "main":
play_game()

五、遇到的问题及解决过程

添加任务元素后游戏无法运行:游戏崩溃了!错误信息:name 'find_treasure' is not defined

是由于在添加初始任务时,find_treasure 任务还没有被定义导致的

修复:
任务定义调整:
将 find_treasure 和 kill_boss 任务的创建移至 create_game_world() 函数中
让 create_game_world() 返回这些任务对象
任务初始化修复:
在 play_game() 中调用 create_game_world() 获取任务对象
确保在添加任务到玩家时,这些任务已经被正确定义

六、总结

从写第一个Character类到最后修复完所有 bug,这游戏算是我用 Python 搞面向对象编程的练手大作”了。刚开始觉得类啊、对象啊挺抽象,写着写着发现,把游戏里的东西都当成 “对象” 来管,逻辑反而更清晰了。尤其是调试的时候,对着错误信息一点点改,那种解决问题后的成就感,跟游戏里打赢 boss 差不多!以后打算再学学网络编程和图形库,把这个游戏做得更热闹,也推荐大家试试自己写个小游戏,真的能学到超多东西!

七、参考资料

参考资料

  1. Python 面向对象编程在游戏开发中的应用 - CSDN 博客
  2. Python 随机数模块在游戏中的应用 - CSDN 博客
  3. Python 文本游戏的用户交互设计 - CSDN 博客
  4. Python 游戏中的任务系统设计 - CSDN 博客
  5. Python 程序调试与异常处理实战 - CSDN 博客
posted @ 2025-06-10 19:30  NA52651  阅读(49)  评论(0)    收藏  举报