Python井字棋游戏第9回合胜负与平局判定逻辑失效Bug排查
井字棋第9回合获胜误判平局Bug修复
问题根因
- 变量残留导致校验失效:平局判定循环中直接复用了前序胜负校验循环最后一次迭代留下的
win_O、win_X变量值,没有针对当前遍历的获胜组合重新计算双方棋子命中情况,校验的数据源本身就是错误的。 - 逻辑运算符使用错误:平局判定条件中使用
or连接两个未命中判断,等价于「只要任意一方在某条获胜线没凑齐3子就触发平局」,完全不符合「双方都没凑齐任何获胜线才是平局」的要求。 - 执行顺序错位:原有代码把胜负校验放在每轮循环的最开头(玩家/AI落子之前执行),第9步落子完成后会先走到平局判定逻辑,还没轮到下一轮的胜负校验,自然会优先触发平局。
- 多余条件限制:原有O玩家的获胜判断加了
counter > 4的限制,实际上玩家第3步就有可能凑齐连线获胜,这个条件会导致前中期获胜无法被识别。 - 附加逻辑缺陷:AI落子仅做了一次占用判断,第一次随机到已占位置后仅重新生成坐标但不做二次校验,很容易出现AI落在已有棋子位置的问题。
修复方案
- 调整判定执行顺序:把胜负、平局的校验逻辑统一移到每次有效落子、counter计数加1之后执行,保证落子完成后先校验胜负,未分胜负再校验是否平局。
- 统一判定逻辑:废弃分两次循环校验胜负、平局的写法,遍历所有获胜线时用标记位记录是否有玩家获胜,遍历完所有获胜线后再根据标记位判断结果:
- 标记位记录到获胜方:直接触发获胜结算
- 无获胜方且回合数counter等于9:触发平局结算
- 删除多余的
counter >4获胜判断限制,只要凑齐连线就判定获胜。 - 给AI落子加循环校验,直到随机到空位才完成落子。
修正后的核心判定代码参考
# 以下逻辑放在每次有效落子、counter +=1 执行完成后 winner = None # 遍历所有获胜线检查胜负 for line in winning_possibilities: o_hit = 0 x_hit = 0 for pos in line: if pos in status_O: o_hit +=1 if pos in status_X: x_hit +=1 if o_hit == 3: winner = "O" break if x_hit ==3: winner = "X" break if winner: print(f"{winner} won, the game is over!\n\n") control = 0 # 此处保留原有游戏重置、重启询问的逻辑即可 status_X = [] status_O = [] board = [["___", "___", "___"], ["___", "___", "___"], ["___", "___", "___"]] counter = 0 turn = 2 if winner == "O" else 1 restart = input("To restart the game please enter R.\n").lower() if restart == "r": print("\n"*10) for i in board: print(" "*28, *i, sep=" "*3, end="\n"*3) control = 1 elif counter ==9: print("Draw!\n\n") control =0 # 此处保留原有平局后游戏重置、重启询问的逻辑即可 status_X = [] status_O = [] board = [["___", "___", "___"], ["___", "___", "___"], ["___", "___", "___"]] counter =0 restart = input("To restart the game please enter R.\n").lower() if restart == "r": print("\n"*10) for i in board: print(" "*28, *i, sep=" "*3, end="\n"*3) control =1
AI落子逻辑修正参考
elif whoseTurn == turnY: # 循环直到选到空位 while True: randomX = random.randint(0,2) randomY = random.randint(0,2) if board[randomX][randomY] == "___": break board[randomX][randomY] = whoseTurn status_O += [[randomX, randomY]] print("\n"*2 + "Now is your opponent's turn, wait him/her to play!" + "\n"*2) counter += 1 turn +=1 print("\n"*5) for i in board: print(" "*28, *i, sep=" "*3, end="\n"*3)
内容的提问来源于stack exchange,提问作者Hotspotower
相关产品推荐
相关产品推荐

