如何修复井字游戏的minimax算法

时间:2019-06-13 01:53:46

标签: python minimax

对于一个学校项目,我一直在尝试制作无与伦比的井字游戏。为此,我尝试实现一个minimax算法,该算法给出了意外的输出,但我仍无法弄清原因,无法解决任何问题。

我尝试打印出变量以查看何时出现问题,但是对于比最简单的情况(它起作用的情况)更复杂的事情,它输出的东西太多了,任何人都无法筛选,以及何时工作通过它,很难跟踪函数调用自身以及调用它自身的次数。我曾尝试将严格的不平等改为非严格的不平等。我已经尝试过重写整个过程几次,看看我是否有错字。我已经逐步理解了逻辑,却一无所获。

这是我的算法

def minimax(newboard, player, huplayer, aiplayer):
    move=-1
    empty=emptyindices(newboard)
    if winning(newboard, huplayer):
        score=-1
    elif winning(newboard, aiplayer):
        score = 1
    elif empty==[]:
        score=0
    else:
        if player == aiplayer:
            score=0
            for i in empty:
                newboard[i]=player
                output=minimax(newboard, huplayer, huplayer, aiplayer)
                tempscore=output[1]
                if tempscore > score:
                    score=tempscore
                    move = i
                    newboard[i]=""
                newboard[i]=""
        if player == huplayer:
            score=0
            for i in empty:
                newboard[i]=player
                output=minimax(newboard, aiplayer, huplayer, aiplayer)
                tempscore=output[1]
                if tempscore < score:
                    score=tempscore
                    move = i
                    newboard[i]=""
                newboard[i]=""
    return [move,score]

我已经将板从0索引到8,就像

0 | 1 | 2

3 | 4 | 5

6 | 7 | 8

我认为所使用的其他函数中没有错误,但是无论如何我都会在这里包括它们,以防万一它们确实是问题所在。

def winning(board,player):
    if (board[0]==player and board[1]==player and board[2]==player) or (board[3]==player and board[4]==player and board[5]==player) or(board[6]==player and board[7]==player and board[8]==player) or(board[0]==player and board[3]==player and board[6]==player) or (board[1]==player and board[4]==player and board[7]==player) or(board[2]==player and board[5]==player and board[8]==player) or (board[0]==player and board[4]==player and board[8]==player) or (board[2]==player and board[4]==player and board[6]==player):
        win=True
    else:
        win=False
    return win

def emptyindices(board):
    empty=[]
    for i in range(9):
        if board[i]=="":
            empty.append(i)
    return empty

在简单的情况下,计算机可以立即采取行动以获胜。 但是对于

print(minimax(['X', '', '', 'O', '', 'X', 'X', 'O', 'O'],"X","O","X"))

输出为

[-1, 0]

即使计算机可以通过进行第2步来保证获胜,这也意味着由于某些原因,此举并没有改变默认值

1 个答案:

答案 0 :(得分:1)

我认为应该可行(我刚刚测试了我在评论中提出的内容)。那个可怜的松散球员太过被贬低了,无法采取行动,因为这是不可避免的命运:-)

def minimax(newboard, player, huplayer, aiplayer):
    move=-1
    empty=emptyindices(newboard)
    if winning(newboard, huplayer):
        score=-1
    elif winning(newboard, aiplayer):
        score = 1
    elif empty==[]:
        score=0
    else:
        if player == aiplayer:
            score=-2
            for i in empty:
                newboard[i]=player
                output=minimax(newboard, huplayer, huplayer, aiplayer)
                tempscore=output[1]
                if tempscore > score:
                    score=tempscore
                    move = i
                    newboard[i]=""
                newboard[i]=""
        if player == huplayer:
            score=2
            for i in empty:
                newboard[i]=player
                output=minimax(newboard, aiplayer, huplayer, aiplayer)
                tempscore=output[1]
                if tempscore < score:
                    score=tempscore
                    move = i
                    newboard[i]=""
                newboard[i]=""
    return [move,score]

很好的功能!

顺便说一句。您可以使用得分因子来使代码更短一些。因此,对于最小化的玩家,您可以将因子设置为-1,将最大化的因子设置为1。这样,您可以将空字段和循环体重新用于两个玩家,而无需通过将条件更改为类似的方式来实现两次:

if tempscore*factor > score: