Tic-Tac-Toe - X atau O?

14

Latar Belakang

Lewati ke "Tugas" jika Anda terbiasa dengan Tic-Tac-Toe (saya pikir sebagian besar adalah!)

Tic-Tac-Toe adalah gim dua pemain yang terkenal. Ini terdiri dari papan 3x3 yang diisi secara bertahap oleh dua pemain (klarifikasi di bawah); Pemain pertama menggunakan karakter Xdan yang lainnya menggunakan O. Pemenangnya adalah yang pertama mendapatkan 3 karakter berurutan dan identik ( Xatau O), baik secara horizontal, vertikal atau diagonal. Jika papan diisi dan tidak ada pemain yang berhasil mendapatkan tiga karakter berturut-turut seperti yang dijelaskan di atas, permainan berakhir dengan seri. Perhatikan bahwa mungkin ada tempat kosong di akhir pertandingan, jika salah satu pemain menang dalam total kurang dari 9 gerakan (ini tidak dapat terjadi jika terjadi seri).

Tugas

Diberikan papan Tic-Tac-Toe di akhir permainan (dalam bentuk string, matriks, daftar datar 9 nilai yang dipesan, format apa pun yang layak), tentukan siapa yang memenangkan permainan.

  • Input akan terdiri dari nilai yang berbeda dan konsisten , satu untuk X, satu untuk Odan yang lain yang mewakili tempat kosong.

  • Program Anda harus dapat menghasilkan 3 nilai yang berbeda, konsisten dan tidak kosong: satu dalam kasus Xmenang, satu lagi jika Omenang atau lainnya jika para pemain terikat.

    Silakan tentukan nilai-nilai ini dalam jawaban Anda. Anda dapat mengasumsikan bahwa input tersebut akan menjadi papan Tic-Tac-Toe yang valid.

Uji Kasus

X, O, _Adalah nilai-nilai masukan di sini; X wins, O winsdan Tieuntuk output.

X O X
O X _
O _ X

Output: X wins.

X _ O
X O _
X O X

Output: X wins.

X O X
_ O X
_ O _

Output: O wins.

X O X
O O X
X X O

Output: Tie.


Seperti biasa, semua aturan standar kami berlaku. Ini adalah , kode terpendek dalam byte yang menang di setiap bahasa!

Tuan Xcoder
sumber
2
Keluar dari otakku! Secara harfiah hanya punya ide untuk tantangan Noughts & Crosses bahwa saya akan Sanbox pada hari Senin. Kemudian saya membuka situs dan melihat ini!
Shaggy
1
@Shaggy Mengutip seseorang dari seri "Fast and Furious": Terlalu lambat! ; p
Mr. Xcoder
Tidak apa-apa, ide saya adalah untuk versi yang dapat dimainkan, dengan asumsi bahwa belum dilakukan.
Shaggy
4
@Laikoni Saya tidak berpikir itu adalah penipuan, karena ini memiliki cara input dan output yang lebih fleksibel dan juga memiliki kotak kosong juga, dan ini juga memungkinkan Anda menganggap input adalah papan yang valid.
Erik the Outgolfer
1
@ Joshua Itu tentang membuat permainan Tic-tac-toe. Ini tentang penilaian satu.
DonielF

Jawaban:

6

Jelly ,  16 15  14 byte

U,Z;ŒD$€ẎḄỊÐḟḢ

Tautan monadik yang menerima daftar daftar (baris - atau kolom) dengan nilai:

X = 0.155; O = -0.155; _ = 0

Hasil kembali:

X wins = 1.085; O wins = -1.085; Tie = 0

Catatan: menggunakan nilai nol untuk _, dan nilai yang sama tetapi berlawanan untuk Xdan O, nilai ini (di sini 0.155) mungkin dalam kisaran (1/6, 1/7)(eksklusif di kedua ujungnya) - Saya hanya memilih nilai dalam rentang yang memberikan hasil titik mengambang yang dapat diwakili secara tepat untuk kasus menang.

Cobalah online!

Bagaimana?

U,Z;ŒD$€ẎḄỊÐḟḢ - Link: list of lists (as described above)
U              - upend (reverse each row)
  Z            - transpose (get the columns)
 ,             - pair the two
      $€       - last two links as a monad for each of them:
    ŒD         -   diagonals (leading diagonals - notes: 1. only one is of length 3;
               -              2. the upend means we get the anti-diagonals too)
        Ẏ      - tighten (make a single list of all the rows, columns and diagonals)
         Ḅ     - from binary (vectorises) (note that [0.155, 0.155, 0.155]
               -                           converts to 4*0.155+2*0.155+1*0.155 = 1.085
               -                           and [-0.155, -0.155, -0.155]
               -                           converts to 4*-0.155+2*-0.155+1*-0.155 = -1.085
               -                           while shorter lists or those of length three
               -                           with any other mixtures of 0.155, -0.155 and 0
               -                           yield results between -1 and 1
               -                           e.g. [.155,.155,0] -> 0.93)
           Ðḟ  - filter discard if:
          Ị    -   insignificant (if abs(z) <= 1) (discards all non-winning results)
             Ḣ - head (yields the first value from the list or zero if it's empty)
Jonathan Allan
sumber
Ya, saya pikir jawaban bahasa esoterik apa pun harus memiliki penjelasan (dan saya juga ingin melihat penjelasan untuk bahasa normal!)
Jonathan Allan
Terima kasih telah menambahkannya! Pendekatan yang sangat bagus, jauh lebih pandai daripada yang saya pikirkan ... Bagus
Tn. Xcoder
6

Javascript (ES6), 103 87 byte

a=>"012+345+678+036+147+258+048+246T".replace(/\d/g,n=>a[n]||!1).match(/(\d)\1\1|T/)[0]

Memasukkan

  • X direpresentasikan sebagai 1
  • O direpresentasikan sebagai 2
  • _ direpresentasikan sebagai 0

Keluaran

  • X menang diwakili sebagai "111"
  • O kemenangan diwakili sebagai "000"
  • Dasi diwakili sebagai "T"

Penjelasan

a=>
    "012+345+678+036+147+258+048+246" // List of indexes for each row
    .replace(/\d/g,n=>a[n]||!1)       // Replace all digits with the value of the cell
    .match(/(\d)\1\1|$/)[0]           // Find the first row filled with the same value

Uji kasus

f=
a=>"012+345+678+036+147+258+048+246T".replace(/\d/g,n=>a[n]||!1).match(/(\d)\1\1|T/)[0]
console.log(f([1,2,1,2,1,0,2,0,1]))
console.log(f([1,0,2,1,2,0,1,2,1]))
console.log(f([1,2,1,0,2,1,0,2,0]))
console.log(f([1,2,1,2,2,1,1,1,2]))

Herman L.
sumber
"Program Anda harus dapat menghasilkan 3 nilai yang berbeda, konsisten dan tidak kosong ", sehingga Anda tidak dapat menampilkan string kosong untuk dasi.
RedClover
1
@ Soaku Saya buruk, saya melewatkan bagian dari aturan.
Herman L
4

Jelly , 18 byte

UŒD;;Z;ŒDµSA⁼3µÐfḢ

Cobalah online!

X= 1, O= -1, _= 0
X menang = [1, 1, 1], O menang = [-1, -1, -1], Tie = 0
Input sebagai daftar 3 daftar dari 3 elemen di (1, -1, 0)masing-masing.

Erik the Outgolfer
sumber
Wow Bagus ... Ketika Anda selesai bermain golf, harap tambahkan nilai I / O dan penjelasannya :-)
Tn. Xcoder
Berikut ini pendekatan yang sama dengan tes yang sedikit lebih pendek. Mengambil X= 1, O= 2, _= 3, mengembalikan 1(X menang), 2(O menang) atau 3(mengikat).
Arnauld
@Arnauld terima kasih atas pemendekannya
Erik the Outgolfer
3

Python 3 , 73 byte

lambda b:{'XXX','OOO'}&{*b.split(),b[::4],b[1::4],b[2::4],b[::5],b[2::3]}

Cobalah online!


Python 2 , 100 95 92 87 82 77 byte

lambda b:{'XXX','OOO'}&set(b.split()+[b[::4],b[1::4],b[2::4],b[::5],b[2::3]])

Cobalah online!


Mengambil input sebagai string yang dipisahkan oleh baris baru XO_

Output:

  • {'XXX'} untuk X,
  • {'OOO'} untuk O
  • {} untuk dasi

Bekerja dengan mengiris string menjadi kolom baris dan diagonal:

The board:
    1 2 3
    4 5 6
    7 8 9
which is '123\n456\n789' is sliced into:

['123', '456', '789', '147', '258', '369', '159', '357']
rows: b.split() -> ['123', '456', '789']
cols: [b[::4],b[1::4],b[2::4]] -> ['147', '258', '369']
diag: [b[::5],b[2::3]] -> ['159', '357']

kemudian 'XXX'dan 'OOO'diperiksa terhadap irisan.

Mengambil input sebagai string yang dipisahkan oleh baris baru XO_

Output:

  • {'XXX'}untuk X,
  • {'OOO'} untuk O
  • {} untuk dasi

Bekerja dengan mengiris string menjadi kolom baris dan diagonal:

The board:
    1 2 3
    4 5 6
    7 8 9
which is '123\n456\n789' is sliced into:

['123', '456', '789', '147', '258', '369', '159', '357']
rows: b.split() -> ['123', '456', '789']
cols: [b[::4],b[1::4],b[2::4]] -> ['147', '258', '369']
diag: [b[::5],b[2::3]] -> ['159', '357']

kemudian 'XXX'dan 'OOO'diperiksa terhadap irisan.

TFeld
sumber
Python slicing FTW Anyways, 81 byte , seharusnya berfungsi, saya kira.
totallyhuman
@icrieverytim [2::2]memotong 3579, sambil [2:8:2]memberi357
TFeld
Python 3, 73 byte .
Jonathan Frech
3

R, 118 116 115 byte

Terima kasih kepada @ user2390246 untuk dua byte tambahan.

function(M,b=table,u=unlist(c(apply(M,1,b),apply(M,2,b),b(diag(M)),b(M[2*1:3+1]))))`if`(any(u>2),names(u[u>2]),"T")

Sedikit tidak berbulu:

function(M){
    u=unlist(c(apply(M,1,table), #Contingency table of the rows
             apply(M,2,table), #of the columns
             table(diag(M)), #of the diagonal
             table(M[2*1:3+1]))) #of the opposite diagonal
    `if`(any(u>2),names(u[u>2]),"T") #Give name of element that occurs more than twice in any setting
 }

Mengembalikan Xjika X menang, Ojika O menang dan Tdalam kasus seri.

Cobalah online!

plannapus
sumber
1
M[c(3,5,7)]lebih pendek untuk diagonal yang berlawanan
user2390246
3

Perl 5 , 58 byte

56 byte kode + 2 fpr -p0.

$_=eval sprintf'/(.)(.{%s}\1){2}/s||'x4 .'0?$1:T',0,2..4

Cobalah online!

Keluaran Xdan Ountuk kemenangan, atauT untuk seri. Termasuk sekelompok kode header / footer untuk menguji sekaligus.


Alternatif, 58 byte

$}.="/(.)(.{$_}\\1){2}/s||"for 0,2..4;$_=eval$}.'0?$1:T'

Cobalah online!

Dom Hastings
sumber
2

Python 2 , 124 118 117 115 byte

  • Disimpan enam byte, terima kasih Erik the Outgolfer ; menggunakan string untuk menghindari komata.
  • Disimpan satu byte berkat Tn. Xcoder ; bermain golf [j*3:j*3+3]untuk[j*3:][:3] .
  • Menyimpan dua byte dengan menggunakan angka ajaib untuk mengompresi string.
def T(B):
 for j in range(8):
	a,b,c=map(int,`0x197bf3c88b2586f4bef6`[j*3:][:3])
	if B[a]==B[b]==B[c]>0:return B[a]

Cobalah online!

Nilai input / output

  • X direpresentasikan sebagai 1
  • O direpresentasikan sebagai 2
  • _ direpresentasikan sebagai None
Jonathan Frech
sumber
[8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6]->map(int,'8036147258048246')
Erik the Outgolfer
@EriktheOutgolfer Terima kasih. Saya mencoba golf daftar integer dengan menggunakan map(ord,"..."), meskipun nulbyte di tengah-tengah string tidak berhasil ...
Jonathan Frech
117 byte . [j*3:j*3+3]adalah [j*3:][:3]. Sebagai catatan, j*3+3sama dengan -~j*3, tetapi itu juga 118 byte.
Tn. Xcoder
@JonathanFrech Anda sepertinya punya tambahan 01234567...
Erik the Outgolfer
1
@ Mr.Xcoder Terima kasih. Belajar golf mengiris baru hari ini.
Jonathan Frech
2

Python 3 , 173 byte

lambda x:h(x,1)*2or+h(x,0)
h=lambda x,y:g(x,y)or g(zip(*x),y)or x[0][0]==x[1][1]==x[2][2]==y or x[0][2]==x[1][1]==x[2][0]==y
g=lambda x,y:any(all(e==y for e in r)for r in x)

Cobalah online!

  • Input sebagai matriks 1 == X, 0 == O, -1 == _

  • Output sebagai nilai tunggal: 2 == X, 1 == O, 0 == TIE

-8 byte terima kasih kepada Erik the Outgolfer

HyperNeutrino
sumber
Anda dapat mengganti baris pertama dengan lambda x:h(x,1)*2or+h(x,0)-8 byte dan 0 == TIE(yang lebih cantik imo).
Erik the Outgolfer
@EriktheOutgolfer keren, terima kasih
HyperNeutrino
2

PHP, 70 byte

for($c=95024101938;${${$i++&7}.=$argn[$c%9]}=1<$c/=3;);echo$XXX-$OOO;

Diasumsikan -n(default juru bahasa). Selain itu membutuhkan -R(mengeksekusi<code> untuk setiap baris input), dihitung sebagai satu.

Input diambil pada satu baris (persis seperti dalam deskripsi masalah, kecuali dengan semua spasi putih dihapus).

Outputnya adalah sebagai berikut: 1→ X Menang, -1→ O Menang,0 → Tie.

Cobalah online!

primo
sumber
Anda tidak perlu memiliki seluruh string, Anda dapat memilih nilai output Anda. 'X Wins'dapat diubah menjadi 'X'(atau bahkan bilangan bulat - katakanlah 1). Hal yang sama berlaku untuk 'O wins'dan Tie. Itu dikatakan, 109 byte .
Tn. Xcoder
@ Mr.Xcoder terima kasih atas klarifikasi.
Primo
1

Retina , 49 byte

;
;;
.*(\w)(.)*\1(?<-2>.)*(?(2)(?!))\1.*
$1
..+
T

Cobalah online!Mengambil input sebagai string 11-karakter dari 9 Xs, Os atau -s dalam tiga kelompok tiga yang dipisahkan oleh ;s, meskipun tautan menyertakan header yang menerjemahkan kasus uji yang diberikan ke format ini. Berfungsi dengan mencocokkan garis pemenang secara langsung menggunakan grup penyeimbang untuk memastikan bahwa ketiga karakter yang cocok sama. (Jarak yang cocok adalah 0 (garis horizontal), 4 (terbalik diagonal), 5 (garis vertikal), atau 6 (diagonal); jarak lain akan mengenai ;atau memanjang di luar string.)

Neil
sumber
1

Java 8, 112 108 106 104 90 102 93 byte

b->b.replaceAll(".*(X|O)(\\1|...\\1...|.{4}\\1.{4}|..\\1..)\\1.*","$1").replaceAll("..+","T")

+12 byte (90 → 102) karena perbaikan bug hanya memeriksa satu diagonal, bukan keduanya ..
-9 byte (102 → 93) dengan menggunakan replaceAllalih-alihmatches .

Input dalam format XOX OX_ O_X, output X,O atau T.

Penjelasan:

Coba di sini.

b->{                   // Method with String as both parameter and return-type
  b.replaceAll(".*(X|O)(\\1|...\\1...|.{4}\\1.{4}|..\\1..)\\1.*",
                       //  If we found a line of X or O:
     "$1")             //   Replace it with either X or O
   .replaceAll("..+",  //  If there are now more than 2 characters left:
     "T")              //   Replace it with T
                       // End of method (implicit / single-line return-statement)

Penjelasan regex:

.*(X|O)(\1|...\1...|.{4}\1.{4}|..\1..)\1.*
.*                                      .*# 0 or more trailing & leading chars
  (X|O)                               \1  # X or O next to those leading/trailing chars
       (\1                                # A single X or O in between (row found)
          |...\1...                       # 3 chars, X or O, 3 chars (column found)
                   |.{4}\1.{4}            # 4 chars, X or O, 4 chars (diagonal TLBR found)
                              |..\1..)    # 2 chars, X or O, 2 chars (diagonal TRBL found)
Kevin Cruijssen
sumber
0

Retina , 127 byte

.*(X|O)\1\1.*
$1
(X|O).. \1.. \1..
$1
.(X|O). .\1. .\1.
$1
..(X|O) ..\1 ..\1
$1
(X|O).. .\1. ..\1
$1
..(X|O) .\1. \1..
$1
..+
_

Cobalah online!

... Saya kira Anda bisa memanggil kekuatan kasar ini ... Pikir mungkin ada beberapa manfaat untuk itu ...

benar-benar manusiawi
sumber
0

Retina , 51 byte

.*(X|O)(\1|...\1...|.{4}\1.{4}|..\1..)\1.*
$1
..+
T

Port of Java 8 saya jawab . Masukkan dalam format XOX OX_ O_X, output X, Oatau T.

Penjelasan:

Coba di sini.

.*(X|O)(\1|...\1...|.{4}\1.{4}|..\1..)\1.*
.*                                      .*# 0 or more trailing & leading chars
  (X|O)                               \1  # X or O next to those leading/trailing chars
       (\1                                # A single X or O in between (row found)
          |...\1...                       # 3 chars, X or O, 3 chars (column found)
                   |.{4}\1.{4}            # 4 chars, X or O, 4 chars (diagonal TL→BR found)
                              |..\1..)    # 2 chars, X or O, 2 chars (diagonal TR→BL found)

$1                                        #  Replace match of above with either X or O

..+                                       # If there are now 2 or more characters left:
T                                         #  Replace everything with T
Kevin Cruijssen
sumber
0

J, 34 byte

[:>./[:+./"1(2 1 0},:0 1 2}),(,|:)

Tidak Disatukan:

[: >./ [: +./"1 (2 1 0} ,: 0 1 2}) , (, |:)

Penjelasan

Pengkodean:

X = 2
O = 3
_ = 1

Strategi tingkat tinggi kami adalah pertama-tama membuat matriks yang setiap barisnya merupakan kemungkinan kemenangan. Baris satu adalah diagonal /, baris 2 adalah diagonal \, tiga baris berikutnya adalah baris, dan tiga baris terakhir adalah kolom. Bagian ini dipenuhi oleh frasa (menggunakan Item Amend }):

(2 1 0},:0 1 2}),(,|:)

Akhirnya kami mengambil GCD dari setiap baris:

+./"1

Berkat pengodean kami, setiap baris dengan kosong akan memiliki GCD 1, seperti juga setiap baris yang berisi campuran Xs dan Os, karena 2 dan 3 adalah coprime. Jadi yang perlu kita lakukan selanjutnya adalah menemukan elemen maksimum:>./

Jika permainan ini seri, maka akan menjadi 1. Jika seorang pemain menang, itu akan menjadi nomor pemain itu.

Cobalah online!

Jonah
sumber
0

JavaScript, 66 byte

([a,b,c,d,e,f,g,h,i])=>e&(a&i|c&g|b&h|d&f)|a&(b&c|d&g)|i&(c&f|g&h)

Menjaga agar tetap sederhana.

  • Input: Sebuah string, atau array angka atau string, dengan yang 0sesuai dengan ruang kosong, 1X, dan2 O.
  • Keluaran: 0untuk seri, 1untuk kemenangan X, 2untuk kemenangan O.

Diperluas, dengan sedikit komentar:

( [a,b,c,d,e,f,g,h,i] ) => // Break apart the input into nine variables w/ destructuring
  // Run through all possible win conditions. 1&1&1 -> 1, 2&2&2 -> 2
  e & (             // All victories involving the middle square
    a & i | c & g | // Diagonal lines
    b & h | d & f   // Vertical/horizontal through the middle
  ) | 
  a & ( b & c | d & g ) | // Victories with the top-left square
  i & ( c & f | g & h )   // Victories with the bottom-right square
Yair Rand
sumber