Python开发DnD 4d6弃最低掷骰工具自选属性分配功能异常排查
问题排查结果
两个核心逻辑缺陷直接导致自选属性分配功能完全失效:
1. 数据类型不匹配,所有判断永久失效
- 候选值列表
val存储的是掷骰求和得到的整数类型属性值(比如13、15) - 通过
input()获取的用户输入值dic是字符串类型(比如用户输入13,程序拿到的是字符串"13") - Python不会对字符串和整数做隐式类型转换,执行
if dic in val做成员判断时,两种类型的对象永远无法匹配,因此代码始终走非法输入分支,既不会触发属性字典的赋值操作,也不会触发候选列表的元素移除逻辑。 - 即使强行跳过判断执行赋值,
x[stat] += dic也会因为整数和字符串做加法直接抛出TypeError,完全无法完成属性值写入。
2. 输入校验逻辑缺失,无异常拦截
- 原代码没有对用户的非数字输入做异常捕获,一旦用户输入无法转成数字的内容,程序会直接崩溃,不会给出友好提示引导重新输入。
- 原循环没有针对单个属性的输入做重试机制,一旦输入非法值,虽然会打印提示,但程序会直接进入下一个属性的分配流程,没有给用户修正的机会。
修正后的可用函数
# 4d6 drop lowest, choose stats def m4d6c(x): val = [] # 生成6份4d6弃最低的合规属性值作为候选 for _ in range(6): rolls = [] for _ in range(4): r = random.randint(1, 6) rolls.append(r) # 移除最低掷骰值后求和 del rolls[rolls.index(min(rolls))] val.append(sum(rolls)) # 遍历所有属性完成用户自选分配 for stat in x: # 单个属性的输入循环,校验通过才退出 while True: print(f"当前剩余可选值:{val}") user_input = input(f"请为{stat}选择分配值:") # 拦截非数字输入,转成和候选列表一致的整数类型 try: selected_value = int(user_input) except ValueError: print("请输入列表中存在的有效数字!") continue # 校验选中值是否在候选列表中 if selected_value in val: x[stat] = selected_value val.remove(selected_value) break else: print("请选择当前列表内的属性值!") return x
修正的核心调整:
- 用户输入拿到后先通过
try-except做整数转换,保证和候选列表的元素类型完全一致,从根上解决判断不匹配的问题 - 把原有的累加赋值逻辑改成直接对属性键赋值,避免初始值和输入值的类型冲突
- 为单个属性的分配环节增加循环校验,只有输入合法值才会进入下一个属性的分配流程,不会因为非法输入提前跳出或崩溃
- 简化了原循环中冗余的变量累加逻辑,直接将掷骰求和结果存入候选列表,提升代码可读性
内容的提问来源于stack exchange,提问作者Fredrick Gootkind
相关产品推荐
相关产品推荐

