You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

回合制系统中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循环,第一个循环执行一次后切换回合状态,进入第二个循环;第二个循环执行一次后再次切换状态,但循环结束后程序直接退出,不会回到第一个循环。

修复方案

修复点说明

  1. 移除错误递归逻辑:用循环实现 reload 倒计时,避免递归返回值问题。
  2. 重构回合循环:改用单个主循环,判断游戏是否继续(双方HP均大于0),在循环内交替执行回合。
  3. 补全缺失的randint引用:统一使用np.randint,因为代码仅导入了numpy。
  4. 规范类与实例命名:类名采用大驼峰命名,实例名用小写,避免命名冲突。
  5. 简化开火逻辑:函数专注于开火计算,倒计时逻辑移到回合循环中处理。

修复后的完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 22:27:20