如何终止Python棋盘游戏的无限循环?
问题解决:棋盘游戏地产售罄后终止逻辑修复
核心问题分析
原代码中判定所有地产售罄的条件错误:board_size=20但实际只有12个地产,遍历整个棋盘索引会包含非地产位置,导致all(...)永远为False,游戏陷入无限循环。同时,售罄后的胜负判定逻辑也存在计算错误。
修复方案
- 仅检查实际存在的地产对应的索引,而非整个棋盘大小
- 修正胜负判定时的最大值计算逻辑
- 添加地产售罄后的10轮倒计时逻辑,符合需求描述
修改后的完整代码
# 导入模块 from random import randint # 定义棋盘大小 board_size = 20 # 玩家设置 num_players = 4 player_funds = [250] * num_players players_position = [0] * num_players # 地产数据 property_prices = { "Property 1": {"cost": 100, "rent": 20, "category": "Category 1", 'owner': None}, "Property 2": {"cost": 150, "rent": 30, "category": "Category 1", 'owner': None}, "Property 3": {"cost": 200, "rent": 40, "category": "Category 1", 'owner': None}, "Property 4": {"cost": 250, "rent": 50, "category": "Category 2", 'owner': None}, "Property 5": {"cost": 200, "rent": 40, "category": "Category 2", 'owner': None}, "Property 6": {"cost": 120, "rent": 24, "category": "Category 2", 'owner': None}, "Property 7": {"cost": 200, "rent": 40, "category": "Category 3", 'owner': None}, "Property 8": {"cost": 180, "rent": 36, "category": "Category 3", 'owner': None}, "Property 9": {"cost": 100, "rent": 20, "category": "Category 3", 'owner': None}, "Property 10": {"cost": 150, "rent": 30, "category": "Category 4", 'owner': None}, "Property 11": {"cost": 200, "rent": 40, "category": "Category 4", 'owner': None}, "Property 12": {"cost": 200, "rent": 40, "category": "Category 4", 'owner': None}, } # 地产所有权记录(-1表示未被购买) property_ownership = [-1] * board_size # 获取所有地产对应的索引列表 property_indices = [int(prop.split()[1]) - 1 for prop in property_prices.keys()] # 掷骰子函数 def roll_dice(): return randint(1,6) # 效果格定义 effect_tiles = ['前进2格', '前进3格', '获得50金币', '支付10手续费', '回到起点并获得50金币', '重新掷骰子'] # 效果处理函数 def effect_function(player): effect_index = players_position[player] % board_size effect = effect_tiles[effect_index] if effect == '前进2格': players_position[player] += 2 elif effect == '前进3格': players_position[player] += 3 elif effect == '获得50金币': player_funds[player] += 50 elif effect == '支付10手续费': player_funds[player] -= 10 elif effect == '回到起点并获得50金币': players_position[player] = 0 player_funds[player] += 50 elif effect == '重新掷骰子': print(f'玩家 {player+1} 触发效果:{effect}') return True print(f'玩家 {player+1} 触发效果:{effect}') return False # 游戏主循环 current_player = 0 # 新增:地产售罄后的剩余轮次计数 remaining_rounds = 0 game_ending = False while True: player = current_player % num_players # 处理游戏结束前的10轮 if game_ending: if remaining_rounds <= 0: # 结束游戏,判定胜者 max_money = max(player_funds) winners = [i + 1 for i, fund in enumerate(player_funds) if fund == max_money] print("\n=== 游戏结束 ===") if len(winners) == 1: print(f'玩家 {winners[0]} 获胜!持有 {max_money} 金币') else: print(f'平局!获胜玩家:{", ".join(map(str, winners))},均持有 {max_money} 金币') break remaining_rounds -= 1 dice_roll = roll_dice() players_position[player] += dice_roll players_position[player] %= board_size # 回到起点奖励 if players_position[player] == 0: player_funds[player] += 50 print(f'玩家 {player+1} 回到起点,获得50金币!') # 触发效果格 if players_position[player] < len(effect_tiles): roll_again = effect_function(player) if roll_again: rolls = 1 while rolls < 3: dice_roll = roll_dice() players_position[player] += dice_roll players_position[player] %= board_size if players_position[player] < len(effect_tiles): roll_again = effect_function(player) if not roll_again: break rolls += 1 # 处理地产格 property_index = players_position[player] property_name = f'Property {property_index + 1}' # 地产已被他人持有,支付租金 if property_name in property_prices and property_ownership[property_index] != -1 and property_ownership[property_index] != player: owner = property_ownership[property_index] property_rent = property_prices[property_name]["rent"] # 检查是否拥有同类别全部地产,租金翻倍 category = property_prices[property_name]['category'] category_properties = [prop for prop in property_prices if property_prices[prop]['category'] == category] owns_all = True for prop in category_properties: idx = int(prop.split()[1]) -1 if property_ownership[idx] != owner: owns_all = False break if owns_all: property_rent *= 2 print(f'玩家 {owner+1} 拥有同类别全部地产,租金翻倍!') player_funds[player] -= property_rent player_funds[owner] += property_rent print(f'玩家 {player+1} 支付玩家 {owner+1} {property_rent} 租金,剩余金币:{player_funds[player]}') print(f'玩家 {owner+1} 获得租金,当前金币:{player_funds[owner]}') # 地产未被持有,询问购买 if property_name in property_prices and property_ownership[property_index] == -1: property_cost = property_prices[property_name]["cost"] purchase_choice = input(f'玩家 {player+1},你 landed on 未被购买的地产 {property_index+1}\n' f'价格 {property_cost},你当前有 {player_funds[player]} 金币,是否购买?(y/n)') if purchase_choice.lower() == 'y': if player_funds[player] >= property_cost: player_funds[player] -= property_cost property_ownership[property_index] = player property_prices[property_name]['owner'] = player print(f'玩家 {player+1} 成功购买 {property_name}') else: print('你金币不足,无法购买该地产') # 显示当前状态 print(f"玩家 {player+1}:当前位置 {players_position[player]},持有金币 {player_funds[player]}") print('-'*30) # 处理玩家破产 if player_funds[player] < 0: print(f'玩家 {player+1} 金币不足,被淘汰!') # 回收该玩家的地产 for idx in property_indices: if property_ownership[idx] == player: property_ownership[idx] = -1 property_prices[f'Property {idx+1}']['owner'] = None # 移除玩家数据 del player_funds[player] del players_position[player] num_players -= 1 current_player -= 1 # 只剩一名玩家直接获胜 if num_players == 1: print(f'\n=== 游戏结束 ===') print(f'玩家 {current_player+1} 获胜!持有 {player_funds[0]} 金币') break # 检查所有地产是否售罄,触发结束倒计时 if not game_ending and all(property_ownership[idx] != -1 for idx in property_indices): print('\n所有地产已被购买!剩余10轮后游戏结束,金币最多的玩家获胜') game_ending = True remaining_rounds = 10 * num_players # 每个玩家一轮,共10轮 current_player += 1
关键修改点说明
- 修正售罄判定逻辑:仅遍历实际存在的地产索引
property_indices,确保能正确触发游戏结束条件 - 新增10轮倒计时:地产售罄后启动10轮倒计时(每个玩家行动一次算一轮),倒计时结束后判定胜者
- 修复租金翻倍逻辑:正确检查玩家是否拥有同类别全部地产,避免逻辑错误
- 修复破产地产回收逻辑:统一回收破产玩家的所有地产,重置为未购买状态
- 修正胜负判定计算:取所有玩家金币的最大值,而非当前玩家的金币值,确保结果准确
内容的提问来源于stack exchange,提问作者APIAmber
相关产品推荐
相关产品推荐

