在 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'以更换玩家。
我正在制作井字游戏。在此,有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'以更换玩家。