Minimax算法不适用于4x4 TicTacToe

时间:2018-09-20 07:24:47

标签: python numpy artificial-intelligence minimax

好的,所以我写了一个机器人玩井字游戏的代理。我使用了传统的minimax算法而不进行修剪。事实是,它非常适合3x3电路板。

但是当我在4x4板上运行它时,它会卡住计算。我不明白为什么。我正在向代理传递一个numpy数组perspectiveState,该数组有0表示空,1表示代理移动,而-1表示对手移动。它返回下一个动作(1)的位置。

控制流从turn()函数开始,该函数调用minimax()函数。

我在这里做什么错了?

class MiniMaxAgent:

def isMovesLeft(self, perspectiveState):
    size = perspectiveState.shape[0]
    #print('!!', np.abs(perspectiveState).sum())
    if np.abs(perspectiveState).sum() == size*size:
        return False
    return True

def evaluate(self, perspectiveState):
    size = perspectiveState.shape[0]
    rsum = perspectiveState.sum(axis=0)
    csum = perspectiveState.sum(axis=1)
    diagSum = perspectiveState.trace()
    antiDiagSum = np.fliplr(perspectiveState).trace()

    if size in rsum or size in csum or size == diagSum or size == antiDiagSum:
        return 10

    if -1*size in rsum or -1*size in csum or -1*size == diagSum or -1*size == antiDiagSum:
        return -10

    return 0

def minimax(self, perspectiveState, isMax):
    score = self.evaluate(perspectiveState)

    if score == 10:
        return score

    if score == -10:
        return score

    if not self.isMovesLeft(perspectiveState):
        return 0

    if isMax:
        best = -1000
        for i in range(perspectiveState.shape[0]):
            for j in range(perspectiveState.shape[0]):
                if perspectiveState[i,j]==0:
                    perspectiveState[i,j] = 1
                    #print('@', isMax)
                    best = max(best, self.minimax(perspectiveState, not isMax))
                    perspectiveState[i,j] = 0
        #print('#', best)
        return best

    else:
        best = 1000;
        for i in range(perspectiveState.shape[0]):
            for j in range(perspectiveState.shape[0]):
                if perspectiveState[i,j]==0:
                    perspectiveState[i,j] = -1
                    #print('@', isMax)
                    best = min(best, self.minimax(perspectiveState, not isMax))
                    perspectiveState[i,j] = 0
        #print('#', best)
        return best

def turn(self, perspectiveState):
    r,c = perspectiveState.shape
    bestVal = -1000
    bestR, bestC = -1, -1

    for i in range(r):
        for j in range(c):
            if perspectiveState[i,j] == 0:
                perspectiveState[i,j] = 1
                moveVal = self.minimax(perspectiveState, False)
                #undo
                perspectiveState[i,j] = 0
                if moveVal > bestVal:
                    bestVal = moveVal
                    bestR = i
                    bestC = j

    return bestR, bestC

1 个答案:

答案 0 :(得分:2)

  

我使用了传统的minimax算法而不进行修剪

这已经是您问题的答案。这就是为什么修剪和记忆过去的状态在算法设计中如此重要的原因。

如果将电路板尺寸增加到4x4,则将呈指数增长,并且会经历大量的计算时间。如果您估计3x3板上可能的移动次数,您将获得(3x3)! = 9 !,等于362880次移动。

如果现在在4x4板上进行可能的移动,则将获得16!可能的状态,这是一个非常庞大的20 922 790 000 000个可能的移动。尽管这些只是近似值,但您可以估计您的计算时间必须高出一百万倍。

有关更多说明,请参见:Tic-Tac-Toe minimax algorithm doesn't work with 4x4 board