Python TicTacToe minimax选择了错误的选项

时间:2017-02-11 18:59:33

标签: python algorithm artificial-intelligence minimax

我目前正在尝试为我的Python TicTacToe游戏实现AI。 除了一种情况外,一切都表现得很好。 我目前的代码:

def testLine(line):
    '''
    ' :param line: Liste containing 3 ints
    ' :return:   1, if all elements of the list == 1
    '           -1, if all elements of the list == -1
    '            0, otherwise
    '''

    if line[0] == 1 and line[1] == 1 and line[2] == 1:
        return 1
    elif line[0] == -1 and line[1] == -1 and line[2] == -1:
        return -1
    return 0


def getWinner(board):
    # test columns
    for idx in range(3):
        line = [board[0][idx], board[1][idx], board[2][idx]]
        if not testLine(line) == 0:
            return line[0]

    # test rows
    for idx in range(3):
        line = board[idx]
        if not testLine(line) == 0:
            return line[0]

    # test diagonals
    line = [board[0][0], board[1][1], board[2][2]]
    if not testLine(line) == 0:
        return line[0]
    line = [board[0][2], board[1][1], board[2][0]]
    if not testLine(line) == 0:
        return line[0]

    # no winner
    return 0

def count(board, obj):
    c = 0
    for r in range(len(board)):
        for col in range(len(board[r])): # FIXED IT
            if board[r][col] == obj:
                c += 1
    return c

def nextMove(board, player):

    if len(board[0]) + len(board[1]) + len(board[2]) == 1: return 0, 4
    nextPlayer = player * (-1)

    if not getWinner(board) == 0:
        if player is 1: return -1, (-1, -1)
        else: return 1, (-1, -1)
    listOfResults = [] # empty array

    if count(board, 0) == 0: # there is no empty field
        return 0, (-1, -1)

    _list = []
    for i in range(len(board)):
        for j in range(len(board[i])):
            if board[i][j] == 0:
                _list.append((i, j))

    for (i, j) in _list:
        board[i][j] = player
        ret, move = nextMove(board, nextPlayer)
        listOfResults.append(ret)
        board[i][j] = 0
    if player is 1:
        maxPossibleValue = max(listOfResults)
        return maxPossibleValue, _list[listOfResults.index(maxPossibleValue)]
    else:
        minPossibleValue = min(listOfResults)
        return minPossibleValue, _list[listOfResults.index(minPossibleValue)]



if __name__ == '__main__':
    print(str(nextMove([[ 1,  -1,  0],
                        [ -1, -1,  1],
                        [ 1,  1,  0]],
                       -1)))

输出:(0, (0, 2))

我可以肯定地说countgetWinnertestLine完美无缺。 但是代码最底部的场景输出完全错误,因为它应该是(0, 2, 2) 因为计算机必须“阻塞”#34;我有机会赢得底线。 您对如何修复我的minimax算法有什么建议吗?

编辑:我已修复过。错误发生在count方法中。你不应该说

for col in board[r]

for col in range(len(board[r]))

因为否则它不会保持元素的正确顺序,整个方法返回错误值。

2 个答案:

答案 0 :(得分:1)

我已经修好了。错误发生在count方法中。你不应该说

    class GameViewController: UIViewController {

        var gameInfo: String? //This works great - now how do I get it to GameScene.swift?

        override func viewDidLoad() {
            super.viewDidLoad()
...

for col in board[r]

因为否则它不会使元素保持正确的顺序,整个方法返回错误的值。

答案 1 :(得分:0)

你需要知道的第一件事是return a, b类似于return (a,b),因为定义一个元组不需要括号(对于一个空元组来说是exept)。

因此,您可以轻松返回(0, 0, 2)而不是(0, (0, 2))

return (maxPossibleValue,) + _list[listOfResults.index(maxPossibleValue)]
# use (a,) for a tuple of len 1

但我知道这只能解决你问题的一半。