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

为何基于一维数组的双向井字棋Minimax算法无法生成获胜局面?

井字棋Minimax算法无法获胜的问题修复

核心问题分析

  • 得分评估逻辑混乱:原getScore函数颠倒了胜负对应的得分值,且未正确处理对手获胜的情况,导致算法无法识别获胜路径。
  • Minimax状态切换错误:原代码通过player和letter组合判断最大化/最小化状态的逻辑完全错误,递归过程中状态切换混乱,无法正确模拟双方的决策。
  • 最佳落子查找逻辑单一:原findBestMove函数仅考虑寻找最高分落子,未适配AI作为最小化玩家的场景。
  • 递归玩家传递错误:递归调用时错误传递了对手的letter,导致落子与评估状态不匹配。

修正后的完整代码

import random

def getOtherPlayer(letter):
    return "O" if letter == "X" else "X"

def getWinner(board):
    # 检查行
    for i in range(3):
        if board[i*3] == board[i*3+1] == board[i*3+2] != "":
            return board[i*3]
    # 检查列
    for i in range(3):
        if board[i] == board[i+3] == board[i+6] != "":
            return board[i]
    # 检查对角线
    if board[0] == board[4] == board[8] != "":
        return board[0]
    if board[2] == board[4] == board[6] != "":
        return board[2]
    # 检查平局
    if "" not in board:
        return "Tie"
    # 未分胜负
    return None

def getAvailableMoves(board):
    return [i for i in range(len(board)) if board[i] == ""]

# 修正得分评估:以AI玩家为基准,AI赢1分,输-1分,平局0分
def getScore(board, ai_letter):
    winner = getWinner(board)
    if winner == ai_letter:
        return 1
    elif winner == getOtherPlayer(ai_letter):
        return -1
    else:
        return 0

def minimax(board, current_letter, ai_letter, is_maximizing):
    winner = getWinner(board)
    if winner is not None:
        return getScore(board, ai_letter)
    
    available_moves = getAvailableMoves(board)
    if is_maximizing:
        best_score = float('-inf')
        for move in available_moves:
            board[move] = current_letter
            score = minimax(board, getOtherPlayer(current_letter), ai_letter, False)
            board[move] = ""
            best_score = max(score, best_score)
        return best_score
    else:
        best_score = float('inf')
        for move in available_moves:
            board[move] = current_letter
            score = minimax(board, getOtherPlayer(current_letter), ai_letter, True)
            board[move] = ""
            best_score = min(score, best_score)
        return best_score

def findBestMove(board, ai_letter):
    available_moves = getAvailableMoves(board)
    best_move = None
    # 根据AI是最大化还是最小化玩家初始化最佳得分
    if ai_letter == "X":
        best_score = float('-inf')
        for move in available_moves:
            board[move] = ai_letter
            score = minimax(board, getOtherPlayer(ai_letter), ai_letter, False)
            board[move] = ""
            if score > best_score:
                best_score = score
                best_move = move
    else:
        best_score = float('inf')
        for move in available_moves:
            board[move] = ai_letter
            score = minimax(board, getOtherPlayer(ai_letter), ai_letter, True)
            board[move] = ""
            if score < best_score:
                best_score = score
                best_move = move
    return best_move

def printBoard(board):
    print()
    for i in range(3):
        print(board[i*3:i*3+3])

# 主程序
board = [""] * 9
# 随机选择玩家角色:0代表人类,1代表AI
player_role = random.choice([0, 1])
human_letter = "X" if player_role == 0 else "O"
ai_letter = getOtherPlayer(human_letter)
print(f"你扮演 {human_letter},AI扮演 {ai_letter}")

while True:
    printBoard(board)
    winner = getWinner(board)
    if winner is not None:
        if winner == "Tie":
            print("平局!")
        else:
            print(f"获胜者:{winner}")
        break
    
    # 人类回合
    if player_role == 0 and human_letter == "X":
        move = int(input("输入你的落子位置(0-8):"))
        while board[move] != "":
            move = int(input("位置已被占用,请重新输入(0-8):"))
        board[move] = human_letter
    elif player_role == 1 and human_letter == "O":
        move = int(input("输入你的落子位置(0-8):"))
        while board[move] != "":
            move = int(input("位置已被占用,请重新输入(0-8):"))
        board[move] = human_letter
    
    # AI回合
    if player_role == 1 and ai_letter == "X":
        move = findBestMove(board, ai_letter)
        print(f"AI落子位置:{move}")
        board[move] = ai_letter
    elif player_role == 0 and ai_letter == "O":
        move = findBestMove(board, ai_letter)
        print(f"AI落子位置:{move}")
        board[move] = ai_letter

关键修正说明

  1. 得分评估函数:重新定义为以AI玩家为基准,明确AI获胜得1、失败得-1、平局得0,逻辑清晰统一。
  2. Minimax函数:明确传递is_maximizing状态,递归时交替切换,AI回合最大化得分,人类回合最小化得分,符合Minimax算法核心逻辑。
  3. 最佳落子查找:根据AI的角色(X/O)分别处理最大化和最小化场景,确保AI选择最优策略。
  4. 主程序逻辑:简化玩家角色判断,明确人类和AI的letter对应关系,避免原代码中混乱的player和letter组合判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:48:15