Нужно написать игру Ним с двумя кучами и Двумя игроками (второй игрок это ИИ)
Игра ним для двух игроков с двумя кучами и без ограничения на количество забираемых камней. Напишите программу с «искусственным интеллектом» (ИИ), которая играет против пользователя и выигрывает, если может. Исходное количество камней в кучах задаёт пользователь, программа всегда ходит первой. Выигрывает забравший последний камень, и при окончании игры нужно объявить победителя. Алгоритм игры выглядит следующим образом:
Сначала пользователь вводит количества камней в кучах (натуральные числа, каждое на новой строке). Затем первый ход делает программа и выводит через пробел четыре числа: из какой кучи взяты камни; сколько камней взято; сколько камней осталось в кучах, сначала в первой, затем во второй. Затем ход делает пользователь: вводит на отдельных строках номер кучи и количество камней, которые он хочет взять. Если ход некорректный, например, пользователь пытается взять камней больше, чем есть в куче, программа должна вывести: Некорректный ход: <куча> <кол-во камней> и ожидать нового ввода пользователя. После каждого корректного хода игрока или ИИ нужно выводить четыре числа, как и после первого хода ИИ. Если выигрывает игрок, то надо вывести фразу: Вы выиграли!, а если ИИ – фразу: ИИ выиграл! Все сообщения программы должны строго соответствовать условию.
Формат ввода Для старта игры вводятся два натуральных числа. Пример диалога игры:
10
10
2 1 10 9
1
15
Некорректный ход: 1 15
2
10
Некорректный ход: 2 10
2
7
2 7 10 2
1 8 2 2
2
1
2 1 2 1
1 1 1 1
1
1
1 1 0 1
2 1 0 0
ИИ выиграл!
Примечания Обратите внимание, что ИИ в выводе не показывает получаемые данные от игрока.
a = int(input())
b = int(input())
while a != 0 or b != 0:
if a == 0:
print(1, b, 0, 0)
b -= b
elif b == 0:
print(1, a, 0, 0)
a -= a
elif a > 0:
if a != 1:
print(1, a - 1, a - (a - 1), b)
a -= (a - 1)
else:
print(1, 1, 0, b)
a -= 1
elif b > 0:
if b != 1:
print(1, b - 1, a, b - (b - 1))
b -= (b - 1)
else:
print(1, 1, a, 0)
b -= 1
if a == 0 and b == 0:
print("ИИ выиграл!")
while True:
c = int(input())
d = int(input())
if c == 1:
if 0 < d <= a:
break
else:
print("Некорректный ход:", c, d)
continue
elif c == 2:
if 0 < d <= b:
break
else:
print("Некорректный ход:", c, d)
continue
else:
print("Некорректный ход:", c, d)
continue
if c == 1:
a -= d
else:
b -= d
print(c, d, a, b)
if a == 0 and b == 0:
print("Вы выиграли!")
Я так сделал но проверка пишет что в некоторых случаях "ИИ должен был выиграть, а проиграл". Нужно написать другой алгоритм ИИ. Я дохринилиард раз пробовал переделывать алгоритм но как видите не получилось(
Ответы (1 шт):
Вроде выигрышная стратегия в данном случае - это на свой ход всегда уравнивать количество камней в кучках. Таким образом если после игрока в одной из кучек остаётся 1 камень, то ИИ сравняв кучки, в обоих оставит по одному, что означает выигрыш на свой следующий ход. А если игрок опустошит одну из кучек, то выигрыш сразу. Все остальные случаи сводятся к походу на комбинацию 1:1. Единственное, когда с таким ИИ игрок может выиграть - это когда изначально кучки равны, ИИ вынужден их разбалансировать, а игрок станет исполнять стратегию ИИ, т.е. сам будет выравнивать кучки (и не дай бог ему хоть раз ошибиться :)).
Примерно так:
# функция взятия amount камней из кучки what
def take(what, amount):
pile[what] -= amount
print(what, amount, pile[1], pile[2])
# в словаре хранятся кучки под ключами 1 и 2
pile = {1: int(input()),
2: int(input())}
while True:
if pile[1] > pile[2]: # берём из первой кучки чтобы сравнять кучки
take(1, pile[1] - pile[2])
elif pile[1] < pile[2]: # берём из второй кучки чтобы сравнять кучки
take(2, pile[2] - pile[1])
else: # кучки уже равны - ничего не остаётся как взять камень из одной из них (лучше брать по минимуму, чтобы измотать игрока - вдруг он где ошибётся, и ИИ перехватит инициативу :))
take(1, 1)
if pile[1] == 0 and pile[2] == 0:
print("ИИ выиграл!")
break
while True:
p = int(input())
n = int(input())
if (p == 1 or p == 2) and 0 < n <= pile[p]:
break
print("Некорректный ход:", p, n)
take(p, n)
if pile[1] == 0 and pile[2] == 0:
print("Вы выиграли!")
break