PythonNegamaxアルゴリズム

キャンドル

Tic Tac Toeの位置を評価するために、可能な限り単純なネガマックスアルゴリズムを使用しています。ゲームの状態は、Xのピースが1で表され、Oのピースが4で表される、配列としてnumpyに格納されます。

私はちょうど今これをテストしていて、見つけました:

a = np.zeros(9).reshape(3,3)
negaMax(a, 6, 1) # Returned zero as it should
negaMax(a, 7, 1) # Returns 100

私のアルゴリズムは、XがTic Tac Toeのゲームで7プライで勝つ方法を見つけたと考えていることを意味します。これは、まともなプレーに対しては明らかに不可能です。見つけた最高の動きを印刷する方法がわからないので、これをデバッグするのに本当に問題があります。私は何が間違っているのですか?

def winCheck(state):
        """Takes a position, and returns the outcome of that game"""
        # Sums which correspond to a line across a column
        winNums = list(state.sum(axis=0))
        # Sums which correspond to a line across a row
        winNums.extend(list(state.sum(axis=1)))
        # Sums which correspond to a line across the main diagonal
        winNums.append(state.trace())
        # Sums which correspond to a line across the off diagonal
        winNums.append(np.flipud(state).trace())

        if Square.m in winNums:
                return 'X'
        elif (Square.m**2 + Square.m) in winNums:
                return 'O'
        elif np.count_nonzero(state) == Square.m**2:
                return 'D'
        else:
                return None

def moveFind(state):
        """Takes a position as an nparray and determines the legal moves"""
        moveChoices = []

        # Iterate over state, to determine which squares are empty
        it = np.nditer(state, flags=['multi_index'])
        while not it.finished:
            if it[0] == 0:
                    moveChoices.append(it.multi_index)
            it.iternext()
        return moveChoices

def moveSim(state, move, player):
        """Create the state of the player having moved without interfering with the board"""
        simState = state.copy()
        if player == 1:
                simState[move] = 1
        else:
                simState[move] = gamecfg.n + 1
        return simState

def positionScore(state):
        """The game is either won or lost"""
        if winCheck(state) == 'X':
                return 100
        elif winCheck(state) == 'O':
                return -100
        else:
                return 0

def negaMax(state, depth, colour):
        """Recursively find the best move via a negamax search"""
        if depth == 0:
                return positionScore(state) * colour

        highScore = -100

        moveList = moveFind(state)
        for move in moveList:
                score = -negaMax(moveSim(state, move, colour), depth -1, colour * -1)
                highScore = max(score, highScore)

        return highScore
ピーター・デ・リヴァズ

あなたのコードは、3つのシンボルの行が作られたときにゲームが停止することを考慮していません。

これは、Oが3のラインを作った後でも、Xが3のラインを作った場合に、Xが勝つ三目並べのバリアントをプレイしていることを意味します。

このバリアントの場合、プログラムはXが常に勝つ可能性があることを正しく検出しました。

(私が作成したチェスプログラムで同じ状況に遭遇しました。コンピューターは、少し後でチェックメイトに到達した場合、その王を喜んで犠牲にしました...)

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事