繁体   English   中英

为什么我的 minimax tic tac toe 试图覆盖玩家的移动?

[英]Why is my minimax tic tac toe trying to overwrite the player's move?

我一直在 python 中使用玩家对计算机组件开发井字游戏。 我使用/稍微更改了一些 minimax 代码以作为“计算机”玩家与我的游戏一起工作。 该游戏适用于 1 或 2 个动作,但随后“计算机”会尝试覆盖玩家的动作。 我一直在寻找明显的错误,但找不到问题所在。 感谢您的任何建议。

这是我的代码。

from tkinter import *
import customtkinter
import random
import gametree

customtkinter.set_appearance_mode("Dark")
#creating CTk window for app
root = customtkinter.CTk()

#setting window width and height
root.geometry('500x300')


#Creating label
label = customtkinter.CTkLabel(master=root,
                               text="Tic Tac Toe",
                               width=120,
                               height=50,
                               font=("normal", 20),
                               corner_radius=8)
label.place(relx=0.25, rely=0.8, anchor=CENTER)

#Handling clicks
def clickbutton(r, c):
    buttons[r][c]["text"]="X"
    buttons[r][c]="X"
    computerplay()

#Button matrix
buttons = [
     [0,0,0],
     [0,0,0],
     [0,0,0]]
 
#Matrix identifying whether buttons are active or inactive
board=[[0,0,0],[0,0,0],[0,0,0]]
 
for i in range(3):
    for j in range(3):                                 
        buttons[i][j] = Button(height = 3, width = 6, font = ("Normal", 20),
                        command = lambda r = i, c = j : clickbutton(r,c))
        buttons[i][j].grid(row = i, column = j)



#Creating label
label = customtkinter.CTkLabel(master=root,
                               text="Player vs. Computer",
                               width=120,
                               height=25,
                               corner_radius=8)
label.place(relx=0.25, rely=0.9, anchor=CENTER)



def computerplay():
    bestmove=gametree.findBestMove(board)
    buttons[bestmove[0]][bestmove[1]]['text']="O"
    board[bestmove[0]][bestmove[1]]="O"
root.mainloop()



极小极大代码:


# Python3 program to find the next optimal move for a player
player, opponent = 'O', 'X'
 
# This function returns true if there are moves left to make on the board. 
def isMovesLeft(board) :
    for i in range(3) :
        for j in range(3) :
            if not(board[i][j]==0):
                return True
    return False
 
# This is the evaluation function 
def evaluate(b) :
   
    # Checking rows for X or O victory.
    for row in range(3) :    
        if (b[row][0] == b[row][1] and b[row][1] == b[row][2]) :       
            if (b[row][0] == player) :
                return 10
            elif (b[row][0] == opponent) :
                return -10
 
    # Checking columns for X or O victory.
    for col in range(3) :
        if (b[0][col] == b[1][col] and b[1][col] == b[2][col]) :
         
            if (b[0][col] == player) :
                return 10
            elif (b[0][col] == opponent) :
                return -10
 
    # Checking diagonals for X or O victory.
    if (b[0][0] == b[1][1] and b[1][1] == b[2][2]) :
     
        if (b[0][0] == player) :
            return 10
        elif (b[0][0] == opponent) :
            return -10
 
    if (b[0][2] == b[1][1] and b[1][1] == b[2][0]) :
     
        if (b[0][2] == player) :
            return 10
        elif (b[0][2] == opponent) :
            return -10
 
    # Else if none of them have won then return 0
    return 0
 
# The minimax function considers all  possible ways the game can go and returns the value of the board
def minimax(board, depth, isMax) :
    score = evaluate(board)
 
    # If Maximizer has won the game return his/her
    # evaluated score
    if (score == 10) :
        return score
 
    # If Minimizer has won the game return his/her
    # evaluated score
    if (score == -10) :
        return score
 
    # If there are no more moves and no winner then
    # it is a tie
    if (isMovesLeft(board) == False) :
        return 0
 
    # If this maximizer's move
    if (isMax) :    
        best = -1000
 
        # Traverse all cells
        for i in range(3) :        
            for j in range(3) :
              
                # Check if cell is empty
                if (board[i][j]==0) :
                 
                    # Make the move
                    board[i][j] = player
 
                    # Call minimax recursively and choose
                    # the maximum value
                    best = max( best, minimax(board,
                                              depth + 1,
                                              not isMax) )
 
                    # Undo the move
                    board[i][j] = 0
        return best
 
    # If this minimizer's move
    else :
        best = 1000
 
        # Traverse all cells
        for i in range(3) :        
            for j in range(3) :
              
                # Check if cell is empty
                if (board[i][j] == 0) :
                 
                    # Make the move
                    board[i][j] = opponent
 
                    # Call minimax recursively and choose
                    # the minimum value
                    best = min(best, minimax(board, depth + 1, not isMax))
 
                    # Undo the move
                    board[i][j] = 0
        return best
 
# This will return the best possible move for the player
def findBestMove(board) :
    bestVal = -1000
    bestMove = (-1, -1)
 
    # Traverse all cells, evaluate minimax function for
    # all empty cells. And return the cell with optimal
    # value.
    for i in range(3) :    
        for j in range(3) :
         
            # Check if cell is empty
            if (board[i][j] == 0) :
             
                # Make the move
                board[i][j] = player
 
                # compute evaluation function for this
                # move.
                moveVal = minimax(board, 0, False)
 
                # Undo the move
                board[i][j] = 0
 
                # If the value of the current move is
                # more than the best value, then update
                # best/
                if (moveVal > bestVal) :               
                    bestMove = (i, j)
                    bestVal = moveVal
 
    return bestMove


我在更改按钮文本时切换了一些错误,但这没有帮助。 我希望计算机的游戏能一直运行到获胜,但它只玩了两步。

您只在此处更新buttons变量:

def clickbutton(r, c):
    buttons[r][c]["text"]="X"
    buttons[r][c]="X"
    computerplay()

您还需要像这样更新棋盘,类似于您在computerplay()中所做的:

def clickbutton(r, c):
    buttons[r][c]["text"]="X"
    buttons[r][c]="X"
    board[r][c]="X"
    computerplay()

一般来说,我认为你的代码过于复杂。 为什么使用两个不同的arrays? 您还有两个 minimax/bestmove 实例,一个就足够了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM