Заведём переменные, отслеживающие сделанные ходы.
Так можно исключать ходы, которые уже были сделаны, не включая их в возвращаемые значения функции.
Сначала найдём для победы Вани первым или вторым ходом, а затем исключим победу Вани только первым ходом.
# Победа Пети первым или вторым, или третьим ходом
def f(x, h, p, v):
if (h == 2 or h == 4 or h == 6) and x >= 21:
return 1
elif h == 6 and x < 21:
return 0
elif x >= 21 and h < 6:
return 0
else:
if h % 2 == 0:
if h == 2:
return f(x + 1, h + 1, p, 1) and f(x + 2, h + 1, p, 2) and f(x * 2, h + 1, p, 3) # стратегия проигравшего
elif h == 4:
if v == 1:
return f(x + 2, h + 1, p, v) and f(x * 2, h + 1, p, v)
elif v == 2:
return f(x + 1, h + 1, p, v) and f(x * 2, h + 1, p, v)
elif v == 3:
return f(x + 1, h + 1, p, v) and f(x + 2, h + 1, p, v)
else: # Петин ход
if h == 1:
return f(x + 1, h + 1, 1, v) or f(x + 2, h + 1, 2, v) or f(x * 2, h + 1, 3, v) # стратегия победителя
elif h == 3:
if p == 1:
return f(x + 2, h + 1, 2, v) or f(x * 2, h + 1, 3, v)
elif p == 2:
return f(x + 1, h + 1, 1, v) or f(x * 2, h + 1, 3, v)
elif p == 3:
return f(x + 1, h + 1, 1, v) or f(x + 2, h + 1, 2, v)
elif h == 5:
if p == 1:
return f(x + 2, h + 1, p, v) or f(x * 2, h + 1, p, v)
elif p == 2:
return f(x + 1, h + 1, p, v) or f(x * 2, h + 1, p, v)
elif p == 3:
return f(x + 1, h + 1, p, v) or f(x + 2, h + 1, p, v)
for x in range(1, 21):
if f(x, 1, 0, 0) == 1:
print("Задача 21:", x)
# Исключаем победу Пети только первым ходом
def f(x, h):
if h == 2 and x >= 21:
return 1
elif h == 2 and x < 21:
return 0
elif x >= 21 and h < 2:
return 0
else:
if h % 2 != 0:
return f(x + 1, h + 1) or f(x + 2, h + 1) or f(x * 2, h + 1) # стратегия победителя
else:
return f(x + 1, h + 1) and f(x + 2, h + 1) and f(x * 2, h + 1) # стратегия проигравшего(любой ход)
for x in range(1, 21):
if f(x, 1) == 1:
print("Победа Пети первым ходом:", x)
# Победа Пети вторым ходом
def f(x, h, m):
if h == 4 and x >= 21:
return 1
elif h == 4 and x < 21:
return 0
elif x >= 21 and h < 4:
return 0
else:
if h % 2 != 0:
if h == 1:
return f(x + 1, h + 1, 1) or f(x + 2, h + 1, 2) or f(x * 2, h + 1, 3) # стратегия победителя
elif h == 3:
if m == 1:
return f(x + 2, h + 1, m) or f(x * 2, h + 1, m)
elif m == 2:
return f(x + 1, h + 1, m) or f(x * 2, h + 1, m)
elif m == 3:
return f(x + 1, h + 1, m) or f(x + 2, h + 1, m)
else:
return f(x + 1, h + 1, m) and f(x + 2, h + 1, m) and f(x * 2, h + 1, m)
for x in range(1, 21):
if f(x, 1, 0) == 1:
print("Победа Пети вторым ходом:", x)
def move(n,lim,s,t):
player = 2-n%2
rival = 3-player
if s>= 21: return rival
if n > lim: return 0
pos = [(s+1,0),(s+2,1),(s*2,2)]
if len(t) > 1: del pos[t[-2]]
res = [move(n+1,lim,x[0],t+[x[1]]) for x in pos]
if any([x==player for x in res]): return player
if all([x==rival for x in res]): return rival
return 0
print('#19:',*[s for s in range(1,21) if move(1,1,s,[])==0 and move(1,3,s,[])==1])
print('#20:',*[s for s in range(1,21) if move(1,2,s,[])==0 and move(1,4,s,[])==2])
print('#21:',*[s for s in range(1,21) if move(1,3,s,[])==0 and move(1,5,s,[])==1])