Неудачная попытка просчитать игру "Крестики-нолики"
Я написал программу "Крестики-нолики", которая должна при определённой ситуации на поле предсказывать исход партии при идеальной игре обоих сторон. То есть в основную функцию передаются занятые поля, и программа должна выдать ответ. Если 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 шт):
Проблема решилась. Переписал функцию 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"