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

Python井字棋胜利判定函数异常问题排查求助

井字棋胜利判定异常:落子3/6/7/8/9号位直接判定胜利

我是Python初学者,正在开发一款简易井字棋游戏,多数功能运行正常,但存在异常:当玩家(或电脑)落子至3、6、7、8、9号位时,会直接判定胜利(无需达成三子连线),我无法定位问题根源。我推测错误出在胜利判定函数victory_for中。

初始棋盘样式:

+-------+-------+-------+
|       |       |       |
|   1   |   2   |   3   |
|       |       |       |
+-------+-------+-------+
|       |       |       |
|   4   |   X   |   6   |
|       |       |       |
+-------+-------+-------+
|       |       |       |
|   7   |   8   |   9   |
|       |       |       |
+-------+-------+-------+

完整代码(标注疑似错误位置):

#电脑使用X,玩家使用O。

#需要随机数实现电脑落子
from random import randrange

#初始棋盘,电脑先行,在中间位置放置X
board = [[1, 2, 3], [4, "X", 6], [7, 8, 9]]

#显示当前棋盘状态
def display_board(board):
  print(
      "\n+-------+-------+-------+",
      "\n|       |       |       |",
      "\n|  ",board[0][0],"  |  ",board[0][1],"  |  ",board[0][2],"  |",
      "\n|       |       |       |",
      "\n+-------+-------+-------+",
      "\n|       |       |       |",
      "\n|  ",board[1][0],"  |  ",board[1][1],"  |  ",board[1][2],"  |",
      "\n|       |       |       |",
      "\n+-------+-------+-------+",
      "\n|       |       |       |",
      "\n|  ",board[2][0],"  |  ",board[2][1],"  |  ",board[2][2],"  |",
      "\n|       |       |       |",
      "\n+-------+-------+-------+"
      )

#生成可落子的空闲位置列表
def make_list_of_free_fields(board):
  list_of_free_fields = []
  for field in range(1,10):
    for row in range(3):
      if field in board[row]:
        list_of_free_fields.append(field)
  return(list_of_free_fields)

#玩家输入落子位置
def enter_move(board):
  while True:
    user_input = int(input("请选择落子位置:"))
    if user_input in make_list_of_free_fields(board):
      break
    print("请选择棋盘上的空闲位置(输入1-9)")
  row = (user_input - 1) // 3
  column = (user_input - 1) - row * 3
  board[row][column] = "O"

#我认为此处存在错误:用于判定当前玩家(通过符号标识)是否获胜
def victory_for(board, sign):
  if (board[0][0] and board[0][1] and board[0][2] == sign or 
      board[1][0] and board[1][1] and board[1][2] == sign or 
      board[2][0] and board[2][1] and board[2][2] == sign or 
      board[0][0] and board[1][0] and board[2][0] == sign or 
      board[0][1] and board[1][1] and board[2][1] == sign or 
      board[0][2] and board[1][2] and board[2][2] == sign or 
      board[0][0] and board[1][1] and board[2][2] == sign or 
      board[0][2] and board[1][1] and board[2][0] == sign):
    return True
  else:
    return False

#电脑随机落子
def draw_move(board):
  while True:
    comp_input = randrange(10)
    if comp_input in make_list_of_free_fields(board):
      break
  row = (comp_input - 1) // 3
  column = (comp_input - 1) - row * 3
  board[row][column] = "X"


#游戏主逻辑:循环直至一方获胜
print(
    "欢迎来到我制作的井字棋游戏!",
    "\n通过输入1-9选择位置放置O",
    "\n电脑先行,放置X"
    )

display_board(board)

while True:
  enter_move(board)
  display_board(board)
  if victory_for(board, "O") == True:
    print("你获胜了!")
    break
  draw_move(board)
  display_board(board)
  if victory_for(board, "X") == True:
    print("你失败了!")
    break

问题排查与修复

错误根源

victory_for函数的逻辑表达式写法错误:Python中,board[0][0] and board[0][1] and board[0][2] == sign这种写法会被拆解为:先判断board[0][0]是否为真值(非零数字、非空字符串都为真),再判断board[0][1]是否为真值,最后判断board[0][2] == sign。只要这三个条件中有一个成立,整个表达式就会返回True。

当落子到3、6、7、8、9号位时,对应行/列/对角线的前两个元素还是初始数字(属于真值),加上最后一个元素等于sign,直接触发胜利判定。

修复后的victory_for函数

正确写法需要每个元素都单独与sign比较,再用and组合:

def victory_for(board, sign):
    if (
        # 检查所有行
        board[0][0] == sign and board[0][1] == sign and board[0][2] == sign or
        board[1][0] == sign and board[1][1] == sign and board[1][2] == sign or
        board[2][0] == sign and board[2][1] == sign and board[2][2] == sign or
        # 检查所有列
        board[0][0] == sign and board[1][0] == sign and board[2][0] == sign or
        board[0][1] == sign and board[1][1] == sign and board[2][1] == sign or
        board[0][2] == sign and board[1][2] == sign and board[2][2] == sign or
        # 检查两条对角线
        board[0][0] == sign and board[1][1] == sign and board[2][2] == sign or
        board[0][2] == sign and board[1][1] == sign and board[2][0] == sign
    ):
        return True
    else:
        return False

额外优化建议

  1. 简化胜利判定逻辑:把所有获胜组合存入列表,遍历检查更简洁:
def victory_for(board, sign):
    # 定义所有获胜的三子组合
    win_combinations = [
        [board[0][0], board[0][1], board[0][2]],
        [board[1][0], board[1][1], board[1][2]],
        [board[2][0], board[2][1], board[2][2]],
        [board[0][0], board[1][0], board[2][0]],
        [board[0][1], board[1][1], board[2][1]],
        [board[0][2], board[1][2], board[2][2]],
        [board[0][0], board[1][1], board[2][2]],
        [board[0][2], board[1][1], board[2][0]]
    ]
    # 判断是否存在全为sign的组合
    return [sign, sign, sign] in win_combinations
  1. 添加平局判断:当前代码未处理棋盘满但无人获胜的情况,可在主循环中补充:
while True:
    enter_move(board)
    display_board(board)
    if victory_for(board, "O"):
        print("你获胜了!")
        break
    # 检查是否无空闲位置(平局)
    if len(make_list_of_free_fields(board)) == 0:
        print("平局!")
        break
    draw_move(board)
    display_board(board)
    if victory_for(board, "X"):
        print("你失败了!")
        break

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 14:45:33