Python双人文本回合制格斗游戏:修复生命值扣除TypeError报错
问题分析与修复方案
核心错误原因
触发TypeError: unsupported operand type(s) for -=: 'str' and 'str'的直接原因是这行完全错误的代码:
"defender_health"[0] -= "int";magnitude
"defender_health"是字符串字面量,不是可操作的变量,无法通过下标修改或执行减法运算"int";magnitude是语法混乱的写法,分号在这里无意义,且试图用字符串和整数做运算,完全不符合Python语法规范
修复步骤
1. 关联防御方对应生命值
在perform_attack函数中,需要根据传入的defender参数,判断要修改的是player1_health还是player2_health,再执行生命值扣除操作。
2. 修正攻击逻辑代码
替换错误的扣除代码,改为根据防御方匹配对应的生命值列表,执行合法的减法运算:
# 替换原来的错误行 if defender == player1_name: player1_health[0] -= magnitude else: player2_health[0] -= magnitude
3. 优化:限制生命值下限
为避免生命值出现负数,可在扣除后将生命值限制为0:
if defender == player1_name: player1_health[0] = max(0, player1_health[0] - magnitude) else: player2_health[0] = max(0, player2_health[0] - magnitude)
修复后的完整代码
import random def get_valid_name(existing_names): while True: name = input("Please type your hero’s name: ") if name and name not in existing_names: return name elif name in existing_names: print(f"{name} is taken, please choose another name!") def perform_attack(attacker: any, defender: any) -> None: magnitude = int(input(f"————— {attacker} Attacks !! —————\nChoose your attack magnitude between 1 and 50: ")) if 1 <= magnitude <= 50: success_chance = random.randint(1, 100) if success_chance <= (100 - magnitude): print(f"{attacker} hits {magnitude} damage!!!") # 修复:根据防御方正确扣除生命值 if defender == player1_name: player1_health[0] = max(0, player1_health[0] - magnitude) else: player2_health[0] = max(0, player2_health[0] - magnitude) else: print(f"Ooopsy! {attacker} missed the attack!") print_status(player1_name, player2_name) else: print("The attack magnitude must be between 1 and 50. Choose your attack magnitude between 1 and 50:") def print_status(player1, player2): print(f"\n{player1} {' ' * 57} {player2}\nHP[{player1_health[0]}]: {'I' * (player1_health[0] // 2)} " f"HP[{player2_health[0]}]: {'I' * (player2_health[0] // 2)}") def coin_toss(): return random.choice([player1_name, player2_name]) def game_over(): print("#" * 70) print(f"{winner} Wins !!!") print("#" * 70) print("\nThanks for playing! See you again!") player1_name = get_valid_name([]) player2_name = get_valid_name([player1_name]) player1_health = [100] player2_health = [100] current_player = coin_toss() print(f"Coin toss result: {current_player} starts first!") print_status(player1_name, player2_name) while True: if current_player == player1_name: perform_attack(player1_name, player2_name) if player2_health[0] <= 0: winner = player1_name game_over() break current_player = player2_name else: perform_attack(player2_name, player1_name) if player1_health[0] <= 0: winner = player2_name game_over() break current_player = player1_name play_again = input("Do you want to play another round (Yes or No)? ").lower() if play_again != 'yes': print("\nThanks for playing! See you again!") break else: player1_health = [100] player2_health = [100] current_player = coin_toss() print(f"Coin toss result: {current_player} starts first!") print_status(player1_name, player2_name)
额外说明
- 使用列表存储生命值(如
player1_health = [100])是因为列表是可变类型,函数中修改列表元素会直接影响全局变量的值 - 加入
max(0, ...)是为了保证生命值不会出现负数,避免状态显示异常
内容的提问来源于stack exchange,提问作者Esmund
相关产品推荐
相关产品推荐

