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
额外优化建议
- 简化胜利判定逻辑:把所有获胜组合存入列表,遍历检查更简洁:
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
- 添加平局判断:当前代码未处理棋盘满但无人获胜的情况,可在主循环中补充:
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
相关产品推荐
相关产品推荐

