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

Python可调节尺寸井字棋minimax算法运行异常排查

问题描述

我正在开发一款支持可调节棋盘尺寸、搭载minimax算法AI的井字棋游戏,棋盘尺寸仅支持奇数,确保对角线获胜规则始终生效。目前游戏运行无任何报错,但minimax算法未完全正常工作,我可以轻松击败电脑AI。我已反复核查代码仍未定位到算法问题所在,以下是我的完整代码:

棋盘以二维数组表示,各元素取值:-1对应O、1对应X、0对应空位。玩家方标记为1,电脑方标记为-1,当前回合方同样以-1或1标识,分别对应O、X。

Main.py

import TicTacToe
import Minimax

if (__name__ == "__main__"):
    t = TicTacToe.ttt(3)
    m = Minimax.Minimax(3, t)
    
    while (t.winner == None):
        if (t.turn == 1):
            playerInputI = int(input("Input row: "))
            playerInputJ = int(input("Input column: "))
            bestIndex = (playerInputI, playerInputJ)
        else:
            winner, bestIndex = m.minimax(t.grid, (-1, -1), 15, -1)
            t.winner = None
            t.findWinner(bestIndex, t.grid)
            

        t.updateGameGrid(bestIndex)
        print(t.grid)

    print(t.grid)

Minimax.py

import Minimax

if (__name__ == "__main__"):
    t = TicTacToe.ttt(3)
    m = Minimax.Minimax(3, t)
    
    while (t.winner == None):
        if (t.turn == 1):
            playerInputI = int(input("Input row: "))
            playerInputJ = int(input("Input column: "))
            bestIndex = (playerInputI, playerInputJ)
        else:
            winner, bestIndex = m.minimax(t.grid, (-1, -1), 15, -1)
            t.winner = None
            t.findWinner(bestIndex, t.grid)
            

        t.updateGameGrid(bestIndex)
        print(t.grid)

    print(t.grid)

Tictactoe.py

from random import randint

class ttt:
    def __init__(self, size):
        self.gridSize = size
        self.grid = self.createGrid()

        # If using minimax algorithm, user is maximizer(1) and computer is minimizer(-1)
        # If single player, then user is 1, computer is -1
        # If multiplayer, user1 is 1, user2 = -1
        self.turn = 1
        self.winner = None

    def createGrid(self):
        grid = []
        for i in range(self.gridSize):
            grid.append([])
            for j in range(self.gridSize):
                grid[i].append(0)


        # grid = [[-1, 1, 0], [0, -1, 0], [0, 0, 0]]

        return grid

    def updateGameGrid(self, index):
        if (self.grid[index[0]][index[1]] != 0):
            return

        self.grid[index[0]][index[1]] = self.turn
        winner = self.findWinner(index, self.grid)  

        self.turn = -self.turn
        
    def randomIndex(self):
        x = randint(0, self.gridSize-1)
        y = randint(0, self.gridSize-1)
        while (self.grid[x][y] != 0):
            x = randint(0, self.gridSize-1)
            y = randint(0, self.gridSize-1)
        return (x, y)

    def findWinner(self, index, grid):
        # Row
        found = True
        for j in range(self.gridSize-1):
            if (grid[index[0]][j] != grid[index[0]][j+1] or grid[index[0]][j] == 0):
                found = False
                break
        if (found):
            self.winner = self.turn
            return self.turn
        
        # Column
        found = True
        for i in range(self.gridSize-1):
            if (grid[i][index[1]] != grid[i+1][index[1]] or grid[i][index[1]] == 0):
                found = False
                break
        if (found):
            self.winner = self.turn
            return self.turn
        
        # Top Left to Bottom Right Diagonal
        if (index[0] == index[1]):
            found = True
            for i in range(self.gridSize-1):
                if (grid[i][i] != grid[i+1][i+1] or grid[i][i] == 0):
                    found = False
                    break
            if (found):
                self.winner = self.turn
                return self.turn

        # Top Right to Bottom Left Diagonal
        if (index[0] + index[1] == self.gridSize-1):
            found = True
            for i in range(self.gridSize-1):
                if (grid[self.gridSize-i-1][i] != grid[self.gridSize-i-2][i+1] or grid[self.gridSize-i-1][i] == 0):
                    found = False
                    break
            if (found):
                self.winner = self.turn
                return self.turn
            
        
        tie = True
        for i in range(self.gridSize):
            for j in range(self.gridSize):
                if (grid[i][j] == 0):
                    tie = False
        
        if (tie):
            self.winner = 0
            return 0

        return None
问题排查与修复方案
    1. Minimax.py内容错误
      你贴出的Minimax.py代码与Main.py完全重复,没有任何Minimax类和minimax算法的核心实现。当前代码能运行无报错说明你本地实际存储的Minimax.py和你粘贴的内容不一致,首先需要核对你本地的Minimax算法实现,确保递归逻辑、分数评估逻辑、玩家角色切换逻辑正确。
    1. Main.py逻辑冗余错误
      AI落子分支里的t.winner = None和t.findWinner(bestIndex, t.grid)属于完全无效的冗余逻辑:你调用findWinner时还没有把AI的落子更新到棋盘上,检测的是落子前的状态,手动修改winner属性还会覆盖minimax返回的获胜状态,建议直接删除这两行代码,winner状态会在后续调用updateGameGrid时自动计算。
    1. findWinner方法存在副作用
      你在findWinner方法内部直接修改了实例的self.winner属性,而minimax递归过程中会模拟大量落子,如果你的minimax实现复用了同一个ttt实例,模拟落子时调用findWinner会篡改实际游戏的winner状态,导致全局状态混乱。建议修改findWinner为纯函数,删除所有修改self.winner的逻辑,仅返回当前落子后的获胜结果,self.winner统一在updateGameGrid中赋值。
    1. minimax调用参数错误
      你调用m.minimax(t.grid, (-1, -1), 15, -1)时第四个参数写死为-1,而minimax递归过程中需要交替切换最大化玩家(玩家方,1)和最小化玩家(AI方,-1)的身份,写死参数会导致AI在递归时无法正确判断当前是谁的回合,自然无法做出最优决策。你需要根据当前回合动态传递该参数,或者在minimax内部自动处理玩家身份切换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:27:03