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

如何终止Python棋盘游戏的无限循环?

问题解决:棋盘游戏地产售罄后终止逻辑修复

核心问题分析

原代码中判定所有地产售罄的条件错误:board_size=20但实际只有12个地产,遍历整个棋盘索引会包含非地产位置,导致all(...)永远为False,游戏陷入无限循环。同时,售罄后的胜负判定逻辑也存在计算错误。

修复方案

  1. 仅检查实际存在的地产对应的索引,而非整个棋盘大小
  2. 修正胜负判定时的最大值计算逻辑
  3. 添加地产售罄后的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:07:16