Неудачная попытка просчитать игру "Крестики-нолики"

Я написал программу "Крестики-нолики", которая должна при определённой ситуации на поле предсказывать исход партии при идеальной игре обоих сторон. То есть в основную функцию передаются занятые поля, и программа должна выдать ответ. Если X побеждает первым ходом, функция возвращает "X1", если O побеждает первым ходом, то возвращается строка "O1" и т.д.. Вот код:

from functools import lru_cache

wincombs = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6),
            (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6))

def moves(busyXcells, busyOcells):
    free_cells = list(range(9))
    for cell in busyXcells + busyOcells:
        free_cells.remove(cell)
    
    ret = []
    for cell in free_cells:
        if len(busyXcells) == len(busyOcells):
            ret.append((busyXcells + (cell, ), busyOcells))
        else:
            ret.append((busyXcells, busyOcells + (cell, )))
    return tuple(ret)

def CheckWin(busyXcells, busyOcells):
    for a, b, c in wincombs:
        if a in busyXcells and b in busyXcells and c in busyXcells or a in busyOcells and b in busyOcells and c in busyOcells:
            return 1
    return 0

@lru_cache(None)

def f(busyXcells, busyOcells):
    if CheckWin(busyXcells, busyOcells):
        return 'win'

    if any(f(x, y) == "win" for x, y in moves(busyXcells, busyOcells)):
        return "X1"
    
    if all(f(x, y) == 'X1' for x, y in moves(busyXcells, busyOcells)):
        return "O1"

    if any(f(x, y) == "O1" for x, y in moves(busyXcells, busyOcells)):
        return "X2"

    if all(f(x, y) == 'X2' for x, y in moves(busyXcells, busyOcells)):
        return "O2"

    if any(f(x, y) == "O2" for x, y in moves(busyXcells, busyOcells)):
        return "X3"

    return "draw"

Представим такую обстановку: Передадим её функции: print(f((0, 8), (2, 4))). Возвращается "X2", как и должно быть. Но когда я передаю функции следующую обстановкувведите сюда описание изображения print(f((0, ), (2, ))) Выводит "draw", хотя должен показывать победу за 3 хода. Таким образом, моя программа работает только наполовину


Ответы (1 шт):

Автор решения: Kamil Ismagilov

Проблема решилась. Переписал функцию f

def f(busyXcells, busyOcells):
    if CheckWin(busyXcells, busyOcells):
        return 'win'

    if any(f(x, y) == "win" for x, y in moves(busyXcells, busyOcells)):
        return "X1"
    
    if all(f(x, y) == 'X1' for x, y in moves(busyXcells, busyOcells)):
        return "O1"

    if any(f(x, y) == "O1" or f(x, y) == "win" for x, y in moves(busyXcells, busyOcells)):
        return "X2"

    if all(f(x, y) == 'X2' or f(x, y) == "X1" for x, y in moves(busyXcells, busyOcells)):
        return "O2"

    if any(f(x, y) == "O2" or f(x, y) == "O1" for x, y in moves(busyXcells, busyOcells)):
        return "X3"

    return "draw"

, и теперь всё работает. Суть в том, что если мы хотим вывести "X2" например, нам надо проверить не только возможную победу за два хода, но и за один ход, так как это тоже вариант, ведущий к победе. Аналогично с ответами "O2" и "X3"

→ Ссылка