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

如何修复井字棋(Tic-Tac-Toe)中玩家二选满行被跳回合的问题?

井字棋游戏行填满时玩家回合异常问题修复

问题描述

我是编程新手,基于课堂所学写了个Tic-Tac-Toe(井字棋)游戏,碰到个问题:当玩家二选了已经完全填满的行时,他的回合会直接被跳过。我试着把对应else分支的break改成continue,本来以为会回到选行的提问,结果反而循环回到选位置的步骤,让玩家二陷入软锁。

原代码片段

print("This is Tic-Tac-Toe, play this with a friend")
TicTacToe = [["-", "-", "-"], 
             ["-", "-", "-"], 
             ["-", "-", "-"]]

for row in TicTacToe:
    print(row[0],row[1],row[2])

while True:
    Player = input("Which row do you want to go; T = top, M = middle, or B = bottom?\n")

    if Player not in ["top", "Top", "T", "t", "middle", "Middle", "M", "m", "bottom", "Bottom", "B", "b"]:
        print("Wrong input, I'm afraid you are going to have to actually write what you were told to.")
        continue
    
    # 玩家一的落子逻辑
    if Player == "top" or Player == "Top" or Player == "T" or Player == "t":
        while True:
            Movement = input("Where do you want to go, L = left, M = middle or R = right?\n")
            if Movement not in ["left", "Left", "L", "l", "Middle", "middle", "M", "m", "right", "Right", "R", "r"]:
                print("That is not one of the options you are allowed to write, please write the options listed.")
                continue

            if Movement == "left" or Movement == "Left" or Movement == "L" or Movement == "l":
                if TicTacToe[0][0] == "-":
                    TicTacToe[0][0] = "X"
                    break
                else:
                    print("A move has already been placed there!")

    # 玩家二的回合
    while True: 
        Player2 = input("Now it's your turn Player Two; T = top, M = middle, or B = bottom?\n")
        
        if Player2 not in ["top", "Top", "T", "t", "middle", "Middle", "M", "m", "bottom", "Bottom", "B", "b"]:
            print("Wrong input, I'm afraid you are going to have to actually write what you were told to.")
            continue
        
        if Player2 == "top" or Player2 == "Top" or Player2 == "T" or Player2 == "t":
            while True:
                Movement = input("Where do you want to go, L = left, M = middle or R = right?\n")
                if Movement not in ["left", "Left", "L", "l", "Middle", "middle", "M", "m", "right", "Right", "R", "r"]:
                    print("That is not one of the options you are allowed to write, please write the options listed.")
                    continue
                
                if Movement == "left" or Movement == "Left" or Movement == "L" or Movement == "l":
                    if TicTacToe[0][0] == "-":
                        TicTacToe[0][0] = "O"
                        break
                    else:
                        print("A move has already been placed there!")
                        break

原修改尝试

if Movement == "left" or Movement == "Left" or Movement == "L" or Movement == "l":
                if TicTacToe[0][0] == "-":
                    TicTacToe[0][0] = "O"
                    break
                else:
                    print("A move has already been placed there!")
                    continue

修复方案

核心修改思路

在玩家选择行之后,先检查整行是否已经填满,如果填满直接提示并重新选行;未填满再进入位置选择。同时简化输入判断逻辑,避免重复代码。

修复后的玩家二回合代码(玩家一可同步修改)

# 玩家二的回合循环
while True: 
    Player2 = input("现在轮到玩家二了;选行:T=顶部,M=中间,B=底部?\n")
    
    # 输入合法性检查
    valid_row_inputs = ["top", "Top", "T", "t", "middle", "Middle", "M", "m", "bottom", "Bottom", "B", "b"]
    if Player2 not in valid_row_inputs:
        print("输入错误,请按照提示输入选项。")
        continue
    
    # 统一输入为小写,简化行索引判断
    row_input = Player2.lower()
    row_idx = 0 if row_input in ["top", "t"] else 1 if row_input in ["middle", "m"] else 2
    
    # 提前检查该行是否有空位
    if "-" not in TicTacToe[row_idx]:
        print("这一行已经满了,请选其他行!")
        continue  # 回到选行输入步骤
    
    # 行有效,进入位置选择
    while True:
        Movement = input("选位置:L=左,M=中,R=右?\n")
        valid_move_inputs = ["left", "Left", "L", "l", "middle", "Middle", "M", "m", "right", "Right", "R", "r"]
        if Movement not in valid_move_inputs:
            print("输入错误,请按照提示输入选项。")
            continue
        
        move_input = Movement.lower()
        col_idx = 0 if move_input in ["left", "l"] else 1 if move_input in ["middle", "m"] else 2
        
        if TicTacToe[row_idx][col_idx] == "-":
            TicTacToe[row_idx][col_idx] = "O"
            break  # 落子成功,退出位置循环
        else:
            print("这个位置已经被占了,请选其他位置!")
    break  # 完成回合,退出玩家二的选行循环

原方法无效原因

  1. 循环层级搞错:你修改的continue属于位置选择的内层while循环,所以只会重新触发位置输入,而不会回到外层的选行循环,导致玩家被困在选位置的步骤里。
  2. 原break逻辑缺陷:原来的break会直接退出位置循环,但如果整行都满了,玩家选这个行后,每个位置都会触发else分支的break,直接结束玩家二的回合,导致回合被跳过。

新方法工作原理

  1. 提前拦截无效行:在进入位置选择前,判断选中行是否还有空位(通过检查-是否存在),如果没有,用continue回到选行输入,让玩家重新选行。
  2. 简化输入判断:把玩家输入转为小写,减少重复的多条件判断,让代码更易读和维护。
  3. 明确循环退出逻辑:只有当玩家成功落子后,才依次退出位置循环和选行循环,确保回合正常完成;如果位置被占,只重新进入位置选择,直到选到有效空位。

内容的提问来源于stack exchange,提问作者SD-CD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:03:18