Функция Minimax возвращает одинаковую оценку для всех возможных ходов в TicTacToe - PullRequest
0 голосов
/ 01 мая 2019

В цикле основной программы цикл for проходит через все пустые позиции на плате TicTacToe, а затем применяет функцию минимакса к каждой позиции, чтобы дать оценку этого конкретного движения.Однако для каждой конкретной конфигурации платы в данный момент на основе входных данных она возвращает одинаковую оценку для всех пустых мест.


board= [ "X", 1, 2, 
         3, "O", 5, 
         6 , 7, 8]

human = "O"
robot= "X"

def evaluation(board):
    if (winning(board, robot)):
        return +10
    elif (winning(board, human)):
        return -10
    else:
        return 0


def minimax(empty_spots, depth, maximizing_player):
    if depth==0 or len(empty_spots)==0:
        eval= evaluation(board)
        # print(f'The evaluation function returns: {evaluation(board)}')
        # return evaluation(board)
        return eval

    if maximizing_player:
        maxEval= -1000000
        empty_spots=list(filter(lambda spot: (spot!="O" and spot!="X"), board))
        # print(f'testing empty spots from maximizing_player{empty_spots}')

        #for the child of that position
        for spot in empty_spots:
            board[spot]=robot
            eval = minimax(empty_spots, depth-1, False)

            #then remove the move and replace it with the number
            board[spot]=spot
            maxEval= max(maxEval, eval)
            # print(f'The maxEval is {maxEval}')
        # print(f'The maxEval is {maxEval}')
        return maxEval

    else:
        minEval= +1000000
        empty_spots=list(filter(lambda spot: (spot!="O" and spot!="X"), board))
        # print(f'testing empty spots from minimizing_player{empty_spots}')

        #for each child of that position
        for spot in empty_spots:
            board[spot]=human
            eval= minimax(empty_spots, depth-1, True)

            #then remove the spot
            board[spot]=spot
            minEval=min(minEval, eval)
        # print(f'The minEval is {minEval}')
        return minEval



#the main program loop
while(True):

    while(True):
        try:    
            human_input=int(input("Please enter an integer from 0 to 8: "))
            #this should only take in empty spots
            if(human_input>=0 and human_input<=8):
                break
        except ValueError:
            print("Input must be an integer value.")    

    board[human_input]= human

    #returns a list of empty positions in the array 
    empty_spots=list(filter(lambda spot: (spot!="O" and spot!="X"), board))
    print(empty_spots)

    moves= []
    for spot in empty_spots:
        spot_eval= minimax(empty_spots, len(empty_spots), True)
        print(f'The spot eval for {spot} is {spot_eval}')
        moves.append(spot_eval)

    print(f'This is the moves array {moves}')
    #go through the moves array and pick out the best
    best_move= empty_spots[0]
    for move in moves:
        best_move= max(best_move, move)
    print(f'The best move is {best_move}')



Где я ожидал, что выход массива перемещения будет [10, -10,0 ..] и так далее для каждого пустого места.Вместо этого мой вывод, например:

enter image description here

1 Ответ

2 голосов
/ 02 мая 2019

Давайте посмотрим на этот цикл в вашей программе:

for spot in empty_spots:
    spot_eval = minimax(empty_spots, len(empty_spots), True)
    print(f'The spot eval for {spot} is {spot_eval}')
    moves.append(spot_eval)

Обратите внимание, что вызов функции minimax одинаков на всех итерациях цикла for, поскольку он не зависит от переменной spot. Так что в основном вы делаете len(empty_spots) вызовы функции minimax в этом цикле (которые все одинаковы). В результате массив moves заполняется тем же значением, которое равно значению, возвращаемому minimax(empty_spots, len(empty_spots), True)

...