如何用字典存储带不同参数的多函数,实现卡牌技能调用逻辑?
卡牌系统函数参数传递解决方案
问题背景
现有卡牌库字典结构如下:
# 原卡牌库 _cardLibrary = { 1: {'name': 'Strike', 'cost': 1, 'type': 'attack', 'rarity': 'common', 'action': [deal_damage]}, 2: {'name': 'Defend', 'cost': 1, 'type': 'skill', 'rarity': 'common', 'action': [give_block]}, 3: {'name': 'Bash', 'cost': 2, 'type': 'attack', 'rarity': 'common', 'action': [deal_damage, apply_status]} }
需要实现use(caster, target, card_idx)函数,执行对应卡牌action中的所有函数。其中:
deal_damage(caster, target, basedamage)需要3个参数apply_status(caster, target, status, intensity)需要4个参数caster和target为调用时动态传入的公共参数,部分函数存在固定参数(如Bash的apply_status需固定status=1、intensity=1)
原方案仅存储函数对象,无法携带固定参数,导致无法匹配不同函数的参数要求。
推荐解决方案:元组存储「函数+固定参数」
直接修改卡牌库的action字段,将每个函数与它的固定参数打包成元组(格式:(函数名, *固定参数))。use函数统一将caster、target作为前置参数,拼接固定参数后调用函数,既保留字典式卡牌库的扩展性,又能灵活处理不同参数需求。
完整实现代码
# 定义基础功能函数 def deal_damage(caster, target, basedamage): print(f"{caster.name}对{target.name}造成{basedamage}点伤害") def give_block(caster, target, block_amount): print(f"{caster.name}获得{block_amount}点格挡") def apply_status(caster, target, status, intensity): print(f"{caster.name}给{target.name}施加状态{status},强度{intensity}") # 修改后的卡牌库:action字段存储(函数, 固定参数)元组 _cardLibrary = { 1: { 'name': 'Strike', 'cost': 1, 'type': 'attack', 'rarity': 'common', 'action': [(deal_damage, 3)] # 固定基础伤害为3 }, 2: { 'name': 'Defend', 'cost': 1, 'type': 'skill', 'rarity': 'common', 'action': [(give_block, 5)] # 固定格挡值为5 }, 3: { 'name': 'Bash', 'cost': 2, 'type': 'attack', 'rarity': 'common', 'action': [ (deal_damage, 4), # 固定基础伤害为4 (apply_status, 1, 1) # 固定状态为1、强度为1 ] } } # 实现use函数 def use(caster, target, card_idx): card = _cardLibrary.get(card_idx) if not card: print("无效卡牌索引") return # 遍历每个action元组,拼接参数并调用 for func, *fixed_args in card['action']: func(caster, target, *fixed_args)
测试调用示例
# 模拟施法者和目标角色 class Character: def __init__(self, name): self.name = name player = Character("玩家") enemy = Character("史莱姆") # 使用Bash卡牌(索引3) use(player, enemy, 3)
运行结果:
玩家对史莱姆造成4点伤害 玩家给史莱姆施加状态1,强度1
可选方案:使用functools.partial预绑定参数
如果不想修改action的结构(仍仅存储函数对象),可以用functools.partial提前将固定参数绑定到函数上,生成新的可调用对象。
示例代码
from functools import partial # 预绑定固定参数 strike_action = partial(deal_damage, basedamage=3) defend_action = partial(give_block, block_amount=5) bash_action1 = partial(deal_damage, basedamage=4) bash_action2 = partial(apply_status, status=1, intensity=1) # 卡牌库 _cardLibrary = { 1: {'name': 'Strike', 'cost':1, 'type':'attack', 'rarity':'common', 'action': [strike_action]}, 2: {'name': 'Defend', 'cost':1, 'type':'skill', 'rarity':'common', 'action': [defend_action]}, 3: {'name': 'Bash', 'cost':2, 'type':'attack', 'rarity':'common', 'action': [bash_action1, bash_action2]} } # 简化后的use函数 def use(caster, target, card_idx): card = _cardLibrary.get(card_idx) if not card: return for func in card['action']: func(caster, target)
方案对比
- 元组方案:直观易懂,无需额外依赖,扩展性强,新增卡牌时直接添加「函数+固定参数」元组即可。
- partial方案:代码更简洁,但需要提前预绑定参数,适合固定参数不常变动的场景。
内容的提问来源于stack exchange,提问作者Lilac Wine
相关产品推荐
相关产品推荐

