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

Python实现Tic Tac Toe(井字棋)AI不败的高效逻辑优化问询

井字棋AI落子逻辑优化方案

核心优化思路

你现在的代码冗余根源是硬编码了所有获胜组合的判断逻辑,只要把所有获胜线抽成公共常量,再统一遍历判断,就能砍掉所有重复的if/elif代码。如果要实现100%不败,直接用极小极大算法穷举所有游戏状态即可,井字棋总状态数只有不到30万,计算开销可以忽略。

第一步:抽取公共获胜线常量

首先把所有8种获胜组合定义为全局常量,胜负检测、落子判断都复用这个常量:

# 所有获胜的三个格子坐标组合
WIN_LINES = [
    [(0,0), (0,1), (0,2)], [(1,0), (1,1), (1,2)], [(2,0), (2,1), (2,2)], # 行
    [(0,0), (1,0), (2,0)], [(0,1), (1,1), (2,1)], [(0,2), (1,2), (2,2)], # 列
    [(0,0), (1,1), (2,2)], [(0,2), (1,1), (2,0)] # 对角线
]

对应你的胜负检测逻辑可以简化为:

def check(board, player):
    for line in WIN_LINES:
        if all(board[x][y] == player for x,y in line):
            win.player_won(player)
            return

第二步:极简拦截+优先赢落子逻辑

不需要写任何硬编码的if判断,直接遍历获胜线即可,落子按以下优先级:

  1. 优先走能让自己直接赢的位置
  2. 其次走拦截对手赢的位置
  3. 剩下的位置按中心>角>边的优先级选择
    代码示例:
def ai_move(board):
    # 优先级1:检查自己能不能直接赢
    for line in WIN_LINES:
        positions = [board[x][y] for x,y in line]
        if positions.count('X') == 2 and positions.count('#') == 1:
            # 找到空位置落子
            for x,y in line:
                if board[x][y] == '#':
                    board[x][y] = 'X'
                    return
    # 优先级2:拦截对手的获胜位置
    for line in WIN_LINES:
        positions = [board[x][y] for x,y in line]
        if positions.count('O') == 2 and positions.count('#') == 1:
            for x,y in line:
                if board[x][y] == '#':
                    board[x][y] = 'X'
                    return
    # 优先级3:占中心
    if board[1][1] == '#':
        board[1][1] = 'X'
        return
    # 优先级4:占四个角
    corners = [(0,0), (0,2), (2,0), (2,2)]
    for x,y in corners:
        if board[x][y] == '#':
            board[x][y] = 'X'
            return
    # 优先级5:占剩下的边位
    edges = [(0,1), (1,0), (1,2), (2,1)]
    for x,y in edges:
        if board[x][y] == '#':
            board[x][y] = 'X'
            return

这个版本已经可以做到几乎不会输,代码量比你原来的硬编码if少80%以上,可维护性极高。

第三步:100%不败的极小极大实现

如果要保证绝对不会输,可以用极小极大算法穷举所有可能的落子路径,计算每个位置的最优得分:

def minimax(board, depth, is_maximizing):
    # 终止状态判断:X赢返回1,O赢返回-1,平局返回0
    for line in WIN_LINES:
        vals = [board[x][y] for x,y in line]
        if vals == ['X','X','X']:
            return 1
        if vals == ['O','O','O']:
            return -1
    # 棋盘满了平局
    if all(board[x][y] != '#' for x in range(3) for y in range(3)):
        return 0
    
    if is_maximizing:
        best_score = -float('inf')
        for x in range(3):
            for y in range(3):
                if board[x][y] == '#':
                    board[x][y] = 'X'
                    score = minimax(board, depth+1, False)
                    board[x][y] = '#'
                    best_score = max(score, best_score)
        return best_score
    else:
        best_score = float('inf')
        for x in range(3):
            for y in range(3):
                if board[x][y] == '#':
                    board[x][y] = 'O'
                    score = minimax(board, depth+1, True)
                    board[x][y] = '#'
                    best_score = min(score, best_score)
        return best_score

# AI落子调用
def best_ai_move(board):
    best_score = -float('inf')
    best_pos = None
    for x in range(3):
        for y in range(3):
            if board[x][y] == '#':
                board[x][y] = 'X'
                score = minimax(board, 0, False)
                board[x][y] = '#'
                if score > best_score:
                    best_score = score
                    best_pos = (x,y)
    board[best_pos[0]][best_pos[1]] = 'X'

这个版本可以保证AI要么赢要么平局,绝对不会输。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:36:03