Потерять в крестики-нолики

18

Напишите программу, в которую вы будете играть в крестики-нолики Мизера. То есть цель состоит в том, чтобы заставить вашего противника занять три места подряд.

Примите для стандартного ввода либо «X», либо «O» (буква, а не ноль), чтобы определить, с какой стороны будет воспроизводиться программа. Затем выведите одну цифру для вашего хода в свой ход и прочитайте одну цифру на ходу ваших оппонентов, пока игра не закончится (X всегда идет первым). После определения победителя выведите X или O для победителя или D для ничьей. Например, если О получает 3 подряд, Х выигрывает.

Предположим, что доска нумеруется так:

0|1|2
-----
3|4|5
-----
6|7|8

В идеале решение будет оптимальным и никогда не проиграет. Как и в крестики-нолики, идеальная игра всегда должна приводить к ничьей. Если приведенный выше протокол соблюдается, я могу автоматически проверять отправленные документы на соответствие различным стратегиям.

Победитель самый короткий код. бонусные очки, если он выбирает случайно из одинаково хороших ходов, чтобы сделать его немного более непредсказуемым.

captncraig
источник

Ответы:

10

Питон, 383 символа

M=[21,1344,86016,4161,16644,66576,65793,4368]
X=lambda B,k:any(m*k==B&m*3for m in M)
def S(B):
 if X(B,2):return 1,
 M=[i for i in range(0,18,2)if B>>i&3<2]
 return max((-S((B|3<<i)^87381)[0],i)for i in M)if M else(0,)
r='D'
c=ord(raw_input())&1
B=0
for i in range(9):
 if i&1==c:m=S(B^c*87381)[1];print m/2;B|=3-c<<m
 else:
  B|=2+c<<input()*2
  if X(B,2+c):r='XO'[c];break
print r

Плата Bпредставлена в виде целого числа , используя два бита на площадь, с 00и 01представляющим пустыми, 10представляющим O и 11представляющим X. Mпредставляет собой набор битмаски с 01в точках проигрышной тройки ( 21= 0b010101= верхняя строки и т.д.) , Xвычисляемых Если какой - либо проигрыш тройка для kприсутствует на доске. Sвыполняет ли минимаксный поиск оптимального хода для X, возвращая пару очков (1 = победа, -1 = поражение, 0 = ничья) и квадратный индекс. ^87381(= ^0b010101010101010101) переворачивает X и O, оставляя пустые квадраты без изменений.

Компьютер никогда не проигрывает, поэтому мне не нужно было включать эту проверку :).

Вероятно, существует более простой / короткий алгоритм, основанный на правилах, но он работает.

Кит Рэндалл
источник
Подлый подлый колдовство +1
Рохан Джунджхунвала