Tentukan kemenangan di Tictactoe


19

Mari kita bermain golf kode!

Diberikan status papan tic-tac-toe (Contoh :)

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

Tentukan apakah game adalah wina loseatau cat. Kode Anda harus menampilkan salah satu dari opsi ini yang diberi status. Permainan di atas harus di-outputlose

Untuk lebih jelasnya: kemenangan didefinisikan sebagai setiap 3 xdetik berturut-turut (diagonal, horizontal, vertikal). kerugian adalah 3 odetik berturut-turut, sedangkan catpermainan tidak ada berturut-turut.

Untuk membuat hal-hal menarik, Anda harus menentukan struktur input Anda untuk keadaan - yang kemudian harus Anda jelaskan. Misalnya xxoxoxooxadalah keadaan yang valid seperti yang terlihat di atas di mana setiap karakter dibaca dari kiri ke kanan, atas ke bawah. [['x','x','o'],['x','o','x'],['o','o','x']]adalah game dalam array multidimensi membaca dengan cara yang sama. Sedangkan 0x1a9hex untuk 110101001mungkin bekerja sebagai kompresi yang cocok di mana 1dapat dimanipulasi untuk xdan 0dapat dimanipulasi untuk o.

Tapi itu hanya beberapa ide, saya yakin Anda mungkin memiliki banyak ide sendiri.

Aturan dasar:

  1. Program Anda harus dapat menerima keadaan apa pun yang layak.
  2. Bentuk input harus dapat mewakili keadaan apa pun.
  3. "Negara yang menang harus ditentukan dari papan"
  4. Asumsikan papan lengkap
  5. Winsebelumnya losemisalnya dalam kasus 'xxxoooxxx'

Hitungan karakter terendah menang


1
Saya suka struktur input ini:, di (win|lose|cat) [xo]{9}mana kata pertama menunjukkan apakah permainan itu menang, kalah, atau kucing (?) Untuk pemain x. Mampu mewakili negara apa pun.
Runer112

2
Dapatkah saya menyarankan aturan seperti "Keadaan menang harus ditentukan dari papan" atau "Masukan tidak boleh mengandung informasi kecuali keadaan dewan"?
undergroundmonorail

3
Apakah kita mengasumsikan hanya permainan legal yang dimainkan? Jika demikian, beberapa negara bagian tidak mungkin, yaitu XXX OOO XXX tetapi sebaliknya beberapa negara bagian papan penuh memasukkan ini sebagai hasil keempat yang mustahil, di mana X menang tetapi O juga menang.
Kerusuhan

10
mengapa "kucing" tidak tertarik?
Chris

7
@DylanMadisetti: tidak pernah mendengarnya sebelumnya dan googlign untuk "win lose cat" tidak menghasilkan apa-apa. Saya akan pergi dengan dasi atau menggambar secara pribadi. Atau dalam hal game ini mungkin "tak terhindarkan". ;-) Saya tidak terlalu keberatan sejauh kompetisi berlangsung. Sebuah string adalah sebuah string. ;-)
Chris

Jawaban:


11

Ruby 2.0, 85 karakter

Berikut ini adalah solusi berbasis bitmask sederhana di Ruby:

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

Papan direpresentasikan sebagai angka hex, terdiri dari sembilan bit yang sesuai dengan sembilan kotak. 1 adalah X, 0 adalahO . Ini seperti 0x1a9contoh dalam pertanyaan, meskipun 0xopsional!

Mungkin ada cara yang lebih baik untuk melakukan bitmask daripada hanya melakukan hardcoding pada daftar besar. Saya akan dengan senang hati menerima saran.

Lihat itu berjalan di Ideone di sini .


1
Daftar Anda mengandung 273dua kali. Dan saya sangat menyukai maxide itu!
Ventero

1
Oh @Ventero, selalu dengan optimasi yang tidak jelas (terima kasih)
Paul Prestidge

Mungkin ada ruang kosong di papan tulis. Format input Anda tidak memperhitungkan ini dan karena itu tidak dapat mewakili kondisi permainan yang layak.
Stephen Ostermiller

2
@StephenOstermiller aturan 4: asumsikan papan lengkap. Anda benar bahwa aturan ini mungkin bertentangan dengan aturan 1 dan 2, namun jika Anda membaca semua komentar pada pertanyaan saya pikir ini sesuai dengan semangat pertanyaan (papan tidak lengkap tidak tercakup, sementara papan lengkap tetapi ilegal). Namun saya berpikir bahwa oktal akan menjadi format input yang lebih ramah pengguna daripada hex.
Level River St

1
Mengerti, saya pikir lengkap berarti sesuatu yang berbeda.
Stephen Ostermiller

10

Mathematica, 84 karakter

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

Masukkan format: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}


Apa yang sedang terjadi disini?
seequ

3
@TheRare Mulai dari kanan. Tr@aadalah jejak bidang (jumlah atas diagonal), Tr@Reverse@aadalah jejak bidang membalik (beberapa lebih anti-diagonal), Tr/@ayang Trditerapkan untuk setiap baris, yang memberi Anda jumlah yang lebih setiap baris, Total@amemberikan Anda jumlah yang lebih setiap kolom. Jadi pada dasarnya, Anda memiliki semua 8 baris yang perlu Anda periksa. Kemudian Whichhal itu diterapkan pada itu (pada dasarnya if/elseif/elsepernyataan), di mana #merupakan daftar 8 nilai. ifada 3kamu menang, else ifada 0kamu kalah, else if 1>0(benar) cat.
Martin Ender

6

Bash: 283 262 258

Menampilkan antarmuka yang relatif ramah.

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

Untuk mengeksekusi bash tictactoe.sh O X O X O X X O X

Catatan: daftar 9 posisi adalah representasi matriks standar. Tidak masalah jika papan direpresentasikan sebagai kolom utama atau baris utama, baca dari kiri ke kanan atau atas ke bawah - permainan noughts dan persilangan (atau tic toe jika Anda bersikeras) simetris, jadi urutan input harus tidak relevan untuk hasil dalam setiap implementasi yang benar, selama input linear.

Sunting: Berkat hjk untuk saran sintaks fungsi yang lebih pendek.


Pertimbangkan t() { ... }bukan function t? Dapat menyimpan beberapa karakter di sana. :)
hjk

Saya benar-benar lupa tentang sintaks fungsi alternatif - terima kasih!
Kerusuhan

Spasi tidak diperlukan <<<untuk menyimpan empat karakter lainnya.
Michael Mior

4

Befunge 93 - 375

Mengambil string biner sebagai input.

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

Membaca string. Bruteforce menulisnya (strip paling vertikal paling kanan) sebagai matriks di antara

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

menambahkan kisi (idk). Menentukan jumlah kolom, baris, dan dua diagnosis. Bandingkan nilai-nilai itu dengan 3 ("menang") atau 0 ("kalah"), jika semua nilai sama dengan 1 atau 2 maka gambarlah ("kucing").


4

GolfScript, 27 karakter

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

Format input adalah string yang terdiri dari delapan digit oktal, masing-masing (secara berlebihan) menyandikan tiga kotak papan berturut-turut:

  • Tiga digit pertama masing-masing menyandikan satu baris papan, dari atas ke bawah dan dari kiri ke kanan.
  • Tiga digit berikut masing-masing menyandikan satu kolom papan, dari kiri ke kanan dan atas ke bawah.
  • Dua digit terakhir masing-masing menyandikan salah satu diagonal (pertama dari kiri atas ke kanan bawah, kemudian dari kiri bawah ke kanan atas).

Untuk menyandikan urutan (baris / kolom / diagonal) dari tiga kotak sebagai digit oktal, ganti setiap xdalam urutan dengan 1 dan setiap odengan 0, dan menafsirkan urutan yang dihasilkan dari satu dan nol sebagai angka biner antara 0 dan 7 inklusif.

Format masukan ini cukup berlebihan (semua posisi papan dikodekan setidaknya dua kali, dengan posisi tengah dikodekan empat kali), tetapi tidak jelas mewakili negara kemungkinan papan tic-tac-toe terisi penuh, dan tidak langsung menyandikan pemenang menjadi input.

Input dapat, secara opsional, mengandung spasi atau pembatas lain di antara digit. Faktanya, semua program benar - benar peduli tentang apakah string input berisi digit 7atau tidak 0.

Misalnya, papan contoh:

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

dapat diwakili oleh input:

651 643 50

Untuk kenyamanan, inilah program GolfScript untuk mengubah tata letak papan seni ASCII, seperti yang ditunjukkan pada tantangan di atas, menjadi string input yang cocok untuk program ini:

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

Konverter ini mengabaikan karakter apa pun selain xdan o, dalam kedua kasus, dalam inputnya. Ini menghasilkan string satu digit (lengkap dengan pembatas ruang seperti yang ditunjukkan di atas) yang cocok untuk dimasukkan ke dalam program penentuan menang di atas, sehingga gabungan dari kedua program ini dapat digunakan untuk menentukan pemenang langsung dari dewan seni ASCII.

Juga, inilah konverter terbalik, hanya untuk menunjukkan bahwa input memang benar-benar mewakili papan:

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

Ps. Inilah demo online dari solusi ini.


2
Format input sepertinya sedikit curang karena banyak pekerjaan yang terjadi dalam menghasilkan input.
Arkku

@ Arkku: Ya, memang, tapi pertanyaannya secara eksplisit mengatakan bahwa "Anda harus menentukan struktur input Anda untuk keadaan - yang kemudian harus Anda jelaskan." Ia bahkan memperlihatkan hex string yang dikemas sedikit sebagai contoh format input yang valid; satu-satunya perbedaan antara itu dan format input saya adalah bahwa saya menyusun ulang dan menduplikasi beberapa bit.
Ilmari Karonen

6
Ini persis duplikasi yang sepertinya curang. (misalnya, itu tidak langsung menyandikan pemenang sebagai kehadiran 7 atau 0 pada input)
Arkku

Tetap itu adalah pengkodean yang pintar, itu berlebihan, tetapi membuat menemukan solusinya jauh lebih efisien daripada pengkodean yang tidak berlebihan!
ARRG

3

Python 2 - 214 byte

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'

Saya yakin ada perbaikan yang harus dilakukan.

Untuk berlari:

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

yang mewakili dewan ini:

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

Keluar dengan NameErrorpengecualian dalam setiap kasus kecuali cat.


Wah, saya tidak pernah tahu <<<! +1 hanya untuk itu.
Greg Hewgill

@GregHewgill Cukup nyaman. ./whatever <<< 'blah blah blah'adalah sama echo -n 'blah blah blah' | ./whatevertetapi tanpa memiliki keseluruhan proses terpisah untuk echo.
undergroundmonorail

@undergroundmonorail echoin bashsebenarnya adalah builtin, jadi jangan garpu proses baru
Bob

@GregHewgill itu disebut herestring

3

Haskell, 146 karakter

Untuk membuat hal-hal menarik, Anda harus menentukan struktur input Anda untuk keadaan - yang kemudian harus Anda jelaskan.

BAIK :). Representasi saya atas papan adalah salah satu dari 126 karakter itu

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

Inilah solusinya dalam 146 karakter:

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

Dan inilah cara kerjanya, sebagai skrip 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 karakter

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'

Dalam versi ini, sberisi bilangan bulat yang mewakili kondisi papan permainan. Ini adalah bit array nilai di mana dua bit mewakili setiap kotak di papan:

  • 10 - X
  • 11 - O
  • 00 - Kotak kosong

Solusi ini menggunakan manipulasi bit untuk menguji masing-masing dari delapan kemungkinan konfigurasi "tiga berturut-turut" (itu menguji mereka masing-masing dua kali, sekali untuk X dan sekali untuk O).

Saya menyajikan ini dengan minifikasi minor dari situs web Tic-Tac-Toe tempat inidetectWin fungsi ini digunakan sebagai bagian dari permainan nyata Tic-Tac-Toe.


6
Nah, ini bisa disebut brute forcing it.
seequ

2

Ruby, 84 karakter

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

Sederhana, solusi berbasis RegExp. Format input adalah string biner 9 digit, misalnya 110101001untuk papan contoh yang diberikan dalam pertanyaan.

Ruby, 78 karakter

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

Masukkan format: 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 input: "X" hanya diwakili oleh x, "O" hanya oleho . Dalam setiap baris, karakter simultan tanpa spasi, dll. Baris dipisahkan oleh baris baru.

Hasilkan semua baris / kolom / diagonal yang mungkin, kemudian filter [("ooo","lose"),("xxx","win")]berdasarkan keberadaannya di papan tulis, lalu pilih kata kedua dalam tuple, jadi kita tahu pemain mana yang menang. Kami menambahkan "cat"sehingga kami dapat mengambil elemen terakhir dari daftar sebagai pemenang kami. Jika kedua pemain menang, "win"akan menjadi yang terakhir (daftar pemahaman menjaga ketertiban). Karena "cat"selalu pertama, jika pemenang ada, itu akan dipilih, tetapi jika tidak, elemen terakhir masih ada sebagai prepending"cat" jaminan nonemptyness.

EDIT: Mencukur 3 karakter dengan mengubah pemahaman daftar terakhir menjadi map .


1

C, 150 kira-kira

Ini tengah malam di sini dan saya belum melakukan pengujian apa pun , tetapi saya tetap akan memposting konsep itu. Saya akan kembali lagi besok.

Pengguna memasukkan dua angka oktal (Saya ingin menggunakan biner tetapi sejauh yang saya tahu C hanya mendukung oktal):

a mewakili kotak tengah, 1 untuk X, 0 untuk O

b adalah angka sembilan digit yang mewakili kuadrat perimeter, melingkari papan mulai dari satu sudut dan berakhir di sudut yang sama (dengan pengulangan sudut itu saja), 1 untuk X, 0 untuk O.

Ada dua cara yang mungkin untuk menang:

  1. kotak tengah adalah X ( a= 1) dan dua kotak yang berlawanan juga X (b&b*4096 bukan nol)

  2. tiga kotak perimeter yang berdekatan adalah X (b/8 & b & b*8 bukan nol). Ini hanya kemenangan yang valid jika kotak tengah adalah kotak tepi, bukan kotak sudut, oleh karena itu perlu untuk menerapkan topeng mjuga, untuk menghindari kasus kotak sudut.

Kehilangan terdeteksi menggunakan variabel c, yang merupakan kebalikan dari 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"));
}

Anda lupa menerapkan topeng mdalam deteksi "kehilangan" - c/8&c&c*8. Saya telah mem-golf-ulang kode Anda (tanpa menguji operasinya) sebagai berikut: 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 karakter). Tes yang diulang cukup lama untuk diekstraksi menjadi fungsi tes t(); ini menghilangkan kebutuhan untuk cdan m; konstanta dikonversi ke hex untuk menyimpan masing-masing satu char.
Toby Speight

Hanya melihat bahwa printftidak perlu string format - cukup berikan string hasil sebagai format - atau puts, karena pertanyaannya tidak meminta baris baru setelah output! (menyimpan 7 karakter selanjutnya).
Toby Speight

1

Pesta, 107 103

Menghasilkan dan menjalankan skrip sed.

Format I / O: oxo-oox-xoooutput lose(gunakan a -untuk memisahkan baris). Masukan pada stdin. Membutuhkan GNU sed untukc perintah.

Saya telah menafsirkan aturan 5 sebagai "jika mungkin menang dan kalah, pilih menang".

Kode Utama

Ini jawaban yang sebenarnya.

Tidak ada yang benar-benar menarik. Itu mendefinisikan $bsebagai /cwinuntuk menyimpan karakter, kemudian mendefinisikan bagian win condition dari skrip, kemudian digunakan sed y/x/o/\;s$b/close/untuk mengkonversi xke odan cwinke close(sehingga menghasilkan kondisi yang hilang). Kemudian mengirimkan dua hal dan ccat(yang akan ditampilkan catjika tidak ada kondisi win / loss cocok) untuk 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"

Kode yang Dihasilkan

Ini adalah skrip sed yang dihasilkan dan dijalankan oleh skrip Bash.

Di regex, .cTEXT regex cocok dengan karakter apa pun dan setelah mereka mencetak TEKS dan keluar jika regex cocok.

Ini dapat dijalankan sebagai skrip sed mandiri. Panjangnya 125 karakter, Anda dapat menghitungnya sebagai solusi lain.

/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

Input masuk i, yang merupakan daftar angka yang mewakili setiap baris, kolom, dan diagonal papan permainan, misalnya:

X X O
O X O
O O X

diwakili oleh [6, 2, 1, 4, 6, 1, 7, 4].

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


1

Dart - 119

(Lihat dartlang.org ).

Versi asli menggunakan RegExp: 151 karakter.

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

Input pada baris perintah adalah 11 karakter, misalnya, "xxx | ooo | xxx". Setiap karakter non-xo dapat digunakan sebagai pembatas.

Ruang putih dan baris baru yang terkemuka harus dihilangkan sebelum menghitung karakter, tapi saya memotong spasi putih di mana mungkin. Saya berharap ada cara yang lebih kecil untuk membuat substring.

Versi bit-base yang resusif: 119 karakter. Input harus berupa angka 9-bit dengan 1s mewakili 'x' dan 0s mewakili '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 karakter

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

Ini adalah kode konversi dasar untuk

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

yang panjangnya 52 karakter.

Input hanyalah representasi string dari papan mulai dari kiri atas, akan baris demi baris. Sebagai contoh:

oxooxooox

yang menghasilkan winoutput. Atau

oxooxoxox

yang menghasilkan a cat output, dll.

Kode hanya melakukan tiga hal berikut:

  • q3/_ - Pisahkan string menjadi bagian-bagian 3, yaitu per baris
  • _z - Salin larik per baris dan transpos ke larik per kolom.
  • __Wf%s4%- Balikkan setiap baris dan dapatkan diagonal kiri ke kanan. Ini adalah diagonal sekunder papan.
  • \s4% - Dapatkan diagonal utama papan
  • ]` - Bungkus semuanya dalam array dan rangkai array.

Sekarang kita memiliki semua kelompok yang memungkinkan 3 dari papan. Kami cukup memeriksa keberadaan "ooo" dan "xxx" untuk menentukan hasilnya.

Cobalah online di sini


1

GNU sed, 25 byte

Jika input adalah representasi berlebihan dari papan dengan tampilan terpisah untuk kolom, baris dan diagonal, seperti yang digunakan dalam jawaban lain juga, maka sed sangat cocok untuk memeriksa keadaan akhir permainan dengan byte paling sedikit.

Format input: xxx ooo xxx xox xox xox xox xox (status board diambil dari pertanyaan OP)

/xxx/cwin
/ooo/close
ccat

Jika format input non-redundan ( xxx ooo xxx), maka kode sed di atas hanya berfungsi jika didahului oleh baris di bawah ini, membuat panjang program 96 byte (dengan rflag yang diperlukan dihitung).

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

1

Bash: 208 karakter

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

Untuk mengeksekusi bash tictactoe.sh 0 1 0 1 0 1 1 0 1

Terinspirasi oleh jawaban ini .


0

VB.net

Dengan contoh, berikan dikodekan sebagai pola bit berikut

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

Sekarang kita dapat menentukan hasil (atau pemenang) dengan melakukan hal berikut.

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 byte

Ya, pendekatan paling sederhana yang tersedia. Input diambil sebagai 111222333, di mana angka mewakili baris. Baca dari kiri ke kanan. Pemain adalah xdan musuh o. Kotak kosong bisa berupa apa saja kecuali xatau o.

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

Contoh: (NB. Adalah komentar)

   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

Kode tanpa penjelasan penjelasan

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 byte

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]

Atau Python, 115 byte dari shell Python (2 atau 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]

Variabel board diatur ke format biner yang dijelaskan dalam pertanyaan: 1untuk X, 0untuk O, kiri-ke-kanan, atas-ke-bawah. Dalam hal ini, 101001110mewakili

XOX
OOX
XXO

Yang mengarah ke keluaran: Cat


Apa format input?
seequ

0

Python ( 73 62 karakter)

Input adalah empat string huruf kecil yang mewakili empat tampilan berbeda dari papan yang sama, semua disatukan menjadi string tunggal: dengan baris, demi kolom, diagonal kanan, diagonal kiri.

MEMPERBARUI

Terima kasih kepada theare untuk menunjukkan ini dengan contoh yang bagus! Setiap tampilan papan, bersama dengan setiap segmen (baris atau kolom) dalam papan harus dipisahkan oleh karakter yang bukan merupakan "x" atau "o" sehingga struktur papan dipertahankan bahkan setelah penggabungan. Batas di sekitar setiap tampilan papan akan berupa tanda kurung siku ("[" dan "]"), dan pemisah antara baris / kolom akan menjadi karakter pipa "|".

Ini membuat algoritma sederhana - cukup cari "xxx" atau "ooo" untuk menang atau kalah, masing-masing. Kalau tidak, itu dasi (kucing).

Misalnya papan tulis (membaca kiri-ke-kanan, atas-ke-bawah) ...

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

... direpresentasikan sebagai "[xxx | xox | oxo]" (dengan baris) + "[xxo | xox | xxo]" (dengan kolom) + "[xoo]" (diag kanan) + [xoo] "(kiri diag) = "[xxx | xox | oxo] [xxo | xox | xxo] [xoo] [xoo]".

Pernyataan Python ini mencetak hasil gim yang diberikan variabel s sebagai input:

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

Apakah ini cocok untuk papan tulis OXX XOO XOX(seharusnya kucing)?
seequ

Tidak ... tidak. Tangkapan yang bagus! Saya kira solusi saya agak terlalu sederhana ... Ups!
bob

Saya tidak bisa mengatakan solusi semacam ini tidak terlintas di benak saya. :)
seequ

0

Haskell (69 karakter)

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

Ini mengambil input yang sama seperti yang dijelaskan oleh jawaban ini . Lebih khusus lagi, input adalah 8 nilai oktal, menggambarkan nilai biner dari setiap baris, kolom, dan diagonal. Kode membuat setiap instance dari 7 "menang", setiap instance dari 0 "kalah", dan menghapus segala sesuatu yang lain. Kemudian ia menambahkan "cat" di akhir dan mengambil 4 karakter pertama dari hasilnya.

Akan ada 4 kemungkinan jawaban: "kalah", "kucing", "menang" diikuti oleh 'l', dan "win" diikuti oleh 'c', yang aturannya tidak melarang :)

Contoh penggunaan:

i "65153806" --outputs "lose"

0

J: 83

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

Penggunaan: cukup tambahkan string x dan o dan saksikan karya sulapnya. misalnya. 'xxxoooxxx'.

Kata kerja dalam (+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))pada dasarnya kotak bersama-sama matriks biner asli, dengan transpos kotak bersama-sama dengan 2 diagonal. Hasil-hasil ini dihancurkan bersama; jumlah baris diambil untuk menentukan kemenangan, dan kemudian dijumlahkan. selanjutnya saya akan memanggil kata kerja ini Inner.

Untuk menemukan pemenang, perbedaan skor antara matriks biner normal dan terbalik diambil oleh hook (-&Inner -.).

Sisa kode hanya membuat output, dan memilih yang benar.


0

JavaScript, 133 , 114 karakter

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

Input iadalah string sederhana dengan pembatas untuk baris, yaitu100|001|100

Sunting: memperbarui metode saya untuk mengganti 1s di regex dengan nol untuk memeriksa kasus kerugian.


Anda dapat menghapus spasi di sekitar =dan tanda kutip di sekitar regex literal. Juga, 1...satu karakter lebih pendek dari 1.{3}.
nyuszika7h

1
r.test(i)juga satu karakter lebih pendek dari i.match(r).
nyuszika7h

0

J - 56 (26?) Char

Input diberikan matriks 3x3 sembilan karakter, karena J dapat mendukungnya sebagai tipe data, LOL.

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

Contoh:

   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

Jika kita diizinkan pengkodean Golfscript dari digit oktal secara berlebihan mewakili keadaan setiap baris, kolom, dan diagonal, maka itu hanya 26 karakter:

   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)

Input adalah nomor hex. Ini cukup banyak terjemahan dari solusi ruby ​​ke T-SQL yang cukup bagus dan rapi.


0

Javascript 1.6, 71 karakter

Saya mengasumsikan input sebagai array gameyang berisi setiap baris, setiap kolom dan setiap diag sebagai string 3 char. Mirip dengan jawaban bob , tetapi datang dalam array, bukan sebagai string yang disatukan.

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

EDIT @ nyuszika7h 's komentar (67 chars)

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

Anda dapat menggunakan ~game.indexOf("xxx")sebagai ganti game.indexOf("xxx")>=0, sama untuk yang lainnya.
nyuszika7h

0

Java 7, 260 byte

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

Kasus yang tidak disatukan & uji:

Coba di sini.

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

Keluaran:

loose
win
cat

0

APL (NARS), 69 karakter, 138 byte

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

Input harus berupa satu matriks 3x3 atau satu array linier dari 9 elemen yang dapat berupa 1 (untuk X) dan 0 (untuk O), hasilnya akan menjadi "kucing" jika tidak ada yang menang, "kalah" jika O menang, "menang "Jika X menang. Tidak ada pemeriksaan untuk satu papan tidak valid atau input adalah satu array memiliki kurang dari 9 elemen atau lebih atau periksa setiap elemen <2.

Sebagai komentar: itu akan mengkonversi input dalam matriks 3x3, dan membangun satu array bernama "x" di mana elemen adalah jumlah setiap kolom baris dan diagonal.

Beberapa contoh tes lihat menunjukkan dari yang lain:

  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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.