在 python 中使用 Tkinter 的 Tic Tac Toe 中我的 minimax 算法有什么问题?

What is wrong in my minimax algorithm in Tic Tac Toe using Tkinter in python?

我正在制作井字游戏。在此,有2种模式。一种是双人模式,另一种是 AI。两个播放器模式运行良好。但是AI模式不起作用。当给定的复选框中有勾号时,将应用 AI 模式,并且其中一个回合由 AI 进行。我已经使用 minimax 算法进行 AI 执行。我没有发现代码有什么问题,因为这是我第一款使用 GUI (Tkinter) 的游戏。请有人告诉我其中有什么问题,或者请更正我的代码。提前致谢。

from tkinter import *
from copy import deepcopy
import random


game = Tk()
game.title("TIC TAC TOE")
game.geometry("450x555")
#game.configure(bg = '#b3b3b3')



with_AI = Label(text = "Want to play with AI:", font = ("Helvatica", 15), fg = "#000000")
with_AI.grid(row = 0, column = 0, columnspan = 2, sticky = 'e')

yes_AI = IntVar()
Checkbutton(game, variable = yes_AI).grid(row = 0, column = 2, sticky = 'w')

textPlay = Label(text = "Start the Game!!!", font = ("Helvatica", 15), fg = "red")
textPlay.grid(row = 1, column = 0, columnspan = 3)




temp = random.choice([0, 1])
if temp == 0:
    player = 'O'
else:
    player = 'X'
stop_game = False




def minimax(states, depth, isMax, playerAI, scores):

    result = checkWinner1()
    if result != None:
        return scores[result]

    if isMax:
        bestVal = -1000
        for i in range(3):
            for j in range(3):
                if states[i][j] == 0:
                    states[i][j] = playerAI
                    moveVal = minimax(states, depth + 1, False, playerAI, scores)
                    states[i][j] = 0
                    bestVal = max(moveVal, bestVal)
        return bestVal
    else:
        bestVal = 1000
        for i in range(3):
            for j in range(3):
                if states[i][j] == 0:
                    if playerAI == 'X':
                        states[i][j] = 'O'
                    else:
                        states[i][j] = 'X'
                    moveVal = minimax(states, depth + 1, True, playerAI, scores)
                    states[i][j] = 0
                    bestVal = min(moveVal, bestVal)
        return bestVal


def bestMove(states, playerAI, scores):
    checkWinner1()

    bestVal = -1000

    for i in range(3):
        for j in range(3):
            if states[i][j] == 0:
                moveVal = playerAI
                moveVal = minimax(states, 0, False, playerAI, scores)
                states[i][j] = 0
                if moveVal > bestVal:
                    bestRow = i
                    bestColumn = j
                    bestVal = moveVal

    return bestRow, bestColumn


def callback(r, c):
    global player
    global textPlay
    global states

    if player == 'X' and states[r][c] == 0 and stop_game == False:
        board[r][c].configure(text = 'X', fg = '#f64c72')
        states[r][c] = 'X'
        player = 'O'
        textPlay.config(text = "O's turn")
        if yes_AI.get() == 1:
            scores = {'X':-1, 'O':1, 'tie':0}
            bestRow, bestColumn = bestMove(states, player, scores)
            board[bestRow, bestColumn].configure(text = 'O', fg = '#f64c72')
            states[bestRow, bestColumn] = 'O'
            textPlay.config(text = "X's turn")

    if player == 'O' and states[r][c] == 0 and stop_game == False:
        board[r][c].configure(text = 'O', fg = '#f64c72')
        states[r][c] = 'O'
        player = 'X'
        textPlay.config(text = "X's turn")
        if yes_AI.get() == 1:
            scores = {'X':1, 'O':-1, 'tie':0}
            bestRow, bestColumn = bestMove(states, player, scores)
            board[bestRow, bestColumn].configure(text = 'X', fg = '#f64c72')
            states[bestRow, bestColumn] = 'X'
            textPlay.config(text = "O's turn")

    checkWinner()



def checkWinner1():
    global stop_game
    global states

    win = None

    win_color = '#85d139'
    for i in range(3):
        if states[i][0] == states[i][1] == states[i][2] != 0:
            if states[i][0] == 'X':
                win = 'X'
            else:
                win = 'O'

    for i in range(3):
        if states[0][i] == states[1][i] == states[2][i] != 0:
            if states[0][i] == 'X':
                win = 'X'
            else:
                win = 'O'

    if states[0][0] == states[1][1] == states[2][2] != 0:
        if states[1][1] == 'X':
            win = 'X'
        else:
            win = 'O'

    if states[2][0] == states[1][1] == states[0][2] != 0:
        if states[1][1] == 'X':
            win = 'X'
        else:
            win = 'O'

    temp1 = 0
    for i in range(3):
        for j in range(3):
            if states[i][j] == 0:
                temp1 = 1
    if temp1 == 0:
        textPlay.configure(text = "It's a tie! Click on 'Reset' to play again.")
        win = 'tie'

    return win



def checkWinner():
    global stop_game
    global states
    global board

    win = None

    win_color = '#85d139'
    for i in range(3):
        if states[i][0] == states[i][1] == states[i][2] != 0:
            board[i][0].config(bg = win_color)
            board[i][1].config(bg = win_color)
            board[i][2].config(bg = win_color)
            stop_game = True
            if states[i][0] == 'X':
                textPlay.config(text = "X wins! Click on 'Reset' to play again.")
                win = 'X'
            else:
                textPlay.config(text = "O wins! Click on 'Reset' to play again.")
                win = 'O'

    for i in range(3):
        if states[0][i] == states[1][i] == states[2][i] != 0:
            board[0][i].config(bg = win_color)
            board[1][i].config(bg = win_color)
            board[2][i].config(bg = win_color)
            stop_game = True
            if states[0][i] == 'X':
                textPlay.config(text = "X wins! Click on 'Reset' to play again.")
                win = 'X'
            else:
                textPlay.config(text = "O wins! Click on 'Reset' to play again.")
                win = 'O'

    if states[0][0] == states[1][1] == states[2][2] != 0:
        board[0][0].configure(bg = win_color)
        board[1][1].configure(bg = win_color)
        board[2][2].configure(bg = win_color)
        stop_game = True
        if states[1][1] == 'X':
            textPlay.config(text = "X wins! Click on 'Reset' to play again.")
            win = 'X'
        else:
            textPlay.config(text = "O wins! Click on 'Reset' to play again.")
            win = 'O'

    if states[2][0] == states[1][1] == states[0][2] != 0:
        board[2][0].configure(bg = win_color)
        board[1][1].configure(bg = win_color)
        board[0][2].configure(bg = win_color)
        stop_game = True
        if states[1][1] == 'X':
            textPlay.config(text = "X wins! Click on 'Reset' to play again.")
            win = 'X'
        else:
            textPlay.config(text = "O wins! Click on 'Reset' to play again.")
            win = 'O'

    temp1 = 0
    for i in range(3):
        for j in range(3):
            if states[i][j] == 0:
                temp1 = 1
    if temp1 == 0:
        textPlay.configure(text = "It's a tie! Click on 'Reset' to play again.")
        win = 'tie'

    return win


f = [[0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]]
board = [[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]]
states = [[0, 0, 0],
         [0, 0, 0],
         [0, 0, 0]]

def reset():
    global stop_game
    global player
    global board
    global states
    for i in range(3):
        for j in range(3):
            board[i][j].configure(text = ' ', fg = '#ffda30', bg = "#242582")
            states[i][j] = 0
    stop_game = False
    textPlay.configure(text = "Start the Game!!!")
    temp = random.choice([0, 1])
    if temp == 0:
        player = 'O'
    else:
        player = 'X'




for i in range(3):
    for j in range(3):
        f[i][j] = Frame(game, width = 150, height = 150)
        f[i][j].propagate(False)
        f[i][j].grid(row = i+2, column = j, sticky = "nsew", padx = 1, pady = 1)
        board[i][j] = Button(f[i][j], font = ("Helvatica", 70), bg = "#242582", fg = "#ffda30",
                        command = lambda    r = i, c = j: callback(r, c))
        board[i][j].pack(expand = True, fill = BOTH)


reset_game = Button(text = "Reset the game!", font = ("Helvatica", 15), bg = "#ffda30", fg = "#000000", 
               command = lambda    :reset())
reset_game.grid(row = 5, column = 0, columnspan = 2, sticky = 'nsew')


quit_game = Button(text = "Quit game!", font = ("Helvatica", 15), bg = "#ffda30", fg = "red", 
                   command = lambda    :game.destroy())
quit_game.grid(row = 5, column = 2, sticky = 'nsew')


game.resizable(False, False)
game.mainloop()

在回调中,在第 2 个 'if condition' 中,您应该添加:

player = 'X'

并在下一个作为玩家'O'以更换玩家。