井字游戏(Python)中的Minimax实现无法正常工作-不知道为什么

时间:2020-03-30 21:49:31

标签: python tic-tac-toe minimax

我目前正在尝试使用在Python中实现的minimax制作井字游戏。我尝试实现的另一个功能是不同的电路板尺寸。但总体而言,不幸的是,该算法无法正常工作。 作为一个初学者,这对我来说并不奇怪,但是这种情况似乎毫无希望。我试图调整很多东西(对我来说似乎很多),以得到相同的结果-计算机从左上角填充到右下角。





#Sprawdzenie czy ktos wygral w poziomie lub pionie / straight line check
def winLine(line, letter):
    return all(n == letter for n in line)

#Utworzenie nowej listy z elementow przekatnych / diagonal check 
def winDiagonal(board, letter):
    arr = []
    tArr = []
    for n in range(boardSize):
        arr.append(board[n][n])
        tArr.append(board[n][boardSize-n-1])
    if winLine(arr, letter):
        return True
    elif winLine(tArr, letter): 
        return True
    else:
        return False

def checkWinner (board):
    #Liczenie wolnych pol / checking the available fields
    openSpots = 9
    for n in range(boardSize):
        for m in range(boardSize):
            if board[n][m] == '0':
                openSpots += 1

    #Transpozycja planszy, by mozna bylo latwo zastosowac winLine na kolumach / transposition of the board
    for letter in (person, ai):
        transPos = list(zip(*board))

        #Sprawdzanie w poziomie / horizontal check
        if any(winLine(row, letter) for row in board):
            #print('winline horizontal')
            return letter

        #Sprawdzanie w pionie / vertical check
        elif any (winLine(col, letter) for col in transPos):
            #print('winline vertical')
            return letter

        #Sprawdzanie po przekatnych / diagonal check
        elif winDiagonal(board, letter):
            return letter

        elif openSpots == 0: return 'tie'

        else: return 'none'

#Funkcja sprawdzajaca czy dane pole jest wolne / checks whether the field is available
def available (row, col):
    global board
    #Sprawdzenie czy pole jest wolne
    if board[row][col] == '0':
        return True
    else:

        return False

#Stale dla algorytmu minimax / minimax initial scores to compare against
minTarget = float('inf')
maxTarget = float('-inf')

#Slownik z wartosciami liczbowi dla wynikow, komputer maksymalizuje / a dictionary with scores for particular results
scores = {
    'X': 10,
    'O': -10,
    'tie': 0
}

#Algorytm minimax

def minimax(myBoard, depth, maximizes):

    #Sprawdzenie czy zaszla wygrana lub remis / Checking whether there is a win or tie
    res = checkWinner(myBoard)
    if (res != 'none'):
        return scores[res]

    #Gracz maksymalizujacy/ Maximizing player
    elif maximizes == True:
        bestScoreMax = maxTarget
        for n in range(boardSize):
            for m in range(boardSize):
                if board[n][m] == '0':
                    board[n][m] = person
                    score = minimax(board, depth + 1, False)
                    board[n][m] = '0'
                    bestScoreMax = max([score, bestScoreMax])

        return bestScoreMax

    #Gracz minimalizujacy / minimizing player
    elif maximizes == False:
        bestScoreMin = minTarget
        for n in range(boardSize):
            for m in range(boardSize):
                if board[n][m] == '0':
                    board[n][m] = ai
                    score = minimax(board, depth + 1, True)
                    board[n][m] = '0'
                    bestScoreMin = min([score, bestScoreMin])

        return bestScoreMin

def makeMove(row, col):
    global board
    board[row][col] = ai

def computedMove():
    global board
    myBoard = board
    computedTarget = maxTarget
    moveX = 2
    moveY = 2
    for n in range(boardSize):
        for m in range(boardSize):
            if myBoard[n][m] == '0':       
                score = minimax(myBoard, 0, True)
                if score > computedTarget:
                    computedTarget = score
                    moveX = n
                    moveY = m

    makeMove(moveX, moveY)

    #print(str(move.x) + ' ' + str(move.y))

# Funkcja pobierajaca ruch uzytkownika / player input for the move

def getPlayerMove():
    global board
    res = input('Please type in your move on the form \"x y\", x being the number of the row and y the number of the column of your choosing.\n')
    col, row = res.split(" ")
    row = int(row)
    col = int(col)
    if available(row-1, col-1):
        board[row-1][col-1] = person
    else:
        print('You cannot make that move')
        getPlayerMove()


def drawBoard():
    global board
    for n in range(boardSize):
        for m in range(boardSize):
            if board[n][m] == '0':
                print(' - ', end='')
            else:
                print(' '+board[n][m]+' ', end='')
        print('\n')

#Zmienna powiadamiajaca o stanie rozgrywki / variable indicating the state of the game
playing = False

#  initializing the variable
boardSize = 0
# initializing the players
person = 'X'
ai = 'O'

#Gracz posiadajacy ruch (a takze rozpoczynajacy) / player who is playing at the moment
currentPlayer = ''

while True:
    currentPlayer = person
    boardSize = int(input("Please enter the size of the board. (one side)\n"))
    global board 
    board = [['0' for i in range(boardSize)] for i in range(boardSize)]
    print("You go first.")
    playing = True

    while playing:
        if currentPlayer == person:
            drawBoard()
            getPlayerMove()

            if checkWinner(board) == person:
                drawBoard()
                print("Yaay, you won!")
                playing = False

            else:
                if checkWinner(board) == 'tie':
                    drawBoard()
                    print('It\'s a tie!')
                    break
                else:
                    currentPlayer = ai

        elif currentPlayer == ai:
            computedMove()
            if checkWinner(board) == ai:
                drawBoard()
                print('You lose!')
                playing = False
            else:
                if checkWinner(board) == 'tie':
                    drawBoard()
                    print('It\'s a tie!')
                    break
                else:
                    currentPlayer = person

    if not input('Do you want to play again?').lower().startswith('y'):
        break






1 个答案:

答案 0 :(得分:0)

在computeMove中,您应该首先播放ai动作,然后检查得分。

def computedMove():
    global board
    myBoard = board
    computedTarget = maxTarget
    moveX = 2
    moveY = 2
    for n in range(boardSize):
        for m in range(boardSize):
            if myBoard[n][m] == '0': 
                myBoard[n][m] = ai                  #This is added      
                score = minimax(myBoard, 0, True)
                if score > computedTarget:
                    computedTarget = score
                    moveX = n
                    moveY = m

    makeMove(moveX, moveY)

在minimax函数中,也应为myBoard和board使用相同的变量。