回合制系统中while循环切换及递归函数报错问题求助
回合制舰船对战程序问题修复
原始代码
import numpy as np BB1turn = True BB2turn = False class BB1: def __init__(BB1, HP, DC): BB1.HP = HP BB1.DC = DC class BB2: def __init__(BB2, HP, DC): BB2.HP = HP BB2.DC = DC BB1 = BB1(6100, 22) BB2 = BB2(3000, 29) print("BB1's stats") print(BB1.HP) print(BB1.DC) print("") print("BB2's stats") print(BB2.HP) print(BB2.DC) print("") def BB1MainGunReload(hit): if hit > 0: result = hit + BB1MainGunReload(hit - 1) print("Your ship has", result, "turn(s) remaining before it can fire again.") elif hit == 0: values = randint(1, 30, 9) print(values) hit = np.int_([1, 1, 1, 1, 1, 1, 1, 1, 1]) hitpositive = hit[(values >= BB2.DC)] print(hitpositive) hits = len(hitpositive) print(hits, "hit(s)") damage = randint(1, 68, hits) print(damage) a = sum(damage) print(a) BB2.HP = BB2.HP - a print("BB2's HP is now", BB2.HP) hit = 3 def BB2MainGunReload(hit): if hit > 0: result = hit + BB2MainGunReload(hit - 1) print("Your ship has", result, "turn(s) remaining before it can fire again.") elif hit == 0: values = randint(1, 30, 9) print(values) hit = np.int_([1, 1, 1, 1, 1, 1, 1, 1, 1]) hitpositive = hit[(values >= BB1.DC)] print(hitpositive) hits = len(hitpositive) print(hits, "hit(s)") damage = randint(1, 68, hits) print(damage) a = sum(damage) print(a) BB1.HP = BB1.HP - a print("BB1's HP is now", BB1.HP) hit = 3 while BB1turn == True: print("") print("BB1's turn.") BB1MainGunReload(3) BB1turn = False BB2turn = True while BB2turn == True: print("") print("BB2's turn.") BB2MainGunReload(3) BB2turn = False BB1turn = True
遇到的问题
问题1:递归函数报错
调用函数传入参数3时,出现以下错误:
BB1's stats 6100 22 BB2's stats 3000 29 BB1's turn. [17 17 29 8 14 10 3 3 8] [1] 1 hit(s) [49] 49 BB2's HP is now 2951 Traceback (most recent call last): File "main.py", line 75, in <module> BB1MainGunReload(3) File "main.py", line 31, in BB1MainGunReload result = hit + BB1MainGunReload(hit - 1) File "main.py", line 31, in BB1MainGunReload result = hit + BB1MainGunReload(hit - 1) File "main.py", line 31, in BB1MainGunReload result = hit + BB1MainGunReload(hit - 1) TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
原因:递归的base case(hit == 0分支)没有返回值,当递归到hit=0时,函数返回None,上层调用hit + BB1MainGunReload(hit-1)尝试将整数与None相加,触发类型错误。同时递归逻辑完全错误,用递归模拟 reload 倒计时不合理,不需要累加返回值。
问题2:回合无法交替循环
传入参数0时,程序仅执行一轮回合后停止:
BB1's stats 6100 22 BB2's stats 3000 29 BB1's turn. [ 7 4 7 19 6 11 10 16 13] [] 0 hit(s) [] 0 BB2's HP is now 3000 BB2's turn. [14 1 3 29 8 21 16 14 4] [1] 1 hit(s) [52] 52 BB1's HP is now 6048
原因:使用了两个独立的while循环,第一个循环执行一次后切换回合状态,进入第二个循环;第二个循环执行一次后再次切换状态,但循环结束后程序直接退出,不会回到第一个循环。
修复方案
修复点说明
- 移除错误递归逻辑:用循环实现 reload 倒计时,避免递归返回值问题。
- 重构回合循环:改用单个主循环,判断游戏是否继续(双方HP均大于0),在循环内交替执行回合。
- 补全缺失的randint引用:统一使用
np.randint,因为代码仅导入了numpy。 - 规范类与实例命名:类名采用大驼峰命名,实例名用小写,避免命名冲突。
- 简化开火逻辑:函数专注于开火计算,倒计时逻辑移到回合循环中处理。
修复后的完整代码
import numpy as np # 规范类命名,合并重复的舰船类 class Battleship: def __init__(self, hp, dc): self.hp = hp self.dc = dc # 创建舰船实例 bb1 = Battleship(6100, 22) bb2 = Battleship(3000, 29) # 打印初始状态 print("BB1's stats") print(f"HP: {bb1.hp}, DC: {bb1.dc}") print("") print("BB2's stats") print(f"HP: {bb2.hp}, DC: {bb2.dc}") print("") def bb1_fire(): # 模拟9次命中判定 values = np.random.randint(1, 31, 9) print(f"Rolled values: {values}") # 筛选命中次数 hits = len(values[values >= bb2.dc]) print(f"{hits} hit(s)") # 计算伤害 if hits > 0: damage = np.random.randint(1, 69, hits) total_damage = sum(damage) print(f"Damage rolls: {damage}") print(f"Total damage: {total_damage}") bb2.hp -= total_damage else: total_damage = 0 print("No damage dealt") print(f"BB2's HP is now {bb2.hp}") def bb2_fire(): # 模拟9次命中判定 values = np.random.randint(1, 31, 9) print(f"Rolled values: {values}") # 筛选命中次数 hits = len(values[values >= bb1.dc]) print(f"{hits} hit(s)") # 计算伤害 if hits > 0: damage = np.random.randint(1, 69, hits) total_damage = sum(damage) print(f"Damage rolls: {damage}") print(f"Total damage: {total_damage}") bb1.hp -= total_damage else: total_damage = 0 print("No damage dealt") print(f"BB1's HP is now {bb1.hp}") def countdown(turns): # 实现倒计时打印 for i in range(turns, 0, -1): print(f"Your ship has {i} turn(s) remaining before it can fire again.") # 主游戏循环,控制回合交替 current_turn = "bb1" while bb1.hp > 0 and bb2.hp > 0: print("\n" + "-"*20) if current_turn == "bb1": print("BB1's turn.") countdown(3) bb1_fire() current_turn = "bb2" else: print("BB2's turn.") countdown(3) bb2_fire() current_turn = "bb1" # 游戏结束判定 print("\n" + "-"*20) if bb1.hp <= 0: print("BB2 wins!") else: print("BB1 wins!")
代码解释
- 类重构:将重复的BB1、BB2类合并为通用的
Battleship类,减少代码冗余。 - 开火函数:拆分原函数的递归和开火逻辑,让每个函数只负责单一功能,更易维护。
- 主循环:通过
current_turn变量控制回合交替,直到某艘舰船HP归0,确保循环持续执行。 - 倒计时逻辑:用
countdown函数实现倒计时打印,替代错误的递归逻辑。
内容的提问来源于stack exchange,提问作者Raging Ultimate
相关产品推荐
相关产品推荐

