为什么我的 MiniMax 实现不起作用?

问题描述

我目前正在使用 Minimax 算法在 Python 中开发一款无与伦比的井字游戏。在这一点上,我已经被困了几天,试图弄清楚为什么算法没有返回正确的分数或让 AI 播放的动作。在程序当前状态下,如果我在左上角执行第一个动作 (X),则极大极小值返回的分数为 0,这似乎是正确的,因为计算机只能打平。然而,这应该适用于所有角落,并且底行的任何初始输入都返回 -1,这是不正确的。返回的最佳移动实际上也不是最佳移动。任何输入将不胜感激,提示将优先于完整答案。我在下面包含了相关代码

   #executes on odd numbered turns (AI goes second) Currently configured with print statements for debugging
    def AI_Logic():
      score = minimax(Board,False)
      x,y = bestmove
      Board[x][y] = 0
      print(count)
      print(bestmove)
      print(score)
      print(Board)
      Turn += 1

def minimax(Board,Maxplayer):
    global bestmove
    global count

    count += 1
    # Checks if the board is full or if a player has won
    if is_Full(Board) or has_Won(Board) == True:

        # Checks for wins,if no wins exists return 0
        if has_Won(Board) == False:
            return 0

        # If O has won,return 1
        elif who_Won(Board) == 0:
            return 1 

        # If X has won,return -1
        elif who_Won(Board) == 1:
            return -1 

    if Maxplayer == True:
        maxscore = float("-inf")
        for x in range(3):
            for y in range(3):
                if Board[x][y] == None:
                    Board[x][y] = 0
                    score = minimax(Board,False)
                    Board[x][y] = None
                    if score > maxscore:
                        bestmove = (x,y)
                    maxscore = max(maxscore,score)

        return maxscore

    else:
        minscore = float("inf")
        for x in range(3):
            for y in range(3):
                if Board[x][y] == None:
                    Board[x][y] = 1
                    score = minimax(Board,True)
                    Board[x][y] = None
                    minscore = min(minscore,score)

        return minscore


def is_Full(Board):
    if any(None in sublist for sublist in Board):
        return False
    else:
        return True

def who_Won(Board):
    global hasWon
    # Checks for three of a kind in first column
    if Board[0][0] == Board[1][0] and Board[0][0] != None:
        if Board[1][0] == Board[2][0]:
            hasWon = 1
            return Board[2][0]
    if Board[0][0] == Board[0][1] and Board[0][0] != None:
        if Board[0][1] == Board[0][2]:
            hasWon = 1
            return Board[0][2]
    # Checks for diag win top Left to bottom right
    if Board[0][0] == Board[1][1] and Board[0][0] != None:
        if Board[1][1] == Board[2][2]:
            hasWon = 1
            return Board[2][2]
    # Checks for diag win bottom left to top right
    if Board[0][2] == Board[1][1] and Board[0][2] != None:
        if Board[1][1] == Board[2][0]:
            hasWon = 1
            return Board[2][0]
    # Checks for center column win
    if Board[0][1] == Board[1][1] and Board[0][1] != None:
        if Board[1][1] == Board[2][1]:
            hasWon = 1
            return Board[2][1]
    # Checks for right column win:
    if Board[0][2] == Board[1][2] and Board[0][2] != None:
        if Board[1][2] == Board[2][2]:
            hasWon = 1
            return Board[2][2]
    # Checks for second row win:
    if Board[1][0] == Board[1][1] and Board[1][0] != None:
        if Board[1][1] == Board[1][2]:
            hasWon = 1
            return Board[1][2]
    # Checks for third row win:
    if Board[2][0] == Board[2][1] and Board[2][0] != None:
        if Board[2][1] == Board[2][2]:
            hasWon = 1
            return Board[2][2]


def has_Won(Board):

    # Checks for three of a kind in first column
    if Board[0][0] == Board[1][0] and Board[0][0] != None:
        if Board[1][0] == Board[2][0]:
            return True
    if Board[0][0] == Board[0][1] and Board[0][0] != None:
        if Board[0][1] == Board[0][2]:
            return True
    # Checks for diag win top Left to bottom right
    if Board[0][0] == Board[1][1] and Board[0][0] != None:
        if Board[1][1] == Board[2][2]:
            return True
    # Checks for diag win bottom left to top right
    if Board[0][2] == Board[1][1] and Board[0][2] != None:
        if Board[1][1] == Board[2][0]:
            return True
    # Checks for center column win
    if Board[0][1] == Board[1][1] and Board[0][1] != None:
        if Board[1][1] == Board[2][1]:
            return True
    # Checks for right column win:
    if Board[0][2] == Board[1][2] and Board[0][2] != None:
        if Board[1][2] == Board[2][2]:
            return True
    # Checks for second row win:
    if Board[1][0] == Board[1][1] and Board[1][0] != None:
        if Board[1][1] == Board[1][2]:
            return True
    # Checks for third row win:
    if Board[2][0] == Board[2][1] and Board[2][0] != None:
        if Board[2][1] == Board[2][2]:
            return True

    return False

# Checks the position of a mouse click and draws an X/O,Appends the Board matrix with a 1 in the correct spot to reflect an X,0 to relfect O
def draw_X(x,y):
    global Turn
    # Checks if turn is an even number (i.e x's turn)
    if Turn % 2 == 0:
        # Series of statements checking the x and y pos of the mouse. Each mouse click lies in a specific Box,draw the X/O in the center of the Box,# making sure there is nothing in the Box,and not to overwrite if an X or O already exist.
        if x < WIDTH / 3 and y < HEIGHT/3:
            if Board[0][0] == None:
                Board[0][0] = 1
                WIN.blit(X,(60,60))
                # Increases Turn after each executed x or O drawing
                Turn += 1
        elif x < WIDTH - WIDTH / 3 and y < HEIGHT/3:
            if Board[0][1] == None:
                Board[0][1] = 1
                WIN.blit(X,(WIDTH / 3 + 60,60))
                Turn += 1
        elif x < WIDTH and y < HEIGHT/3:
            if Board[0][2] == None:
                Board[0][2] = 1
                WIN.blit(X,(WIDTH - WIDTH / 3 + 60,60))
                Turn += 1
        elif x < WIDTH / 3 and y < HEIGHT - HEIGHT/3:
            if Board[1][0] == None:
                Board[1][0] = 1
                WIN.blit(X,HEIGHT / 3 + 60))
                Turn += 1
        elif x < WIDTH - WIDTH / 3 and y < HEIGHT - HEIGHT/3:
            if Board[1][1] == None:
                Board[1][1] = 1
                WIN.blit(X,HEIGHT / 3 + 60))
                Turn += 1
        elif x < WIDTH and y < HEIGHT - HEIGHT/3:
            if Board[1][2] == None:
                Board[1][2] = 1
                WIN.blit(X,HEIGHT / 3 + 60))
                Turn += 1
        elif x < WIDTH / 3 and y < HEIGHT:
            if Board[2][0] == None:
                Board[2][0] = 1
                WIN.blit(X,HEIGHT - HEIGHT / 3 + 60))
                Turn += 1
        elif x < WIDTH - WIDTH / 3 and y < HEIGHT:
            if Board[2][1] == None:
                Board[2][1] = 1
                WIN.blit(X,HEIGHT - HEIGHT / 3 + 60))
                Turn += 1
        elif x < WIDTH and y < HEIGHT:
            if Board[2][2] == None:
                Board[2][2] = 1
                WIN.blit(X,HEIGHT - HEIGHT / 3 + 60))
                Turn += 1

    # On odd number turns,O will be drawn onto the board:
    else:

        if x < WIDTH / 3 and y < HEIGHT/3:
            if Board[0][0] == None:
                Board[0][0] = 0
                WIN.blit(O,60))
                Turn += 1
        elif x < WIDTH - WIDTH / 3 and y < HEIGHT/3:
            if Board[0][1] == None:
                Board[0][1] = 0
                WIN.blit(O,60))
                Turn += 1
        elif x < WIDTH and y < HEIGHT/3:
            if Board[0][2] == None:
                Board[0][2] = 0
                WIN.blit(O,60))
                Turn += 1
        elif x < WIDTH / 3 and y < HEIGHT - HEIGHT/3:
            if Board[1][0] == None:
                Board[1][0] = 0
                WIN.blit(O,HEIGHT / 3 + 60))
                Turn += 1
        elif x < WIDTH - WIDTH / 3 and y < HEIGHT - HEIGHT/3:
            if Board[1][1] == None:
                Board[1][1] = 0
                WIN.blit(O,HEIGHT / 3 + 60))
                Turn += 1
        elif x < WIDTH and y < HEIGHT - HEIGHT/3:
            if Board[1][2] == None:
                Board[1][2] = 0
                WIN.blit(O,HEIGHT / 3 + 60))
                Turn += 1
        elif x < WIDTH / 3 and y < HEIGHT:
            if Board[2][0] == None:
                Board[2][0] = 0
                WIN.blit(O,HEIGHT - HEIGHT / 3 + 60))
                Turn += 1
        elif x < WIDTH - WIDTH / 3 and y < HEIGHT:
            if Board[2][1] == None:
                Board[2][1] = 0
                WIN.blit(O,HEIGHT - HEIGHT / 3 + 60))
                Turn += 1
        elif x < WIDTH and y < HEIGHT:
            if Board[2][2] == None:
                Board[2][2] = 0
                WIN.blit(O,HEIGHT - HEIGHT / 3 + 60))
                Turn += 1

# 3x3 Matrix used for game logic
Board = [[None]*3,[None]*3,[None]*3]
# Executes every frame,draws the board,checks for wins,and updates the display
def draw_Window():

    draw_Board()
    has_Won(Board)
    pygame.display.update()
# Main Event Loop
def main():
    global Turn
    FPS = 60
    run = True
    WIN.fill((255,255,255))
    clock = pygame.time.Clock()

    while run:

        clock.tick(FPS)
        draw_Window()
        # Runs the AI turn on odd numbers
        if Turn % 2 != 0:
            while x:
                AI_Logic()
                x = False
        # Checks for winner
        if has_Won == True:
            pass
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            # Checks if a mouse is clicked. When clicked,it records the x and y pos of the mouse and passes it through the draw_X function
            if event.type == pygame.MOUSEBUTTONDOWN:
                x,y = pygame.mouse.get_pos()
                draw_X(x,y)
        pygame.display.update()
    pygame.quit()


main()

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)