Określ wygraną w Tictactoe


19

Zagrajmy w golfa z kodem!

Biorąc pod uwagę stan planszy kółko i krzyżyk (przykład :)

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

Ustal, czy gra jest wina loselub cat. Twój kod powinien wypisać dowolną z tych opcji w danym stanie. Powyższa gra powinna zostać wypisanalose

Żeby było jasne: wygrana jest definiowana jako dowolne 3 xs z rzędu (po przekątnej, w poziomie, w pionie). przegrana to 3 os z rzędu, podczas gdy catgra nie jest z rzędu.

Aby uczynić rzeczy interesującymi, musisz określić strukturę wejściową dla stanu, którą następnie musisz wyjaśnić. Na przykład xxoxoxooxjest to prawidłowy stan, jak pokazano powyżej, w którym każdy ze znaków jest odczytywany od lewej do prawej, od góry do dołu. [['x','x','o'],['x','o','x'],['o','o','x']]to gra w wielowymiarowej tablicy odczytanej w podobny sposób. Chociaż 0x1a9jest to wartość szesnastkowa, 110101001może działać jako odpowiednia kompresja, w której 1można manipulować dla xsi i 0można nim manipulować o.

Ale to tylko niektóre pomysły, jestem pewien, że możesz mieć wiele własnych.

Podstawowe zasady:

  1. Twój program musi być w stanie zaakceptować dowolny możliwy stan.
  2. Forma danych wejściowych musi być w stanie reprezentować dowolny stan.
  3. „Stan wygranej należy ustalić z planszy”
  4. Załóż pełną tablicę
  5. Winwcześniej losena przykład w sprawie „xxxoooxxx”

Wygrywa najniższa liczba postaci


1
Podoba mi się ta struktura wprowadzania: (win|lose|cat) [xo]{9}gdzie pierwsze słowo oznacza, czy gra jest wygrana, przegrana, czy kot (?) Dla gracza x. Potrafi reprezentować dowolny stan.
Runer112

2
Czy mogę zasugerować zasadę typu „Stan wygranej musi zostać ustalony z planszy” lub „Dane wejściowe nie mogą zawierać żadnych informacji poza stanem planszy”?
undergroundmonorail

3
Czy zakładamy, że rozgrywane są tylko legalne gry? Jeśli tak, niektóre stany byłyby niemożliwe, np. XXX OOO XXX, ale w innym przypadku niektóre stany z pełnym wyżywieniem uwzględniają to jako czwarty niemożliwy wynik, w którym X wygrywa, ale O także wygrywa.
Riot

10
dlaczego „kot” nie jest zainteresowany?
Chris

7
@DylanMadisetti: nigdy wcześniej tego nie słyszałem, a googlign dla „wygrać przegrać kota” nic nie wymyślił. Poszedłbym z remisem lub osobiście. Lub w przypadku tej gry może „nieuchronność”. ;-) Nie mam nic przeciwko, jeśli chodzi o konkurencję. Ciąg jest ciągiem. ;-)
Chris

Odpowiedzi:


11

Ruby 2.0, 85 znaków

Oto proste rozwiązanie oparte na masce bitowej w Ruby:

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

Plansza jest reprezentowana przez liczbę szesnastkową, złożoną z dziewięciu bitów odpowiadających dziewięciu kwadratom. 1 to an X, 0 to an O. To jest tak jak w 0x1a9przykładzie w pytaniu, chociaż 0xjest opcjonalne!

Prawdopodobnie jest lepszy sposób na wykonanie maski bitowej niż zakodowanie dużej listy. Z przyjemnością przyjmę sugestie.

Zobacz, jak działa na Ideone tutaj .


1
Twoja lista zawiera 273dwa razy. I naprawdę podoba mi się ten maxpomysł!
Ventero

1
Oh @Ventero, zawsze z niejasnymi optymalizacjami (dzięki)
Paul Prestidge

Na planszy mogą znajdować się puste miejsca. Twój format wejściowy nie uwzględnia tego i dlatego nie może reprezentować żadnego możliwego do utrzymania stanu gry.
Stephen Ostermiller

2
@StephenOstermiller reguła 4: załóż kompletną tablicę. Masz rację, że reguła ta może być sprzeczna z regułami 1 i 2, jednak jeśli przeczytasz wszystkie komentarze do pytania, myślę, że jest to zgodne z duchem pytania (niekompletne tablice nie są objęte, a kompletne, ale nielegalne są). Myślę jednak, że ósemkowy byłby bardziej przyjazny dla użytkownika format wejściowy niż szesnastkowy.
Level River St

1
Rozumiem, pomyślałem, że kompletne oznaczało coś innego.
Stephen Ostermiller

10

Mathematica, 84 znaki

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

Format wejściowy: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}


Co tu się dzieje?
patrz

3
@ TheRare Zacznij od prawej. Tr@ato ślad pola (suma po przekątnej), Tr@Reverse@ato ślad odwróconego pola (niektóre ponad przekątną), Tr/@ajest Trstosowany do każdego wiersza, co daje sumę nad każdym wierszem, Total@adaje sumę nad każdą kolumną. Zasadniczo masz wszystkie 8 linii, które musisz sprawdzić. Następnie Whichrzecz jest stosowana do tego (w zasadzie if/elseif/elseinstrukcji), gdzie #reprezentuje listę 8 wartości. ifistnieje 3wygrasz, else ifistnieje 0tracisz, else if 1>0(true) cat.
Martin Ender

6

Bash: 283 262 258

Posiada stosunkowo przyjazny interfejs.

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

Wykonać bash tictactoe.sh O X O X O X X O X

Uwaga: lista 9 pozycji jest standardową reprezentacją macierzy. Nie ma znaczenia, czy plansza jest reprezentowana jako główna kolumna czy główna kolumna, czytana od lewej do prawej lub od góry do dołu - gry kółek i krzyżyków (lub kółko i krzyżyk, jeśli nalegasz) są symetryczne, więc kolejność wprowadzania nie powinna mieć znaczenia do wyniku w każdej poprawnej implementacji, o ile dane wejściowe są liniowe.

Edycja: Dzięki hjk za krótsze sugestie dotyczące składni funkcji.


Zastanów się t() { ... }zamiast function t? Można tam zapisać niektóre postacie. :)
hjk

Zupełnie zapomniałem o składni funkcji alternatywnych - dzięki!
Riot

W pobliżu nie są wymagane odstępy, <<<aby zapisać kolejne cztery znaki.
Michael Mior

4

Befunge 93-375

Pobiera ciąg binarny jako dane wejściowe.

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       <^  <

Czyta ciąg. Bruteforce zapisuje go (najbardziej prawy pionowy pasek) jako macierz pomiędzy

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

dodawanie kraty (idk). Określa sumę kolumn, wierszy i dwóch diagnoz. Porównuje te wartości do 3 („wygrana”) lub 0 („przegrana”), w przeciwnym razie, jeśli wszystkie wartości będą równe 1 lub 2, to losuje („kot”).


4

GolfScript, 27 znaków

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

Format wejściowy to ciąg składający się z ośmiu cyfr ósemkowych, z których każda (nadmiarowo) koduje trzy kolejne kwadraty na planszy:

  • Pierwsze trzy cyfry kodują pojedynczy rząd planszy, od góry do dołu i od lewej do prawej.
  • Następne trzy cyfry kodują pojedynczą kolumnę planszy, od lewej do prawej i z góry na dół.
  • Dwie ostatnie cyfry kodują jedną z przekątnych (najpierw od lewego górnego rogu do prawego dolnego rogu, a następnie od lewego dolnego rogu do prawego górnego rogu).

Aby zakodować sekwencję (wiersz / kolumna / przekątna) trzech kwadratów jako cyfrę ósemkową, zamień każdy xw sekwencji na 1, a każdy ona 0, i zinterpretuj wynikową sekwencję zer i jedynek jako liczbę binarną od 0 do 7 włącznie.

Ten format wejściowy jest całkowicie zbędny (wszystkie pozycje deska kodowane są co najmniej dwa razy, z pozycji centralnej kodowane cztery razy), ale nie w sposób jednoznaczny oznaczają ewentualnego stanu całkowitego wypełnienia płyty Tic-krzyżyk, a nie bezpośrednio zakodowania zwycięzca w danych wejściowych.

Dane wejściowe mogą opcjonalnie zawierać spacje lub inne ograniczniki między cyframi. W rzeczywistości wszystkim, na czym naprawdę zależy programowi, jest to, czy ciąg wejściowy zawiera cyfry, 7czy nie 0.

Na przykład tablica przykładowa:

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

mogą być reprezentowane przez dane wejściowe:

651 643 50

Dla wygody, oto program GolfScript do konwersji układu płytki graficznej ASCII, jak pokazano w powyższym wyzwaniu, na ciąg wejściowy odpowiedni dla tego programu:

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

Konwerter ignoruje wszelkie znaki inne niż xi o, w obu przypadkach, w danych wejściowych. Tworzy jednocyfrowe ciągi znaków (wraz z ogranicznikami spacji, jak pokazano powyżej), odpowiednie do wprowadzenia do powyższego programu określającego wygraną, więc konkatenację tych dwóch programów można wykorzystać do ustalenia zwycięzcy bezpośrednio z tablicy artystycznej ASCII.

Ponadto, oto odwrócony konwerter, aby pokazać, że wejście rzeczywiście jednoznacznie reprezentuje płytkę:

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

Ps. Oto demo online tego rozwiązania.


2
Format wejściowy wydaje się trochę oszustwem, ponieważ większość pracy przy tworzeniu danych wejściowych.
Arkku

@Arkku: Tak, tak, ale pytanie wyraźnie mówi, że „musisz określić swoją strukturę wejściową dla stanu - co musisz następnie wyjaśnić”. Pokazuje nawet spakowany bit ciąg znaków jako przykład prawidłowego formatu wejściowego; jedyną różnicą między tym a moim formatem wejściowym jest to, że zmieniam kolejność i duplikuję niektóre bity.
Ilmari Karonen

6
To właśnie duplikacja wydaje się oszustwem. (na przykład, to jest bezpośrednio koduje zwycięzcę jak obecność 7 lub 0 na wejściu)
Arkku

Nadal jest to sprytne kodowanie, jest redundantne, ale sprawia, że ​​znalezienie rozwiązania jest znacznie bardziej wydajne niż jakikolwiek kodowanie nie redundantne!
ARRG

3

Python 2 - 214 bajtów

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'

Jestem pewien, że należy wprowadzić ulepszenia.

Biegać:

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

który reprezentuje ten zarząd:

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

Wyjścia z NameErrorwyjątkiem w każdym przypadku z wyjątkiem cat.


O, nigdy nie wiedziałem <<<! +1 za to.
Greg Hewgill

@GregHewgill To całkiem wygodne. ./whatever <<< 'blah blah blah'jest taki sam, echo -n 'blah blah blah' | ./whateverale bez osobnego procesu dla echo.
undergroundmonorail

@undergroundmonorail echow bashjest właściwie wbudowany, więc nie rozwidla nowego procesu
Bob

@GregHewgill nazywa się to tustring

3

Haskell, 146 znaków

Aby uczynić rzeczy interesującymi, musisz określić strukturę wejściową dla stanu, którą następnie musisz wyjaśnić.

DOBRZE :). Moja reprezentacja planszy to jedna z tych 126 postaci

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

Oto rozwiązanie dla 146 znaków:

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

A oto jak to działa, jako skrypt 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"

3

JavaScript, 420 znaków

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'

W tej wersji szawiera liczbę całkowitą, która reprezentuje stan planszy. Jest to tablica bitów wartości, w której dwa bity reprezentują każdy kwadrat na planszy:

  • 10 - X
  • 11 - O
  • 00 - Pusty kwadrat

To rozwiązanie wykorzystuje manipulację bitową do testowania każdej z ośmiu możliwych konfiguracji „trzy z rzędu” (testuje je dwa razy, raz dla X i raz dla O).

Przedstawiam to z drobnymi drobiazgami na mojej stronie Kółko i krzyżyk, gdzie ta detectWinfunkcja jest używana jako część prawdziwej gry Kółko i krzyżyk .


6
Cóż, można to nazwać brutalnym zmuszaniem.
patrz

2

Ruby, 84 znaków

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

Proste rozwiązanie oparte na RegExp. Format wejściowy to 9-cyfrowy ciąg binarny, np110101001 Dla przykładowej płytki podanej w pytaniu.

Ruby, 78 znaków

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

Format wejściowy: xxo_xox_oox


1

Haskell, 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

Format wejściowy: „X” jest reprezentowany tylko przez x, „O” tylko przez o. W każdym rzędzie znaki są równoczesne bez spacji itp. Wiersze są oddzielone nowymi wierszami.

Generuje wszystkie możliwe wiersze / kolumny / przekątne, następnie filtruje [("ooo","lose"),("xxx","win")]według ich istnienia na planszy, a następnie wybiera drugie słowo w krotce, abyśmy wiedzieli, którzy gracze zwyciężyli. Przygotowujemy się "cat", abyśmy mogli wziąć ostatni element listy jako naszego zwycięzcę. Jeśli obaj gracze wygrają, "win"będzie ostatni (listy ze zrozumieniem utrzymują porządek). Ponieważ "cat"zawsze jest pierwszy, jeśli zwycięzca istnieje, zostanie on wybrany, ale w przeciwnym razie ostatni element nadal istnieje, ponieważ wyprzedzanie "cat"gwarantuje brak pustki .

EDYCJA: Ogolono 3 znaki, zmieniając sposób interpretowania ostatniej listy na map.


1

C, około 150

Jest północ i nie przeprowadziłem żadnych testów , ale i tak opublikuję tę koncepcję. Wrócę do tego jutro.

Użytkownik wprowadza dwie liczby ósemkowe (chciałem użyć wartości binarnych, ale o ile wiem C obsługuje tylko liczby ósemkowe):

a oznacza kwadrat środkowy, 1 dla X, 0 dla O

b to dziewięciocyfrowa liczba reprezentująca kwadraty obwodowe, okrążająca planszę, rozpoczynająca się w jednym rogu i kończąca się w tym samym rogu (tylko z powtórzeniem tego rogu), 1 dla X, 0 dla O.

Istnieją dwa sposoby na wygraną:

  1. środkowy kwadrat to X ( a= 1), a dwa przeciwległe kwadraty to także X ( b&b*4096jest niezerowy)

  2. trzy sąsiadujące kwadraty obwodowe to X ( b/8 & b & b*8jest niezerowa). Jest to ważna wygrana tylko wtedy, gdy środkowy kwadrat jest kwadratem krawędzi, a nie kwadratem narożnym, dlatego konieczne jest również zastosowanie maski m, aby uniknąć kwadratowych narożników.

Przegrywanie jest wykrywane za pomocą zmiennej c, która jest odwrotnością b.

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"));
}

Zapomniałeś zastosować maskę mw wykrywaniu „zagubienia” - c/8&c&c*8. Zmodyfikowałem Twój kod (bez testowania jego działania) w następujący sposób: 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 znaków). Powtarzany test był wystarczająco długi, aby wyodrębnić go do funkcji testowej t(); eliminuje to potrzebę ci m; stałe zamienione na hex, aby zapisać jeden znak każdy.
Toby Speight,

Zauważyłem, że printfnie potrzebuje ciągu formatującego - wystarczy podać ciąg wynikowy jako format - lub putstaki, ponieważ pytanie nie wymaga nowego wiersza po wyjściu! (zapisuje kolejne 7 znaków).
Toby Speight,

1

Grzmotnąć, 107 103

Generuje i uruchamia skrypt sed.

Format I / O: oxo-oox-xoowyjścia lose(użyj a -do oddzielenia wierszy). Wejście na standardowe wejście. Wymaga GNU sed dlac polecenia.

Zinterpretowałem zasadę 5 jako „jeśli możliwe jest zarówno zwycięstwo, jak i przegrana, wybierz zwycięstwo”.

Kod główny

To jest właściwa odpowiedź.

Naprawdę nic ciekawego. Definiuje, $bjak /cwinzapisywać postacie, następnie definiuje część skryptu dotyczącą warunku wygranej, a następnie używa sed y/x/o/\;s$b/close/do konwersji xdo oi cwindo close(tym samym generując warunki przegranej). Następnie wysyła dwie rzeczy i ccat(które zostaną wyświetlone, catjeśli nie zostanie spełniony warunek wygranej / przegranej) do 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"

Wygenerowany kod

To jest skrypt sed generowany i uruchamiany przez skrypt Bash.

W wyrażeniach regularnych .dopasowuje dowolną postać i po niejcTEXT wyrażeniach regularnych drukuje TEKST i kończy działanie, jeśli wyrażenie jest dopasowane.

Może to działać jako samodzielny skrypt sed. Ma on 125 znaków, można go liczyć jako kolejne rozwiązanie.

/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

Wprowadzono dane wejściowe i, czyli listę liczb reprezentujących każdy rząd, kolumnę i przekątną planszy, np .:

X X O
O X O
O O X

jest reprezentowany przez [6, 2, 1, 4, 6, 1, 7, 4].

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


1

Dart - 119

(Zobacz dartlang.org ).

Oryginalna wersja wykorzystująca RegExp: 151 znaków.

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);
}

W wierszu polecenia wpisuje się 11 znaków, np. „Xxx | ooo | xxx”. Jako separator można użyć dowolnego znaku innego niż xo.

Wiodące białe znaki i znaki nowej linii należy pominąć przed zliczaniem znaków, ale w miarę możliwości odcinam wewnętrzne białe znaki. Chciałbym, aby istniał mniejszy sposób na utworzenie podciągu.

Recusive wersja bit-base: 119 znaków. Dane wejściowe muszą być liczbą 9-bitową, przy czym 1s oznaczają „x”, a 0s oznaczają „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 znaków

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

To jest podstawowy konwertowany kod dla

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

który ma 52 znaki.

Dane wejściowe to po prostu ciąg znaków reprezentujący tablicę, zaczynając od lewego górnego rogu, przechodząc rząd po rzędzie. Na przykład:

oxooxooox

co daje winwynik. Lub

oxooxoxox

co daje catwynik itp.

Kod po prostu wykonuje następujące trzy czynności:

  • q3/_ - Podziel ciąg na części po 3, tj. Na rząd
  • _z - Skopiuj tablicę na wiersz i transponuj na tablicę na kolumnę.
  • __Wf%s4%- Odwróć każdy rząd i uzyskaj przekątną od lewej do prawej. Jest to wtórna przekątna planszy.
  • \s4% - Zdobądź główną przekątną planszy
  • ]` - Zawiń wszystko w tablicę i uszereguj tablicę.

Teraz mamy wszystkie możliwe grupy 3 z planszy. Sprawdzamy po prostu obecność „ooo” i „xxx”, aby ustalić wynik.

Wypróbuj online tutaj


1

GNU sed, 25 bajtów

Jeśli dane wejściowe to nadmiarowa reprezentacja planszy z osobnymi widokami dla kolumn, wierszy i przekątnych, jak również w innych odpowiedziach, wtedy sed bardzo dobrze nadaje się do sprawdzania stanu końcowego gry z najmniej bajtami.

Format wejściowy: xxx ooo xxx xox xox xox xox xox (stan płytki pochodzi z pytania PO)

/xxx/cwin
/ooo/close
ccat

Jeśli format wejściowy nie jest redundantny ( xxx ooo xxx), to powyższy kod sed działa tylko wtedy, gdy poprzedzony jest wierszem poniżej, co powoduje, że program ma 96 bajtów długości (z wymaganą rflagą).

s/(.)(.)(.) (.)(.)(.) (.)(.)(.)/& \1\4\7 \2\5\8 \3\6\9 \1\5\9 \3\5\7/

1

Bash: 208 znaków

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

Wykonać bash tictactoe.sh 0 1 0 1 0 1 1 0 1

Zainspirowany tą odpowiedzią .


0

VB.net

W tym przykładzie dostarczony jest kodowany jako następujący wzór bitowy

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

Teraz możemy ustalić wynik (lub zwycięzcę), wykonując następujące czynności.

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 bajtów

Najprostsze dostępne podejście. Dane wejściowe przyjmuje się jako 111222333, gdzie liczby reprezentują wiersze. Czytaj od lewej do prawej. Gracz jest, xa wróg jest o. Pustymi kwadratami może być cokolwiek oprócz xlub o.

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

Przykłady: (NB. To komentarz)

   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

Niegolfowany kod wyjaśnienia

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`---- >@{~

0

Python 2, 120 bajtów

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]

Lub Python, 115 bajtów z powłoki Python (2 lub 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]

Zmienna planszowa jest ustawiona na format binarny opisany w pytaniu: 1dla X, 0dla O, od lewej do prawej, od góry do dołu. W tym przypadku 101001110reprezentuje

XOX
OOX
XXO

Co prowadzi do wyjścia: Cat


Jaki jest format wejściowy?
patrz

0

Python ( 73 62 znaków)

Dane wejściowe to cztery małe litery reprezentujące cztery różne widoki tej samej tablicy, wszystkie połączone w jeden ciąg: wiersz, kolumna, prawa-przekątna, lewa-przekątna.

AKTUALIZACJA

Dzięki theRare za zwrócenie na to uwagi dobrym przykładem! Każdy widok planszy wraz z każdym segmentem (rzędem lub kolumną) w obrębie tablicy musi być oddzielony znakiem, który nie jest ani „x”, ani „o”, aby struktura tablicy została zachowana nawet po konkatenacji. Obramowania wokół każdego widoku tablicy będą nawiasami kwadratowymi („[” i „]”), a separatorem między wierszami / kolumnami będzie znak „”.

To sprawia, że ​​algorytm jest prosty - po prostu wyszukaj „xxx” lub „ooo” odpowiednio dla wygranej lub przegranej. W przeciwnym razie jest to remis (cat).

Np. Tablica (czytanie od lewej do prawej, od góry do dołu) ...

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

... jest reprezentowany jako „[xxx | xox | oxo]” (przez rzędy) + „[xxo | xox | xxo]” (przez kolumny) + „[xoo]” (prawy diag) + [xoo] ”(po lewej diag) = "[xxx | xox | oxo] [xxo | xox | xxo] [xoo] [xoo]".

Ta instrukcja Python wypisuje wynik gry, biorąc pod uwagę zmienną s jako dane wejściowe:

print 'win' if 'xxx' in s else 'lose' if 'ooo' in s else 'cat'

Czy to działa na pokładzie OXX XOO XOX(powinien to być kot)?
patrz

Nie ... nie nie. Dobry chwyt! Wydaje mi się, że moje rozwiązanie było trochę zbyt proste ... Ups!
Bob

Nie mogę powiedzieć, że tego rodzaju rozwiązanie nie przyszło mi do głowy. :)
patrz

0

Haskell (69 znaków)

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

To wymaga takiego samego wkładu, jak opisano w tej odpowiedzi . Mówiąc dokładniej, wejściem jest 8 wartości ósemkowych, opisujących wartość binarną każdego wiersza, kolumny i przekątnej. Kod powoduje, że każde wystąpienie 7 „wygrywa”, każde wystąpienie 0 „przegrywa” i usuwa wszystko inne. Następnie dodaje „cat” na końcu i pobiera pierwsze 4 znaki z wyniku.

Będą 4 możliwe odpowiedzi: „przegrać”, „kot”, „wygrać”, a następnie „l”, i „wygrać”, a następnie „c”, których reguły nie zabraniają :)

Przykładowe użycie:

i "65153806" --outputs "lose"

0

J: 83

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

Zastosowanie: wystarczy dołączyć ciąg znaków X i O i obserwować magiczną pracę. na przykład. „xxxoooxxx”.

Wewnętrzny czasownik (+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))zasadniczo zawiera razem oryginalną macierz binarną, a transpozycja jest zapakowana razem z 2 przekątnymi. Te wyniki są zrównane z sobą; sumy wierszy są pobierane w celu ustalenia wygranych, a następnie sumowane. dalej nazywam to czasownikiem Inner.

Aby znaleźć zwycięzcę, różnica wyników między normalną a odwróconą macierzą binarną jest brana pod uwagę (-&Inner -.).

Reszta kodu po prostu tworzy dane wyjściowe i wybiera właściwy.


0

JavaScript, 133 , 114 znaków

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')

Dane wejściowe ito prosty ciąg z ogranicznikami wierszy, tj100|001|100

Edycja: zaktualizowałem moją metodę, aby zastąpić jedynką w wyrażeniu regularnym zerami, aby sprawdzić przypadek straty.


Możesz usunąć spacje wokół =i cudzysłowy wokół wyrażenia regularnego. Ponadto, 1...jeden znak jest krótszy niż 1.{3}.
nyuszika7h

1
r.test(i)jest także o jedną postać krótszy niż i.match(r).
nyuszika7h

0

J - 56 (26?) Char

Dane wejściowe otrzymują macierz 3x3 dziewięciu znaków, ponieważ J może to obsługiwać jako typ danych, LOL.

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

Przykłady:

   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

Jeśli wolno nam kodować Golfscriptish cyfr ósemkowych nadmiarowo reprezentujących stan każdego wiersza, kolumny i przekątnej, to jest to tylko 26 znaków:

   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

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)

Dane wejściowe to liczba szesnastkowa. To jest prawie tłumaczenie tłumaczenia ruby ​​na T-SQL całkiem ładnie i schludnie.


0

JavaScript 1.6, 71 znaków

Zakładam, że dane wejściowe są tablicą, gamektóra zawiera każdy wiersz, każdą kolumnę i każdy diag jako ciąg 3 znaków. Podobna do odpowiedzi boba , ale występuje w tablicy, a nie w postaci połączonego łańcucha.

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

Edycja komentarza @ nyuszika7h (67 znaków)

alert(~game.indexOf("xxx")?"win":~game.indexOf("ooo")?"lose":"cat")

Możesz użyć ~game.indexOf("xxx")zamiast game.indexOf("xxx")>=0, to samo dla drugiego.
nyuszika7h

0

Java 7, 260 bajtów

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";}

Przypadki bez golfa i testy:

Wypróbuj tutaj.

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 }));
  }
}

Wynik:

loose
win
cat

0

APL (NARS), 69 znaków, 138 bajtów

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

Dane wejściowe powinny być jedną matrycą 3x3 lub jedną liniową tablicą 9 elementów, która może być tylko 1 (dla X) i 0 (dla O), wynikiem będzie „kot”, jeśli nikt nie wygra, „przegrana”, jeśli O wygra, ”wygrana „jeśli X wygra. Nie ma możliwości sprawdzenia jednej nieprawidłowej płytki lub danych wejściowych, czy jedna tablica ma mniej niż 9 elementów lub więcej, lub sprawdź każdy element <2.

Jako komentarz: przekształci dane wejściowe w macierz 3x3 i zbuduje jedną tablicę o nazwie „x”, w której elementy są sumą każdej kolumny wiersza i przekątnej.

Niektóre testy patrz przykład pokazany przez innych:

  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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.