【问题标题】:What is wrong in my minimax algorithm in Tic Tac Toe using Tkinter in python?在 python 中使用 Tkinter 在井字游戏中的 minimax 算法有什么问题?
【发布时间】:2020-06-12 07:48:08
【问题描述】:

我正在制作井字游戏。在此,有 2 种模式。一种是两人模式,另一种是AI。两人模式运行良好。但是AI模式不起作用。当给定复选框中有勾号时,将应用 AI 模式,并且其中一个回合由 AI 播放。我已经使用极小极大算法进行 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()

【问题讨论】:

  • 欢迎来到 Stack Overflow!人们不是来修复你的代码的,所以你必须展示更多的工作才能得到好的答案。问题出在您的 GUI 中还是在您的 minimax 中?您是否在 GUI 之外测试了您的极小极大代码以尝试验证问题所在?你能用一个返回随机移动的玩家来替换极小极大,看看这是否有效?

标签: python tkinter artificial-intelligence tic-tac-toe minimax


【解决方案1】:

在回调中,在第二个“如果条件”内,您应该添加:

player = 'X'

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 2017-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多