Как сохранить состояние при рекурсии в python - PullRequest
0 голосов
/ 16 февраля 2020

Я пытаюсь реализовать простой алгоритм min max для игры ti c ta c toe в python У меня проблема со следующим методом:

def get_best_move(self, board, empty_cells, turns, points=None):
        if points is None:
            points = []

#here I loop trough the empty cells on the board and fill it with 'X' or 'O'
        for cell in empty_cells:
            new_board = copy.deepcopy(board)
            new_turns = turns.copy()

            if turns[-1] == 'X':
              new_board[cell[0]][cell[1]] = 'O'
              new_turns.append('O')
            elif turns[-1] == 'O':
              new_board[cell[0]][cell[1]] = 'X'
              new_turns.append('X')

#here i select all the empty cells after a move
            new_empty_cells = [[index1,index2] for index1,value1 in enumerate(new_board) for index2,value2 in enumerate(value1) if value2==' ']

#here I check if there is a winner and append the points list with 1,0,-1 accordingly
            if self.winner(new_board) == 'X':
                return points.append(-1)
            elif self.winner(new_board) == 'O':
                return points.append(1)
            elif len(new_empty_cells) == 0:
                return points.append(0)
            else:
#here I call this method again if there is no winner or the game is not a draw. 
                self.get_best_move(new_board, new_empty_cells, new_turns, points)
            return print(points)

метод принимает следующие аргументы:

board = [[' ',' ',' '],
         [' ',' ',' '],
         [' ',' ',' ']]

empty_cells = [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]

turns = ['X']

Таким образом, при наличии такой доски должно быть 255168 возможных результатов, поэтому я ожидаю, что мой список очков будет содержать 255168 значений 1,0, -1, но все, что у меня есть, это:

[1]
[1]
[1]
[1]
[1]
[1]

В идеале я хотел бы получить отдельный список для каждой ячейки в поле для l oop. У меня такое чувство, что я совершаю довольно очевидную ошибку, но я просто не могу ее обнаружить, поэтому любая помощь будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2020

Как указано в комментариях, ваш l oop всегда будет выходить на первой итерации.

Либо if приведет к выражению return, либо в нижней части вашего тела for l oop есть универсальный элемент return print(points). Так что, что бы ни случилось, ваш for l oop выполнит return в своей первой итерации.

Это явно не желаемое поведение. Переместите финал return из for l oop.

0 голосов
/ 16 февраля 2020

Я не совсем уверен, что понимаю вашу логику c.

Я бы, вероятно, полностью игнорировал пустые позиции на доске. И следите за тем, где вместо этого X s и O s.

Во всяком случае

Когда вы рекурсивно вызываете свою функцию self.get_best_move(new_board, new_empty_cells, new_turns, points), вы должны либо вернуть, либо добавить ее возвращаемое значение в твой список Не уверен, но вы полностью отбрасываете возвращаемое значение; это не может быть правдой.

return self.get_best_move(new_board, new_empty_cells, new_turns, points)

или

points + self.get_best_move(new_board, new_empty_cells, new_turns, points)

что-то в этом роде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...