Определить победу в Tictactoe

19

Давай поиграем в гольф!

С учетом состояния крестики-нолики (пример :)

|x|x|o|
|x|o|x|
|o|o|x|

Определите, является ли игра winа loseили cat. Ваш код должен выводить любую из этих опций с учетом состояния. Вышеприведенная игра должна вывестиlose

Просто чтобы прояснить: выигрыш определяется как любые 3 xс подряд (диагональ, горизонталь, вертикаль). проигрыш - 3 oс подряд, а catигра - ни одного подряд.

Чтобы сделать вещи интересными, вы должны определить свою структуру ввода для состояния, которое вы должны затем объяснить. Например, xxoxoxooxдопустимое состояние, как показано выше, где каждый из символов читается слева направо, сверху вниз. [['x','x','o'],['x','o','x'],['o','o','x']]это игра в многомерном массиве, читаемая аналогичным образом. В то время 0x1a9как шестнадцатеричное для 110101001может работать как подходящее сжатие, где 1можно манипулировать для xs и 0можно манипулировать для o.

Но это всего лишь некоторые идеи, я уверен, что у вас их может быть много.

Ключевые правила:

  1. Ваша программа должна быть в состоянии принять любое жизнеспособное состояние.
  2. Форма ввода должна быть в состоянии представить любое состояние.
  3. «Состояние победы должно быть определено с доски»
  4. Предположим, полная доска
  5. Winперед, loseнапример, в случае «xxxoooxxx»

Наименьшее количество персонажей выигрывает

Дилан Мадисетти
источник
1
Мне нравится эта структура ввода: (win|lose|cat) [xo]{9}где первое слово обозначает, является ли игра победой, поражением или кошкой (?) Для игрока х. Способен представлять любое государство.
Runer112
2
Могу ли я предложить правило типа «Состояние выигрыша должно быть определено на доске» или «Вход не должен содержать никакой информации, кроме состояния доски»?
подземный
3
Мы предполагаем, что играли только в легальные игры? Если это так, то определенные состояния были бы невозможны, например, XXX OOO XXX, но в противном случае некоторые состояния с полным пансионом включают это в качестве четвертого невозможного результата, где X выигрывает, но O также выигрывает.
Бунт
10
почему "кошка" из интереса?
Крис
7
@DylanMadisetti: никогда не слышал этого раньше, и googlign для «победа, потеря кота» ничего не придумала. Я бы пошел с галстуком или ничьей лично. Или в случае с этой игрой может быть «неизбежность». ;-) Я не особо возражаю против соревнований. Строка - это строка. ;-)
Крис

Ответы:

11

Ruby 2.0, 85 символов

Вот простое решение на основе битовой маски в Ruby:

d=gets.hex
$><<[292,146,73,448,56,7,273,84].map{|m|d&m<1?:lose:d&m<m ?:cat: :win}.max

Доска представлена ​​в виде шестнадцатеричного числа, состоящего из девяти бит, соответствующих девяти квадратам. 1 - это X, 0 - это O. Это так же, как 0x1a9пример в вопросе, хотя0x это необязательно!

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

Посмотрите, как это работает на Ideone здесь .

Пол Престиж
источник
1
Ваш список содержит 273дважды. И мне очень нравится maxидея!
Вентеро
1
О @Ventero, всегда с неясными оптимизациями (спасибо)
Пол Престиж
На доске могут быть пустые места. Ваш формат ввода не учитывает это и, следовательно, не может представлять какое-либо жизнеспособное состояние игры.
Стивен Остермиллер
2
Правило @StephenOstermiller 4: примите полный совет. Вы правы в том, что это правило, возможно, противоречит правилам 1 и 2, однако, если вы прочитаете все комментарии к вопросу, я думаю, что это соответствует духу вопроса (неполные доски объявлений не рассматриваются, в то время как полные, но незаконные доски объявлений.) Однако я думаю, что восьмеричный будет более удобным для пользователя форматом ввода, чем шестнадцатеричный.
Уровень Река St
1
Понял, я думал, что полный означает что-то другое.
Стивен Остермиллер
10

Mathematica, 84 символа

a=Input[];Which[Max@#>2,win,Min@#<1,lose,1>0,cat]&@{Tr@a,Tr@Reverse@a,Tr/@a,Total@a}

Формат ввода: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}

alephalpha
источник
Что тут происходит?
Seequ
3
@TheRare Начните с правой стороны. Tr@aесть след поля (сумма по диагонали), Tr@Reverse@aесть след перевернутого поля (некоторые более анти-диагональ), Tr/@aбудет Trприменяться к каждой строке, которая дает вам сумму по каждой строке, Total@aдает вам сумму по каждой колонке. В общем, у вас есть все 8 строк, которые нужно проверить. Затем Whichвещь применяется к этому (в основном, к if/elseif/elseвыражению), где #представляет этот список из 8 значений. ifесть 3победа, else ifесть 0проигрыш else if 1>0(правда) cat.
Мартин Эндер
6

Баш: 283 262 258

Отличается относительно дружественным интерфейсом.

t(){ sed 's/X/true/g;s/O/false/g'<<<$@;}
y(){ t $(sed 's/X/Q/g;s/O/X/g;s/Q/O/g'<<<$@);}
f(){($1&&$2&&$3)||($1&&$5&&$9)||($1&&$4&&$7)||($2&&$5&&$8)||($3&&$5&&$7)||($3&&$6&&$9)||($4&&$5&&$6)||($7&&$8&&$9)}
f $(t $@)&&echo win||(f $(y $@)&&echo lose)||echo cat

Выполнить bash tictactoe.sh O X O X O X X O X

Примечание: список из 9 позиций является стандартным матричным представлением. Неважно, если доска представлена ​​в виде основной колонки или основной строки, читается слева направо или сверху вниз - игры в крестики-нолики и крестики (или крестики-нолики, если вы настаиваете) симметричны, поэтому порядок ввода должен быть несущественным к результату в каждой правильной реализации, пока вход является линейным.

Редактировать: Благодаря HJK для более короткого предложения синтаксиса функции.

буйство
источник
Рассмотрим t() { ... }вместо function t? Можно сохранить некоторые символы там. :)
hjk
Я совершенно забыл про синтаксис альтернативной функции - спасибо!
Бунт
Пробелы вокруг не требуются, <<<чтобы сохранить еще четыре символа.
Майкл Миор
4

Befunge 93 - 375

Принимает двоичную строку в качестве ввода.

99>~\1-:!!|>v  
>0v>v>v   >^$>v
^+ + +    0<:p:
>#+#+#+    ^246
^+ + +    0<265
>#+#+#+    ^pp6
^+ + +    0<2++
 #+#+#+     55p
   0 0      552
  >^>^>0v   +46
v+ + +  <   ppp
>0 + + + v  444
   v!!-3:<< 246
  v_"ni"v   ppp
  0v" w"<   :+:
  \>,,,,@   266
  ->,,,@    555
  !^"cat"_^ 645
  !>:9-! ^  +:+
  >|        p:p
   >"eso"v  6p6
 @,,,,"l"<  246
            p2p
            >^ 
  v       <^  <

Читает строку. Bruteforce пишет это (самая правая вертикальная полоса) в виде матрицы между

^+ + + 
>#+#+#+
^+ + + 
>#+#+#+
^+ + + 
 #+#+#+

добавление решетки (idk). Определяет сумму столбцов, строк и двух диагнозов. Сравнивает эти значения с 3 («победа») или 0 («проигрыш»), иначе, если все значения равны 1 или 2, тогда ничья («кошка»).

AndoDaan
источник
4

GolfScript, 27 символов

70&.{~"win""lose"if}"cat"if

Формат ввода - это строка, состоящая из восьми восьмеричных цифр, каждая из которых (избыточно) кодирует три последовательных квадрата платы:

  • Первые три цифры каждая кодируют одну строку платы сверху вниз и слева направо.
  • Следующие три цифры каждая кодируют один столбец платы, слева направо и сверху вниз.
  • Последние две цифры каждая кодируют одну из диагоналей (сначала сверху вниз, слева направо, затем снизу слева вверху справа).

Чтобы закодировать последовательность (строка / столбец / диагональ) из трех квадратов в виде восьмеричной цифры, замените каждый x в последовательности на 1, а каждый oна 0, и интерпретируйте полученную последовательность из единиц и нулей как двоичное число от 0 до 7 включительно.

Этот формат ввод довольно лишний (все позиции досок кодируются по меньшей мере в два раз, с центральным положение кодировало четыре раза), но это однозначно представлять любое возможное состояние полностью заполненный крестики-нолики борта, и не напрямую кодировать победитель на входе.

Входные данные могут, необязательно, содержать пробелы или другие разделители между цифрами. На самом деле, все, что действительно волнует программу, это то, содержит ли входная строка цифры 7или0 .

Например, пример платы:

|x|x|o|
|x|o|x|
|o|o|x|

может быть представлен входом:

651 643 50

Для удобства вот программа GolfScript для преобразования макета художественной доски ASCII, как показано в задании выше, во входную строку, подходящую для этой программы:

."XOxo"--[{1&!}/]:a[3/.zip"048642"{15&a=}%3/]{{2base""+}%}%" "*

Этот конвертер игнорирует любые символы, кроме xи o, в любом случае, при вводе. Он генерирует однозначную строку (в комплекте с разделителями пробелов, как показано выше), подходящую для ввода в программу определения выигрыша, указанную выше, поэтому объединение этих двух программ можно использовать для определения победителя непосредственно с доски объявлений ASCII.

Кроме того, вот обратный преобразователь, просто чтобы продемонстрировать, что вход действительно однозначно представляет плату:

.56,48>-- 3<{2base-3>{"ox"=}%n}%"|".@@*+);

Ps. Вот онлайн-демонстрация этого решения.

Илмари Каронен
источник
2
Формат ввода выглядит как обман, так как большая часть работы происходит при создании ввода.
Арку
@Arkku: Ну, да, это так, но вопрос прямо говорит, что «вы можете определить свою структуру ввода для состояния - что вы должны затем объяснить». Он даже показывает битовую упакованную шестнадцатеричную строку в качестве примера правильного формата ввода; единственное различие между этим и моим форматом ввода состоит в том, что я переупорядочиваю и дублирую некоторые биты.
Илмари Каронен
6
Это именно то дублирование, которое кажется читом. (например, это делает непосредственно кодировать победителя , как наличие 7 или 0 на входе)
Arkku
Тем не менее, это умная кодировка, она избыточна, но делает поиск решения гораздо более эффективным, чем любая не избыточная кодировка!
ARRG
3

Python 2 - 214 байтов

b=eval(raw_input())
s=map(sum,b)
w,l='win','lose'
e="if min(s)<1:print l;a\nif max(s)>2:print w;a"
exec e+'\ns=map(sum,zip(*b))\n'+e
m=b[1][1]
for i in 0,2:
 if m==b[0][i]==b[2][abs(i-2)]:print[l,w][m];a
print'cat'

Я уверен, что есть улучшения, которые будут сделаны.

Бежать:

python2 tictactoe.py <<< '[[1,1,1],[1,0,1],[0,1,0]]'

который представляет эту доску:

X|X|X
-----
X|O|X
-----
0|X|0

Выход с NameErrorисключением во всех случаях, кроме cat.

undergroundmonorail
источник
О, я никогда не знал о <<<! +1 только за это.
Грег Хьюгилл
@GregHewgill Это довольно удобно. ./whatever <<< 'blah blah blah'то же самое, echo -n 'blah blah blah' | ./whateverно без отдельного процесса для echo.
подземный
@undergroundmonorail echoin bashна самом деле является встроенным, поэтому не разворачивает новый процесс
Bob
@GregHewgill это называется herestring
3

Haskell, 146 символов

Чтобы сделать вещи интересными, вы должны определить свою структуру ввода для состояния, которое вы должны затем объяснить.

OK :). Мое представление доски является одним из тех 126 символов

ĻŃŇʼnŊœŗřŚşšŢťŦŨųŷŹźsƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂDždžLjǏǑǒǕǖǘǝǞǠǤǯDZDzǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸ''ˀˎː˔~˭ˮ˰˴˼̌

Вот решение в 146 символов:

main=interact$(\x->case(head x)of h|elem h "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂdžǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌"->"lose";h|elem h "ƏƝƞƹǁLjǑǝȍȺɆɈɶɾʎʸ"->"cat";h->"win")

И вот как это работает, как скрипт на haskell:

import Data.List (subsequences, (\\))
import Data.Char (chr)

-- A set of indexes [0-8] describing where on the board pieces of a single color have been played
-- For example the board "OxO;Oxx;xxO" is indexes [0,2,3,8]
type Play = [Int]

-- There are 126 filled tic tac toe boards when X plays first.
--      (This is a combination of 4 OHs among 9 places : binomial(9 4) = 126)
-- perms returns a list of all such possible boards (represented by the index of their OHs).
perms = filter (\x -> 4 == length x) $ subsequences [0..8]

-- We now create an encoding for plays that brings them down to a single char.
-- The index list can be seen as an 9 bit binary word [0,2,3,8] -> '100001101'
-- This, in turn is the integer 269. The possible boards give integers between 15 and 480.
-- Let's call those PlayInts
type PlayInt = Int

permToInt [] = 0
permToInt (x:xs) = (2 ^ x) + permToInt xs 

-- Since the characters in the range 15-480 are not all printable. We offset the chars by 300, this gives the range 
-- ĻŃŇʼnŊœŗřŚşšŢťŦŨųŷŹźſƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂDždžLjǏǑǒǕǖǘǝǞǠǤǯDZDzǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸʽʾˀ˄ˍˎː˔˜˭ˮ˰˴˼̌
-- Of all distinct, printable characters
uOffset = 300

-- Transform a PlayInt to its Char representation
pIntToUnicode i = chr $ i + uOffset

-- Helper function to convert a board in a more user friendly representation to its Char
-- This accepts a representation in the form "xooxxxoxo"
convertBoard s = let play = map snd $ filter (\(c, i) -> c == 'o') $ (zip s [0..]) :: Play 
    in pIntToUnicode $ permToInt play

--
-- Now let's cook some data for our final result
--  

-- All boards as chars
allUnicode = let allInts = map permToInt perms 
    in map pIntToUnicode allInts

-- Now let's determine which boards give which outcome.

-- These are all lines, columns, and diags that give a win when filled
wins = [
        [0,1,2],[3,4,5],[6,7,8], -- lines
        [0,3,6],[1,4,7],[2,5,8], -- columns
        [0,4,8],[2,4,6] -- diagonals
    ]

isWin :: Play -> Bool   
isWin ps = let triplets = filter (\x -> 3 == length x) $ subsequences ps -- extract all triplets in the 4 or 5 moves played
    in any (\t -> t `elem` wins) triplets -- And check if any is a win line

-- These are OH wins
oWins = filter isWin perms
-- EX wins when the complement board wins
xWins = filter (isWin . complement) perms
    where complement ps = [0..9] \\ ps
-- And it's stalemate otherwise
cWins = (perms \\ oWins) \\ xWins

-- Write the cooked data to files
cookData = let toString = map (pIntToUnicode . permToInt) in do
  writeFile "all.txt" allUnicode
  writeFile "cWins.txt" $ toString cWins
  writeFile "oWins.txt" $ toString oWins
  writeFile "xWins.txt" $ toString xWins

-- Now we know that there are 48 OH-wins, 16 stalemates, and 62 EX wins (they have more because they play 5 times instead of 4).
-- Finding the solution is just checking to which set an input board belongs to (ungolfed :)
main = interact $ \x -> case (head x) of -- Only consider the first input char
    h | elem h "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂdžǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌" -> "lose" -- This string is == oWins
    h | elem h "ƏƝƞƹǁLjǑǝȍȺɆɈɶɾʎʸ" -> "cat" -- And this one == cWins
    h -> "win"
ARRG
источник
3

JavaScript, 420 символов

if((s&0x3F000)==0x3F000||(s&0x00FC0)==0x00FC0||(s&0x0003F)==0x0003F||(s&0x030C3)==0x030C3||(s&0x0C30C)==0x0C30C||(s&0x30C30)==0x30C30||(s&0x03330)==0x03330||(s&0x30303)==0x30303)return 'win'
if((s&0x3F000)==0x2A000||(s&0x00FC0)==0x00A80||(s&0x0003F)==0x0002A||(s&0x030C3)==0x02082||(s&0x0C30C)==0x08208||(s&0x30C30)==0x20820||(s&0x03330)==0x02220||(s&0x30303)==0x20202)return 'lose'
if((s&0x2AAAA)==0x2AAAA)return 'cat'

В этой версии sсодержится целое число, которое представляет состояние игрового поля. Это битовый массив значений, где два бита представляют каждый квадрат на доске:

  • 10 - ИКС
  • 11 - О
  • 00 - Пустой квадрат

Это решение использует битовую манипуляцию для проверки каждой из восьми возможных конфигураций «три в ряд» (оно проверяет их каждый дважды, один раз для X и один раз для O).

Я представляю это с небольшим уменьшением на моем сайте Tic-Tac-Toe, где эта detectWinфункция используется как часть настоящей игры Tic-Tac-Toe.

Стивен Остермиллер
источник
6
Ну, это можно назвать грубым принуждением.
seequ
2

Рубин, 84 персонажа

$><<(gets.tr("01","10")[r=/0..(0|.0.)..0|000(...)*$|^..0.0.0/]?:win:~r ?:lose: :cat)

Простое решение на основе RegExp. Формат ввода представляет собой 9-значную двоичную строку, например110101001 для примера платы, приведенной в вопросе.

Рубин, 78 знаков

$><<(gets.tr("ox","xo")[r=/o...(o|.o.)...o|ooo|o_.o._o/]?:win:~r ?:lose: :cat)

Формат ввода: xxo_xox_oox

Ventero
источник
1

Хаскелл, 169

main=interact$(\x->last$"cat":[b|(a,b)<-[("ooo","lose"),("xxx","win")],any(==a)x]).(\x->x++(foldr(zipWith(:))(repeat[])x)++map(zipWith(!!)x)[[0..],[2,1,0]]).take 3.lines

Формат ввода: «X» представлен только как x, «O» только как o. Внутри каждой строки символы являются одновременными без пробелов и т. Д. Строки разделены новыми строками.

Создает все возможные строки / столбцы / диагонали, затем фильтрует [("ooo","lose"),("xxx","win")]их по существованию на доске, затем выбирает второе слово в кортеже, чтобы мы знали, какие игроки выиграли. Мы готовимся к "cat"тому, чтобы взять последний элемент списка в качестве нашего победителя. Если оба игрока выиграют, "win"будет последним (список пониманий поддерживает порядок). Так "cat"как всегда первый, если победитель существует, он будет выбран, но в противном случае последний элемент все еще существует в качестве предшествующего"cat" гарантирует непустоту.

РЕДАКТИРОВАТЬ: побрил 3 символа, изменив понимание последнего списка на map.

YawarRaza7349
источник
1

С, 150 ок

У нас полночь, я не тестировал , но я все равно опубликую концепцию. Я вернусь к этому завтра.

Пользователь вводит два восьмеричных числа (я хотел использовать двоичные числа, но, насколько я знаю, C поддерживает только восьмеричные):

a представляет центральный квадрат, 1 для X, 0 для O

b представляет собой девятизначное число, представляющее квадраты по периметру, окружающие доску, начиная с одного угла и заканчивая в том же углу (с повторением только этого угла), 1 для X, 0 для O.

Есть два возможных способа выиграть:

  1. центральный квадрат X ( a= 1) и два противоположных квадрата также X ( b&b*4096ненулевой)

  2. три соседних квадрата периметра - это X ( b/8 & b & b*8ненулевое значение). Это действительный выигрыш, только если средний квадрат является квадратом ребра, а не угловым квадратом, поэтому необходимо также применять маску m, чтобы избежать случаев угловых квадратов.

Потеря обнаруживается с помощью переменной с, которая является обратной к б.

int a,b,c,m=010101010;
main(){
    scanf("%o%o",a,b);c=b^0111111111;
    printf("%s",(a&&b&b*4096)|(b/8&b&b*8&m)?"win":((!a&&c&c*4096)|(c/8&c&c*8)?"lose":"cat"));
}
Уровень реки St
источник
Вы забыли применить маску mпри обнаружении «проигрыша» c/8&c&c*8. Я изменил ваш код (без проверки его работы) следующим образом: int a,b;t(v){return a&&v&v<<12||v/8&v&v*8&0x208208;}main(){scanf("%o%o",a,b);printf("%s",t(b)?"win":t(b^0x1249249)?"lose":"cat");}(130 символов). Повторный тест был достаточно длинным, чтобы извлечь его из тестовой функции t(); это устраняет необходимость cи m; константы конвертируются в гекс, чтобы сохранить один символ каждый.
Тоби Спейт
Просто заметил, что printfстрока формата не нужна - просто укажите строку результата в качестве формата - или putsэто, так как вопрос не запрашивает перевод строки после вывода! (сохраняет еще 7 символов).
Тоби Спейт
1

Bash, 107 103

Создает и запускает сценарий sed.

Формат ввода / вывода: oxo-oox-xooвыходные данные lose(используйте -для разделения строк). Вход на стандартный ввод. Требуется GNU sed для cкоманды.

Я интерпретировал правило 5 как «если возможны как выигрыш, так и проигрыш, выберите выигрыш».

Основной код

Это фактический ответ.

Ничего интересного на самом деле. Он определяет, $bкак /cwinсохранять символы, затем определяет часть сценария с условием выигрыша, а затем использует sed y/x/o/\;s$b/close/для преобразования xв oи cwinв close(таким образом, генерируя условия проигрыша). Затем он отправляет две вещи и ccat(которые будут выводиться, catесли не найдено ни одного условия выигрыша / проигрыша) в sed.

b=/cwin
v="/xxx$b
/x...x...x$b
/x..-.x.-..x$b
/x-.x.-x$b"
sed "$v
`sed y/x/o/\;s$b/close/<<<"$v"`
ccat"

Сгенерированный код

Это скрипт sed, сгенерированный и запущенный скриптом Bash.

В регулярных выражениях .соответствует любому символу и после них cTEXTпечатает TEXT и завершается, если регулярное выражение сопоставлено.

Это может работать как отдельный скрипт sed. Это 125 символов в длину, вы можете посчитать это другим решением.

/xxx/cwin
/x...x...x/cwin
/x..-.x.-..x/cwin
/x-.x.-x/cwin
/ooo/close
/o...o...o/close
/o..-.o.-..o/close
/o-.o.-o/close
ccat

источник
1

Python 3, 45

Входные данные - iэто список чисел, представляющих каждую строку, столбец и диагональ игрового поля, например:

X X O
O X O
O O X

представлен [6, 2, 1, 4, 6, 1, 7, 4].

Код :('cat','lose','win')[2 if 7 in i else 0 in i]

pseudonym117
источник
1

Дротик - 119

(См. Dartlang.org ).

Оригинальная версия с использованием RegExp: 151 символов.

main(b,{w:"cat",i,p,z}){
 for(p in["olose","xwin"])
   for(i in[0,2,3,4])
     if(b[0].contains(new RegExp('${z=p[0]}(${'.'*i}$z){2}')))
       w=p.substring(1);
  print(w);
}

Ввод в командной строке - 11 символов, например, «xxx | ooo | xxx». В качестве разделителя можно использовать любой символ, отличный от xo.

Ведущие пробелы и символы новой строки должны быть пропущены перед подсчетом символов, но я по возможности сократил внутренние пробелы. Хотелось бы, чтобы был меньший способ сделать подстроку.

Версия с рекурсивной битовой базой: 119 символов. Входные данные должны быть 9-битными числами, где 1 представляют «x», а 0 - «o».

main(n){
  n=int.parse(n[0]);
  z(b,r)=>b>0?b&n==b&511?"win":z(b>>9,n&b==0?"lose":r):r;
  print(z(0x9224893c01c01e2254,"cat"));
}
лрн
источник
1

CJam, 39 38 36 знаков

"ᔔꉚ굌궽渒䗠脯뗠㰍㔚귇籾〳㎪䬔⹴쪳儏⃒ꈯ琉"2G#b129b:c~

Это базовый преобразованный код для

q3/_z__Wf%s4%\s4%]`:Q3'o*#"win"{Q'x3*#"lose""cat"?}?

длиной 52 символа.

Входные данные - это просто строковое представление доски, начиная сверху слева и переходя строка за строкой. Например:

oxooxooox

что приводит к winвыводу. Или

oxooxoxox

что приводит к catвыводу и т. д.

Код просто выполняет следующие три вещи:

  • q3/_ - разбить строку на части по 3, т.е. на строку
  • _z - Скопируйте массив для каждой строки и транспонируйте в массив для каждого столбца.
  • __Wf%s4%- Переверните каждый ряд и получите диагональ слева направо. Это вторичная диагональ доски.
  • \s4% - Получить основную диагональ доски
  • ]` - Обернуть все в массиве и привести в порядок массив.

Теперь у нас есть все возможные группы из 3 с доски. Мы просто проверяем наличие «ooo» и «xxx», чтобы определить результат.

Попробуйте онлайн здесь

Оптимизатор
источник
1

GNU sed, 25 байт

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

Формат ввода: xxx ooo xxx xox xox xox xox xox (состояние платы взято из вопроса ОП)

/xxx/cwin
/ooo/close
ccat

Если входной формат не является избыточным ( xxx ooo xxx), то приведенный выше код sed работает только в том случае, если ему предшествует строка ниже, что делает программу длиной 96 байт (с учетом необходимого rфлага).

s/(.)(.)(.) (.)(.)(.) (.)(.)(.)/& \1\4\7 \2\5\8 \3\6\9 \1\5\9 \3\5\7/
seshoumara
источник
1

Баш: 208 символов

y(){ tr '01' '10'<<<$@;}
f(){ x=$[($1&$2&$3)|($1&$5&$9)|($1&$4&$7)|($2&$5&$8)|($3&$5&$7)|($3&$6&$9)|($4&$5&$6)|($7&$8&$9)]; }
f $@;w=$x
f $(y $@)
([ $x -eq 1 ]&&echo lose)||([ $w -eq 1 ]&&echo win)||echo cat

Выполнить bash tictactoe.sh 0 1 0 1 0 1 1 0 1

Вдохновлен этим ответом .

Майкл Миор
источник
0

VB.net

С помощью примера обеспечить кодируется как следующий битовый шаблон

q  = &B_100101_100110_011010 ' 00 Empty, 01 = O, 10 = X

Теперь мы можем определить результат (или победителя), выполнив следующее.

Dim g = {21, 1344, 86016, 66576, 16644, 4161, 65379, 4368}
Dim w = If(g.Any(Function(p)(q And p)=p),"Lose",If(g.Any(Function(p)(q And p*2)=p*2),"Win","Cat"))
Адам Спейт
источник
0

J - 97 байт

Ну, самый простой доступный подход. Ввод принимается как 111222333, где числа представляют строки. Читайте слева направо. Игрок есть, xа враг есть o. Пустые квадраты могут быть чем угодно, кроме xили o.

f=:(cat`lose>@{~'ooo'&c)`('win'"_)@.('xxx'&c=:+./@(r,(r|:),((r=:-:"1)(0 4 8&{,:2 4 6&{)@,))3 3&$)

Примеры: (NB. Это комментарий)

   f 'xoxxoxxox' NB. Victory from first and last column.
win
   f 'oxxxooxxx' NB. Victory from last row.
win
   f 'ooxxoxxxo' NB. The example case, lost to a diagonal.
lose
   f 'xxooxxxoo' NB. Nobody won.
cat
   f 'xoo xx ox' NB. Victory from diagonal.
win

Ungolfed код объяснения

row   =: -:"1                        Checks if victory can be achieved from any row.
col   =: -:"1 |:                     Checks if victory can be achieved from any column.
diag  =: -:"1 (0 4 8&{ ,: 2 4 6&{)@, Checks if victory can be achieved from diagonals.
check =: +./@(row,col,diag) 3 3&$    Checks all of the above and OR's them.

f     =: (cat`lose >@{~ 'ooo'&check)`('win'"_)@.('xxx'&check)
Check if you have won ........................@.('xxx'&check)
 If yes, return 'win' .............. ('win'"_)
 If not                   (cat`lose >@{~ 'ooo'&check)
  Check if enemy won ................... 'ooo'&check
   If yes, return 'lose'   ---`lose >@{~
   If not, return 'cat'    cat`---- >@{~
seequ
источник
0

Python 2, 120 байт

b=0b101001110
l=[448,56,7,292,146,73,273,84]
print(['Win'for w in l if w&b==w]+['Lose'for w in l if w&~b==w]+['Cat'])[0]

Или Python, 115 байт из оболочки Python (2 или 3):

b=0b101001110;l=[448,56,7,292,146,73,273,84];(['Win'for w in l if w&b==w]+['Lose'for w in l if w&~b==w]+['Cat'])[0]

Переменная board установлена ​​в двоичный формат, описанный в вопросе: 1 для X,0 для O, слева направо, сверху вниз. В этом случае 101001110представляет

XOX
OOX
XXO

Что приводит к выходу: Cat

Сис Тиммерман
источник
Какой формат ввода?
Seequ
0

Python ( 73 62 символа)

Входными данными являются четыре строчные строчные буквы, представляющие четыре различных вида одной и той же платы, все объединенные в одну строку: по строке, по столбцу, по диагонали справа, по диагонали слева.

ОБНОВИТЬ

Спасибо theRare за хороший пример для подражания! Каждый вид доски вместе с каждым сегментом (строкой или столбцом) внутри доски должен быть отделен символом, который не является ни «x», ни «o», чтобы структура доски сохранялась даже после объединения. Границы вокруг каждого вида доски будут в квадратных скобках ("[" и "]"), а разделитель между строками / столбцами будет символом "|".

Это делает алгоритм простым - просто ищите «xxx» или «ooo» для выигрыша или проигрыша, соответственно. В противном случае это галстук (кот).

Например, доска (чтение слева направо, сверху вниз) ...

X | X | X X | O | X O | X | O

... представляется как «[xxx | xox | oxo]» (по строкам) + «[xxo | xox | xxo]» (по столбцам) + «[xoo]» (правый диагон) + [xoo] »(левый diag) = "[xxx | xox | oxo] [xxo | xox | xxo] [xoo] [xoo]".

Этот оператор Python печатает результат игры, учитывая переменную s в качестве входных данных:

print 'win' if 'xxx' in s else 'lose' if 'ooo' in s else 'cat'
Боб
источник
Это работает для доски OXX XOO XOX(это должен быть кот)?
Seequ
Нет ... нет, это не так. Хороший улов! Я думаю, мое решение было слишком простым ... Ой!
Боб
Я не могу сказать, что этот тип решения не приходил мне в голову. :)
seequ
0

Haskell (69 символов)

i x=take 4$(x>>=(\y->case y of{'7'->"win";'0'->"lose";_->""}))++"cat"

Это принимает те же данные, которые описаны в этом ответе . Более конкретно, вводом является 8 восьмеричных значений, описывающих двоичное значение каждой строки, столбца и диагонали. Код заставляет каждый экземпляр 7 «выигрывать», каждый экземпляр 0 «проигрывать» и удаляет все остальное. Затем он добавляет «кошку» в конец и берет первые 4 символа из результата.

Будет 4 возможных ответа: «проиграть», «кошка», «победа», за которыми следует «l», и «победа», за которой следует «с», что не запрещено правилами :)

Пример использования:

i "65153806" --outputs "lose"
TheBrownMotie
источник
0

J: 83

(;:'lose cat win'){::~>:*(-&(+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))-.)3 3$'x'=

Использование: просто добавьте строку с х и о и наблюдайте за магической работой. например. 'Xxxoooxxx.

Внутренний глагол (+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:))) основном, объединяет исходную двоичную матрицу, а транспонирование упаковывается вместе с двумя диагоналями. Эти результаты сравниваются; суммы строк взяты для определения выигрышей, а затем суммируются. далее я назову этот глагол Inner.

Для нахождения победителя, разница в баллах между нормальной и инвертированной двоичными матрицами берется за крючок (-&Inner -.) .

Оставшаяся часть кода просто делает выводы и выбирает правильный.

jpjacobs
источник
0

JavaScript, 133 , 114 символов

r = '/(1){3}|(1.{3}){2}1|(1.{4}){2}1|(1\|.1.\|1)/';alert(i.match(r)?'WIN':i.match(r.replace(/1/g,0))?'LOSS':'CAT')

Ввод iпредставляет собой простую строку с разделителями для строк, т.е.100|001|100

Изменить: обновил мой метод, чтобы заменить 1 в регулярном выражении с нулями, чтобы проверить случай потери.

Тома
источник
Вы можете удалить пробелы вокруг =и кавычки вокруг литерала регулярного выражения. Кроме того, 1...один символ короче 1.{3}.
nyuszika7h
1
r.test(i)также на один символ короче i.match(r).
nyuszika7h
0

J - 56 (26?) Символ

На вход дается матрица 3х3 из девяти символов, потому что J может поддерживать это как тип данных, LOL.

(win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)

Примеры:

   NB. 4 equivalent ways to input the example board
   (3 3 $ 'xxoxoxoox') ; (_3 ]\ 'xxoxoxoox') ; ('xxo','xox',:'oox') ; (];._1 '|xxo|xox|oox')
+---+---+---+---+
|xxo|xxo|xxo|xxo|
|xox|xox|xox|xox|
|oox|oox|oox|oox|
+---+---+---+---+
   (win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.) 3 3 $ 'xxoxoxoox'
lose
   wlc =: (win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)
   wlc (3 3 $ 'xoxoxooxo')
cat
   wlc (3 3 $ 'xxxoooxxx')
win

Если нам разрешено кодировать в восьмеричной системе Golfscriptish избыточно представляющее состояние каждой строки, столбца и диагонали, то это всего лишь 26 символов:

   win`lose`cat{::~7 0<./@i.] 6 5 1 6 4 3 5 0
lose
   f=:win`lose`cat{::~7 0<./@i.]
   f  7 0 7 5 5 5 5 5
win
algorithmshark
источник
0

T-SQL (2012), 110

select max(iif(@&m=0,'lose',iif(@&m=m,'win','cat')))from(VALUES(292),(146),(73),(448),(56),(7),(273),(84))z(m)

Ввод представляет собой шестнадцатеричное число. Это в значительной степени перевод решения ruby ​​на T-SQL, довольно приятный и аккуратный.

Майкл Б
источник
0

Javascript 1.6, 71 символ

Я предполагаю input как массив, gameкоторый содержит каждую строку, каждый столбец и каждый diag в виде строки из 3 символов. Аналогичен ответу Боба , но он представлен в виде массива, а не в виде объединенной строки.

alert(game.indexOf("xxx")>=0?"win":game.indexOf("ooo")>=0?"lose":"cat")

EDIT @ nyuszika7h комментарий (67 символов)

alert(~game.indexOf("xxx")?"win":~game.indexOf("ooo")?"lose":"cat")
ЕНФ
источник
Вы можете использовать ~game.indexOf("xxx")вместо того game.indexOf("xxx")>=0же, для другого.
nyuszika7h
0

Java 7, 260 байт

String c(int[]s){int a[]=new int[8],x=0,y;for(;x<3;x++){for(y=0;y<3;a[x]+=s[x*3+y++]);for(y=0;y<3;a[x+3]+=s[y++%3]);}for(x=0;x<9;y=s[x],a[6]+=x%4<1?y:0;a[7]+=x%2<1&x>0&x++<8?y:0);x=0;for(int i:a)if(i>2)return"win";for(int i:a)if(i<1)return"loose";return"cat";}

Ungolfed и тестовые случаи:

Попробуй это здесь.

class M{
  static String c(int[] s){
    int a[] = new int[8],
        x = 0,
        y;
    for(; x < 3; x++){
      for(y = 0; y < 3; a[x] += s[x * 3 + y++]);
      for (y = 0; y < 3; a[x + 3] += s[y++ % 3]);
    }
    for(x = 0; x < 9; y = s[x],
                      a[6] += x % 4 < 1
                               ? y
                               : 0,
                      a[7] += x % 2 < 1 & x > 0 & x++ < 8
                               ? y
                               : 0);
    x = 0;
    for(int i : a){
      if(i > 2){
        return "win";
      }
    }
    for(int i : a){
      if(i < 1){
        return "loose";
      }
    }
    return "cat";
  }

  public static void main(String[] a){
    /*  xxo
        xox
        oox  */
    System.out.println(c(new int[]{ 1, 1, 0, 1, 0, 1, 0, 0, 1 }));
    /*  xxx
        ooo
        xxx  */
    System.out.println(c(new int[]{ 1, 1, 1, 0, 0, 0, 1, 1, 1 }));
    /*  xxo
        oox
        xox  */
    System.out.println(c(new int[]{ 1, 1, 0, 0, 0, 1, 1, 0, 1 }));
  }
}

Выход:

loose
win
cat
Кевин Круйссен
источник
0

APL (NARS), 69 символов, 138 байтов

{w←3 3⍴⍵⋄x←(+/1 1⍉⊖w),(+/1 1⍉w),(+⌿w),+/w⋄3∊x:'win'⋄0∊x:'lose'⋄'cat'}

Входные данные должны быть одной матрицей 3x3 или одним линейным массивом из 9 элементов, который может быть только 1 (для X) и 0 (для O), результатом будет «cat», если никто не выигрывает, «проигрывать», если O выигрывает, «win» «если Х выиграет. Не существует проверки на одну недопустимую плату или вход, если в одном массиве менее 9 элементов или более, или проверьте каждый элемент <2.

В качестве комментария: он преобразует входные данные в матрицу 3x3 и создает один массив с именем «x», где элементы представляют собой сумму каждого столбца строки и диагонали.

Некоторые тесты показывают пример, показанный другими:

  f←{w←3 3⍴⍵⋄x←(+/1 1⍉⊖w),(+/1 1⍉w),(+⌿w),+/w⋄3∊x:'win'⋄0∊x:'lose'⋄'cat'}
  f 1 2 3
win
  f 0 0 0
lose
  f 1 0 1  1 0 1  1 0 1
win
  f 0 1 1  1 0 0  1 1 1
win
  f 0 0 1  1 0 1  1 1 0
lose
  f 1 1 0  0 1 1  1 0 0
cat
  f 1 1 0  0 1 0  0 0 1
win
  f 1 1 0  1 0 1  0 0 1
lose
РосЛУП
источник