优化Python随机宝可梦遭遇系统:避免重复显示与代码重构

优化Python随机宝可梦遭遇系统:避免重复显示与代码重构

本文针对python中随机宝可梦遭遇系统出现的重复显示问题进行深入分析,揭示了硬编码和代码冗余带来的弊端。通过引入面向对象编程(oop)思想,设计`pokemon`类封装宝可梦属性,并利用数据驱动的方法构建`pokedex`数据结构,实现了代码的模块化、可维护性和可扩展性。最终提供了一个清晰、高效的解决方案,彻底消除了重复显示,并优化了整体代码结构。

随机宝可梦遭遇系统的问题分析

在开发一个随机宝可梦遭遇系统时,常见的挑战是如何高效且无误地根据随机数显示对应的宝可梦及其属性。原始代码中存在一个显著问题:无论随机到哪只宝可梦,”Pidgey”(波波)的信息总是会一同显示。

原始代码结构与缺陷

分析原始代码,其核心逻辑是通过一系列if/elif语句判断一个随机生成的数字variables.random_pokemon_counter,然后根据匹配的数字来设置对应的宝可梦信息并打印出来。

def random_pokemon_for_battle():    variables.random_pokemon_counter = random.randint(1, 6)    if variables.random_pokemon_counter == 1:        # ... Pidgey 相关的代码 ...        print("A wild Pidgey appeared!") # Pidgey 自己的显示        # ...    elif variables.random_pokemon_counter == 2:        # ... Weedle 相关的代码 ...        print("A wild Pidgey appeared!") # 错误地显示了 Pidgey        # ...    elif variables.random_pokemon_counter == 3:        # ... Pikachu 相关的代码 ...        print("A wild Pidgey appeared!") # 错误地显示了 Pidgey        # ... (其他 elif 分支类似)

主要问题点:

重复的打印语句: 在每一个elif分支中,除了打印当前随机到的宝可梦信息外,都错误地包含了一行 print(“A wild Pidgey appeared!”)。这是导致无论哪只宝可梦出现,波波都会被额外显示出来的直接原因。代码冗余: 每个宝可梦的属性(等级、HP、攻击、防御)的生成逻辑都是相同的,只是变量名不同(如variables.pidgey_level, variables.weedle_level)。这种重复的代码块使得维护和扩展变得困难。硬编码: 宝可梦的名称、音效文件路径以及它们的编号(1到6)都是硬编码在if/elif结构中的,这使得添加新的宝可梦或修改现有宝可梦信息时需要修改大量的代码。全局变量滥用: 大量使用variables.前缀的全局变量来存储宝可梦属性,这可能导致变量名冲突、代码可读性差以及状态管理混乱。

解决方案:面向对象与数据驱动设计

为了解决上述问题,我们可以采用面向对象编程(OOP)和数据驱动的设计模式。

立即学习“Python免费学习笔记(深入)”;

1. 定义 Pokemon 类

创建一个Pokemon类来封装每只宝可梦的属性和行为。这样,每只宝可梦都将是一个独立的Pokemon对象,拥有自己的名称、等级、生命值、攻击力、防御力及音效。

import randomimport winsound # 假设 winsound 模块用于播放声音# 假设 sounds 模块存在,并包含对应的音效文件路径# import sounds # 实际项目中需要根据文件结构导入# 示例:class MockSounds:    pidgey_sound = "pidgey.wav"    weedle_sound = "weedle.wav"    pikachu_sound = "pikachu.wav"    nidoran_male_sound = "nidoran_m.wav"    nidoran_female_sound = "nidoran_f.wav"    caterpie_sound = "caterpie.wav"sounds = MockSounds() # 在实际项目中替换为真实的 sounds 模块导入class Pokemon:    """    表示一只宝可梦的类,封装其名称、等级、生命值、攻击力、防御力及音效。    """    def __init__(self, name: str, sound_path: str):        self.name = name        self.level = random.randint(1, 10)        self.hp = 100        self.attack = random.randint(10, 25)        self.defense = random.randint(15, 35)        self.sound = sound_path    def play_sound(self):        """播放宝可梦的音效。"""        try:            winsound.PlaySound(self.sound, winsound.SND_FILENAME)        except Exception as e:            print(f"无法播放 {self.name} 的音效: {e}")    def display_info(self):        """显示宝可梦的遭遇信息和属性。"""        print(f"A wild {self.name} appeared!")        print(f"Level: {self.level}")        print(f"HP: {self.hp}")        print(f"Attack: {self.attack}")        print(f"Defense: {self.defense}")

2. 构建 pokedex 数据结构

使用一个列表来存储所有可遭遇宝可梦的基础数据。每个元素可以是一个元组或字典,包含宝可梦的名称和对应的音效文件路径。

pokedex_data = [    ("Pidgey", sounds.pidgey_sound),    ("Weedle", sounds.weedle_sound),    ("Pikachu", sounds.pikachu_sound),    ("Nidoran_M", sounds.nidoran_male_sound),    ("Nidoran_F", sounds.nidoran_female_sound),    ("Caterpie", sounds.caterpie_sound)]

这种数据结构使得添加、删除或修改宝可梦变得非常简单,只需修改pokedex_data列表即可,无需触碰核心逻辑代码。

3. 重构随机遭遇函数

利用random.choice()方法从pokedex_data中随机选择一个宝可梦的数据,然后用这些数据来实例化一个Pokemon对象。

def random_pokemon_for_battle() -> Pokemon:    """    随机生成一只宝可梦,播放其音效并显示其属性。    返回生成的 Pokemon 对象。    """    # 从 pokedex_data 中随机选择一个宝可梦的数据 (名称, 音效路径)    chosen_pokemon_data = random.choice(pokedex_data)    # 使用选中的数据创建 Pokemon 对象    # *chosen_pokemon_data 会将元组解包为 Pokemon 类的构造函数参数    poke = Pokemon(*chosen_pokemon_data)    # 播放音效    poke.play_sound()    # 显示宝可梦信息    poke.display_info()    return poke

完整代码示例

将以上组件整合,形成一个完整、优化后的随机宝可梦遭遇系统。

import randomimport winsound# 模拟 sounds 模块,实际项目中应根据文件结构导入class MockSounds:    pidgey_sound = "pidgey.wav"    weedle_sound = "weedle.wav"    pikachu_sound = "pikachu.wav"    nidoran_male_sound = "nidoran_m.wav"    nidoran_female_sound = "nidoran_f.wav"    caterpie_sound = "caterpie.wav"sounds = MockSounds()class Pokemon:    """    表示一只宝可梦的类,封装其名称、等级、生命值、攻击力、防御力及音效。    """    def __init__(self, name: str, sound_path: str):        self.name = name        self.level = random.randint(1, 10)        self.hp = 100        self.attack = random.randint(10, 25)        self.defense = random.randint(15, 35)        self.sound = sound_path    def play_sound(self):        """播放宝可梦的音效。"""        try:            winsound.PlaySound(self.sound, winsound.SND_FILENAME)        except Exception as e:            print(f"无法播放 {self.name} 的音效: {e}")    def display_info(self):        """显示宝可梦的遭遇信息和属性。"""        print(f"A wild {self.name} appeared!")        print(f"Level: {self.level}")        print(f"HP: {self.hp}")        print(f"Attack: {self.attack}")        print(f"Defense: {self.defense}")# 宝可梦数据列表pokedex_data = [    ("Pidgey", sounds.pidgey_sound),    ("Weedle", sounds.weedle_sound),    ("Pikachu", sounds.pikachu_sound),    ("Nidoran_M", sounds.nidoran_male_sound),    ("Nidoran_F", sounds.nidoran_female_sound),    ("Caterpie", sounds.caterpie_sound)]def random_pokemon_for_battle() -> Pokemon:    """    随机生成一只宝可梦,播放其音效并显示其属性。    返回生成的 Pokemon 对象。    """    chosen_pokemon_data = random.choice(pokedex_data)    poke = Pokemon(*chosen_pokemon_data)    poke.play_sound()    poke.display_info()    return poke# 示例调用print("--- 第一次遭遇 ---")encountered_pokemon_1 = random_pokemon_for_battle()print("n--- 第二次遭遇 ---")encountered_pokemon_2 = random_pokemon_for_battle()

可能的输出:

--- 第一次遭遇 ---无法播放 Pidgey 的音效: [WinError 2] 系统找不到指定的文件。A wild Pidgey appeared!Level: 7HP: 100Attack: 15Defense: 28--- 第二次遭遇 ---无法播放 Caterpie 的音效: [WinError 2] 系统找不到指定的文件。A wild Caterpie appeared!Level: 3HP: 100Attack: 22Defense: 19

(注:winsound模块在没有对应.wav文件时会报错,此处为了演示,已在play_sound中添加了错误处理。)

总结与注意事项

通过引入Pokemon类和pokedex_data列表,我们实现了以下改进:

消除重复显示: 每个宝可梦的信息打印都由其自身的display_info方法负责,确保只显示当前遭遇的宝可梦。代码去重: 宝可梦属性的生成逻辑被封装在Pokemon类的构造函数中,避免了冗余的if/elif分支代码。提高可维护性: 增加或修改宝可梦信息只需修改pokedex_data列表,无需改动函数逻辑。增强可读性: 代码结构更清晰,每个部分职责明确。更好的扩展性: 未来可以轻松添加更多宝可梦,甚至从外部文件(如JSON, CSV)加载pokedex_data,实现更灵活的数据管理。

注意事项:

音效文件: 确保sounds模块中引用的.wav文件实际存在于项目的正确路径中,否则winsound.PlaySound会抛出FileNotFoundError。在生产环境中,应加入更健壮的错误处理机制。数据源: 对于大型游戏项目,建议将pokedex_data存储在外部配置文件(如JSON、YAML或数据库)中,而不是硬编码在Python脚本里。这样可以实现数据的动态加载和独立更新。变量作用域 避免在函数内部使用全局变量来存储临时状态,如原始代码中的variables.random_pokemon_counter和variables.random_pokemon_encounter。通过函数返回值或对象属性来管理状态是更推荐的做法。

这种面向对象和数据驱动的重构方法不仅解决了特定的显示问题,更从根本上提升了代码质量,使其更符合现代软件开发的最佳实践。

以上就是优化Python随机宝可梦遭遇系统:避免重复显示与代码重构的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1379906.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 21:03:19
下一篇 2025年12月14日 21:03:37

相关推荐

  • 在Python Flask中实现在线图片URL到Blurhash编码

    本教程详细介绍了如何在python flask应用中,将在线图片url转换为blurhash键。针对官方文档主要侧重本地文件处理的局限,文章通过整合`requests`库下载图片内容和`blurhash-python`库进行编码,提供了完整的解决方案,并包含代码示例、依赖安装、错误处理及在flask…

    好文分享 2025年12月14日
    000
  • python虚拟环境如何激活

    使用venv或virtualenv时,Windows用your_venvScriptsactivate,macOS/Linux用source your_venv/bin/activate;2. 使用conda时用conda activate env_name;3. 退出均用deactivate。 在…

    2025年12月14日
    000
  • Django ListView中按用户ID或外键过滤QuerySet的最佳实践

    本教程详细阐述了在django类视图(listview)中根据用户id或外键高效过滤queryset的方法。核心在于通过重写视图的`get_queryset`方法,结合`loginrequiredmixin`确保用户认证,从而实现基于当前请求用户关联数据的精准筛选。文章将提供示例代码并强调相关最佳实…

    2025年12月14日
    000
  • Python批量重命名:高效移除文件名指定前缀

    本教程详细介绍了如何使用python批量移除文件名的特定前缀。通过结合`os`模块的文件操作和`fnmatch`模块的模式匹配功能,您可以轻松识别并重命名文件夹中符合特定模式的文件,从而实现自动化、高效的文件管理。文章提供了清晰的步骤和示例代码,并强调了操作前的注意事项,确保安全有效地完成文件重命名…

    2025年12月14日
    000
  • Python循环中列表追加与中断条件的执行顺序解析

    本文深入探讨了Python循环中列表元素追加操作与`break`条件判断的执行顺序问题。通过一个具体的`while`循环示例,文章解释了为何即使满足中断条件,不期望的值仍可能被添加到列表中。核心在于理解代码的顺序执行,并提供了通过调整`append`和`break`语句位置来确保逻辑正确性的解决方案…

    2025年12月14日
    000
  • 使用 Selenium 自动化展开动态下拉菜单并抓取子类别链接

    本教程详细介绍了如何使用 selenium 自动化处理动态网页中的多层下拉菜单,以获取所有子类别链接。核心步骤包括识别并迭代点击展开图标,确保在动态加载内容后重新定位元素,然后从展开的菜单中筛选并提取目标链接。文章提供了详细的代码示例和实现策略,帮助读者高效地抓取复杂网页结构中的数据。 使用 Sel…

    2025年12月14日
    000
  • Odoo QWeb模板中浮点数到整数的正确显示方法

    本文旨在解决odoo qweb报表或视图中将浮点数转换为整数后无法正确显示的问题。核心在于理解qweb指令`t-value`和`t-esc`的区别。通过使用`t-esc`指令结合python内置的`int()`函数,开发者可以确保转换后的整数值被正确渲染并显示在odoo模板中,避免只显示占位符或空值…

    2025年12月14日
    000
  • Python中高效解决队列元素交换问题:理解与应用str.replace()

    本文旨在解决一个常见的编程挑战:在给定时间内,对包含’B’和’G’元素的队列进行条件性交换,即当’B’后跟’G’时,它们交换位置,且每轮操作中每个’BG’对只交换一次。文章将分析传…

    2025年12月14日
    000
  • PyQuery教程:如何自定义User-Agent以模拟浏览器行为

    本教程详细介绍了如何在pyquery库中设置自定义user-agent字符串,以模拟真实的浏览器请求行为。通过在pyquery初始化时传入headers参数,您可以轻松配置user-agent,从而有效避免爬虫被识别,并获取更准确的网页内容。文章包含代码示例及网页解析实践。 理解User-Agent…

    2025年12月14日
    000
  • Pandas教程:高效整合多维NumPy数组列表为带标签的DataFrame

    本教程详细介绍了如何将一个包含多个形状不一的numpy数组的列表,高效地转换为一个统一的pandas dataframe。核心方法是利用`pd.concat`结合字典推导式,为每个原始数组生成唯一的标识符,并将其作为新列添加到最终的dataframe中。文章涵盖了数据准备、分步实现、列重命名以及重要…

    2025年12月14日
    000
  • Python循环中break语句与列表追加顺序的陷阱解析

    本文深入探讨python循环中使用`break`语句时,由于操作顺序不当,导致不期望的值被追加到列表中的常见问题。通过分析正弦函数计算示例,揭示了`append`操作在条件判断之前的执行逻辑,并提供了将`append`移至条件判断之后的解决方案,以确保列表仅包含符合条件的元素,从而避免程序行为与预期…

    2025年12月14日
    000
  • 解决Google Colab中Gemini AI连接错误及API调用优化策略

    在google colab中使用gemini ai时,开发者常遇到`internalservererror`或`networkerror`,尤其是在调用`list_models`或`generate_content`时。这些错误通常源于瞬时网络问题或服务器端不稳定。本文提供了一种健壮的解决方案,通过…

    2025年12月14日
    000
  • PySpark Pandas UDF:正确应用自定义函数到DataFrame列

    本文详细阐述了在pyspark中使用pandas udf时,如何正确将自定义函数应用于dataframe列。核心问题在于理解pandas udf接收pandas series作为输入,而非单个字符串。文章通过示例代码演示了如何重构udf,使其能够高效地处理series数据,并提供了调试技巧,以避免常…

    2025年12月14日
    000
  • Python编程实践:高效且正确地统计数组元素频率

    本教程旨在解决python中统计数组元素频率时常见的索引误用问题。我们将深入分析`for…in`循环中变量的正确使用方式,通过对比错误与正确的代码示例,详细解释如何构建准确的元素频率映射。文章还将介绍python标准库`collections.counter`这一更简洁高效的实现方法,帮…

    2025年12月14日
    000
  • Python中安全重定向sys.stderr并避免I/O错误

    本文旨在解决Python中重定向`sys.stderr`到文件时常见的`ValueError: I/O operation on closed file`错误。我们将深入分析错误原因,并提供两种安全、健壮的解决方案:推荐使用`contextlib.redirect_stderr`上下文管理器,以及一…

    2025年12月14日
    000
  • 解决Discord机器人事件重复触发问题:正确使用@bot.event装饰器

    在使用disnake或discord.py构建discord机器人时,开发者常会遇到事件(如`on_presence_update`)重复触发的问题。这通常是由于在事件装饰器`@bot.event`后错误地添加了括号`()`所致。本文将深入解析这一常见误区,解释`@bot.event`与`@bot.…

    2025年12月14日
    000
  • 将字典列表转换为按键分组的NumPy数组

    本文详细介绍了如何将一个包含多个单键字典的列表,高效地转换为一个以原字典键为索引、值为对应NumPy数组的字典结构。通过迭代分组和类型转换两步,实现数据从扁平化字典列表到按类别聚合的数值数组的重塑,这对于数据预处理和分析任务至关重要。 在数据处理和分析的场景中,我们经常会遇到需要将特定格式的原始数据…

    2025年12月14日
    000
  • Python测试依赖管理:使用pyproject.toml的最佳实践

    本文旨在解决python测试依赖管理中普遍存在的混乱局面,并提出一种基于`pyproject.toml`和`[project.optional-dependencies]`的现代最佳实践。通过将测试依赖声明为可选依赖项,并结合`pip`和`tox`等工具进行安装和管理,可以实现清晰、可维护且符合py…

    2025年12月14日
    000
  • 二叉树等和分割问题:从递归陷阱到高效解法

    本文深入探讨了如何通过移除一条边将二叉树分割成两个和相等的子树。文章首先分析了递归解法中常见的错误,如不正确的边移除逻辑和递归参数传递问题,并提供了修正后的代码。随后,引入了一种更高效的算法,通过一次性自底向上计算所有子树的和来避免重复计算,从而优化了时间复杂度,并给出了相应的python实现。 二…

    2025年12月14日
    000
  • Keras安装失败:Python版本兼容性与dm-tree构建问题解析

    本教程旨在解决在python 3.12环境下安装keras时遇到的`dm-tree`构建失败问题。此类错误通常表现为缺少cmake或编译工具,导致依赖包无法成功编译。文章将深入分析问题根源,并提供一个经过验证的解决方案:通过降级python版本至3.11.x来确保keras及其复杂依赖的顺利安装,同…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信