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

Python井字棋程序开发问题:终止move()及UnboundLocalError报错排查

解决你的井字棋程序问题

问题2:UnboundLocalError 错误修复

这个错误是Python变量作用域规则导致的:当你在函数内部给一个变量(比如stop)赋值时,Python会自动把它认定为局部变量。如果你的代码存在“先引用这个变量,再给它赋值”的情况,或者某些分支里没给stop赋值就去使用它,就会触发这个报错。

举个典型的错误场景:

def move():
    # 某些逻辑...
    if 获胜条件:
        stop = True
    # 这里如果上面的if分支没触发,stop就没被定义,直接报错!
    if stop:
        return

修复方案很简单,二选一即可:

  • 初始化局部变量:在函数开头就给stop赋初始值,确保所有分支都能访问到它:
    def move():
        stop = False  # 先初始化局部变量
        # 后续逻辑...
        if 获胜条件:
            stop = True
        if stop:
            return
    
  • 声明全局变量:如果stop是在函数外定义的全局变量,需要在函数开头用global声明,告诉Python你要使用全局作用域的stop:
    stop = False  # 全局变量
    def move():
        global stop  # 声明使用全局变量
        # 后续逻辑...
        if 获胜条件:
            stop = True
    

问题1:实现获胜时终止move()的逻辑

要在出现三连时终止游戏,核心是每次落子后立刻检查是否满足获胜条件,具体步骤如下:

1. 定义所有获胜组合

先把井字棋中所有可能的三连情况整理成列表,覆盖横向、纵向、对角线的所有组合:

winning_combos = [
    # 横向三连
    ["top-l", "top-m", "top-r"],
    ["mid-l", "mid-m", "mid-r"],
    ["low-l", "low-m", "low-r"],
    # 纵向三连
    ["top-l", "mid-l", "low-l"],
    ["top-m", "mid-m", "low-m"],
    ["top-r", "mid-r", "low-r"],
    # 对角线三连
    ["top-l", "mid-m", "low-r"],
    ["top-r", "mid-m", "low-l"]
]

2. 落子后检查获胜条件

在move()函数里,每次玩家或AI完成落子后,遍历上面的组合列表,检查是否有某个组合的三个位置全是"X"或"O":

def move(player):
    stop = False  # 初始化变量,同时解决UnboundLocalError
    # 你的落子逻辑(玩家输入/AI随机选位置)...
    
    # 检查是否获胜
    for combo in winning_combos:
        # 取出组合内三个位置的值
        pos1, pos2, pos3 = board[combo[0]], board[combo[1]], board[combo[2]]
        # 判断是否全为当前玩家的标记
        if pos1 == pos2 == pos3 == player:
            print(f"玩家 {player} 获胜!")
            stop = True
            break
    # 额外检查平局:所有位置都填满且没人获胜
    if not stop and all(value != " " for value in board.values()):
        print("平局!")
        stop = True
    
    # 如果触发获胜/平局,直接终止函数
    if stop:
        return
    # 否则继续执行后续逻辑...

3. 整合到主循环

在游戏的主循环里,每次调用move()后判断是否触发终止条件,如果是就跳出循环,结束游戏。

修改后的完整示例代码

import random

board = {
    "top-l":" ","top-m":" ","top-r":" ",
    "mid-l":" ","mid-m":" ","mid-r":" ",
    "low-l":" ","low-m":" ","low-r":" "
}

winning_combos = [
    ["top-l", "top-m", "top-r"],
    ["mid-l", "mid-m", "mid-r"],
    ["low-l", "low-m", "low-r"],
    ["top-l", "mid-l", "low-l"],
    ["top-m", "mid-m", "low-m"],
    ["top-r", "mid-r", "low-r"],
    ["top-l", "mid-m", "low-r"],
    ["top-r", "mid-m", "low-l"]
]

def print_board(board):
    print(f"{board['top-l']}|{board['top-m']}|{board['top-r']}")
    print("-+-+-")
    print(f"{board['mid-l']}|{board['mid-m']}|{board['mid-r']}")
    print("-+-+-")
    print(f"{board['low-l']}|{board['low-m']}|{board['low-r']}")

def move(player):
    stop = False
    if player == "X":
        # 玩家落子逻辑
        while True:
            pos = input("请输入落子位置(如top-l):")
            if board[pos] == " ":
                board[pos] = "X"
                break
    else:
        # AI随机落子
        while True:
            pos = random.choice(list(board.keys()))
            if board[pos] == " ":
                board[pos] = "O"
                break
    # 检查获胜
    for combo in winning_combos:
        if board[combo[0]] == board[combo[1]] == board[combo[2]] == player:
            print(f"玩家 {player} 获胜!")
            stop = True
            break
    # 检查平局
    if not stop and all(v != " " for v in board.values()):
        print("平局!")
        stop = True
    return stop

# 主游戏循环
current_player = "X"
while True:
    print_board(board)
    game_over = move(current_player)
    if game_over:
        print_board(board)
        break
    # 切换玩家
    current_player = "O" if current_player == "X" else "X"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:18:52