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

Python井字棋开发:函数内修改外部变量值的持久化问题

井字棋变量持久化及逻辑修正方案

问题根源

  1. answers1未声明全局:你在player_turn函数内重新创建了局部的answers1,外部的全局answers1完全没被更新,导致判定逻辑一直用初始的[0,0,0,0,0]。
  2. count变量无法累计回合:每次调用player_turn时,count都会被重置为0再加1,永远等于1,只有answer1会被赋值,其他answer变量始终是初始值0。
  3. 获胜判定逻辑错误:or的优先级低于==,原代码的条件写法实际是判断(win1common) or (win2common) ... or (win8common ==3),只要有一个非0值就会触发"X win",逻辑完全错误。

修复后的代码

line1 = (" 1  | 2  | 3 ")
line2 = ("----|----|----")
line3 = (" 4  | 5  | 6 ")
line4 = ("----|----|----")
line5 = (" 7  | 8  | 9 ")

lines = [line1, line2, line3, line4, line5]

# 用列表存储玩家落子,比单个变量更简洁
player_moves = []

for word in lines:
    print(word)

# 全局回合计数器,记录当前是第几次落子
turn_count = 0

def player_turn():
    global line1, line3, line5, turn_count, player_moves
    
    turn_count += 1
    player_input = int(input("请输入落子位置(1-9): "))
    
    # 用字典映射位置到对应的行和数字,减少冗余代码
    position_map = {
        1: (line1, '1'),
        2: (line1, '2'),
        3: (line1, '3'),
        4: (line3, '4'),
        5: (line3, '5'),
        6: (line3, '6'),
        7: (line5, '7'),
        8: (line5, '8'),
        9: (line5, '9'),
    }
    
    target_line, target_num = position_map[player_input]
    # 根据位置更新对应的行
    if target_line is line1:
        global line1
        line1 = line1.replace(target_num, 'X')
    elif target_line is line3:
        global line3
        line3 = line3.replace(target_num, 'X')
    elif target_line is line5:
        global line5
        line5 = line5.replace(target_num, 'X')
    
    # 记录玩家的落子
    if turn_count <= len(player_moves):
        player_moves[turn_count-1] = player_input
    else:
        player_moves.append(player_input)
    
    # 更新棋盘并打印
    updated_lines = [line1, line2, line3, line4, line5]
    for word in updated_lines:
        print(word)

def check_win():
    win_combinations = [
        [1,2,3], [4,5,6], [7,8,9],  # 横向
        [1,4,7], [2,5,8], [3,6,9],  # 纵向
        [1,5,9], [3,5,7]             # 对角线
    ]
    
    # 检查是否有任意一个获胜组合完全包含在玩家落子中
    for combo in win_combinations:
        if set(combo).issubset(set(player_moves)):
            print("X win")
            return True
    # 如果没赢,且棋盘已满则平局,否则继续
    if len(player_moves) == 9:
        print("平局")
        return True
    print("游戏继续")
    return False

# 游戏主循环
for _ in range(9):
    player_turn()
    if check_win():
        break
    print(f"当前玩家落子记录: {player_moves}")

关键修改说明

  • 全局变量声明:把player_moves和turn_count加入player_turn的global声明,确保函数内修改的是全局变量。
  • 简化落子记录:用列表player_moves代替单个answer变量,更简洁易维护,直接追加或修改元素即可。
  • 修正回合计数:把turn_count放在函数外部作为全局变量,每次调用player_turn时累加,正确记录回合数。
  • 优化获胜判定:用set(combo).issubset(set(player_moves))直接判断获胜组合是否完全包含在玩家落子中,逻辑清晰且正确。
  • 减少代码冗余:用字典映射位置和对应的行,避免重复的if判断,提升代码可读性。

内容的提问来源于stack exchange,提问作者user19748230

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:54:22