如何修复井字棋(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 # 完成回合,退出玩家二的选行循环
原方法无效原因
- 循环层级搞错:你修改的
continue属于位置选择的内层while循环,所以只会重新触发位置输入,而不会回到外层的选行循环,导致玩家被困在选位置的步骤里。 - 原break逻辑缺陷:原来的
break会直接退出位置循环,但如果整行都满了,玩家选这个行后,每个位置都会触发else分支的break,直接结束玩家二的回合,导致回合被跳过。
新方法工作原理
- 提前拦截无效行:在进入位置选择前,判断选中行是否还有空位(通过检查
-是否存在),如果没有,用continue回到选行输入,让玩家重新选行。 - 简化输入判断:把玩家输入转为小写,减少重复的多条件判断,让代码更易读和维护。
- 明确循环退出逻辑:只有当玩家成功落子后,才依次退出位置循环和选行循环,确保回合正常完成;如果位置被占,只重新进入位置选择,直到选到有效空位。
内容的提问来源于stack exchange,提问作者SD-CD
相关产品推荐
相关产品推荐

