Tic-Tac-Toe - X veya O?


14

Arka fon

Tic-Tac-Toe'ya aşina iseniz "Görev" e geçin (Bence çoğu öyle!)

Tic-Tac-Toe iki kişilik ünlü bir oyundur. İki oyuncu tarafından kademeli olarak doldurulan 3x3'lük bir tahtadan oluşur (aşağıdaki açıklamalar); İlk oyuncu karakteri X, diğeri kullanır O. Kazanan, yatay, dikey veya çapraz olarak 3 ardışık ve aynı karakter ( Xveya O) alan ilk kişidir. Oyun tahtasının doldurulması ve oyuncuların hiçbirinin yukarıda açıklandığı gibi üç ardışık karakter almayı başaramaması durumunda, oyun berabere biter. Her iki oyuncunun da toplam 9 hamleden daha az kazanması durumunda oyunun sonunda boş noktalar olabileceğini unutmayın (bir beraberlik durumunda bu olamaz).

Görev

Bir oyunun sonunda bir Tic-Tac-Toe tahtası verildiğinde (bir dize, bir matris, 9 sıralı değerin düz bir listesi, diğer iyi biçimler), oyunu kimin kazanacağını belirleyin.

  • Girdi , biri için , biri için ve diğeri boş bir noktayı temsil eden farklı ve tutarlı değerlerden oluşacaktır .XO

  • Programınız 3 farklı, tutarlı ve boş olmayan değer üretebilmelidir: biri Xkazanırsa, diğeri Okazanırsa veya oyuncular bağlıysa diğeri.

    Lütfen bu değerleri cevabınızda belirtin. Girişin geçerli bir Tic-Tac-Toe kartı olacağını varsayabilirsiniz.

Test Durumları

X, O, _Burada giriş değerleri; X wins, O winsve Tieçıktı içindir.

X O X
O X _
O _ X

Çıktı: X wins.

X _ O
X O _
X O X

Çıktı: X wins.

X O X
_ O X
_ O _

Çıktı: O wins.

X O X
O O X
X X O

Çıktı: Tie.


Her zamanki gibi, tüm standart kurallarımız geçerlidir. Bu , her dilde bayt en kısa kod kazanır!


2
Beynimden çık! Kelimenin tam anlamıyla, Pazartesi günü Sanbox yapacağım bir Noughts & Crosses mücadelesi için bir fikrim vardı. Sonra siteyi açmak çatlamak ve bunu görmek!
Shaggy

1
@Shaggy "Hızlı ve Öfkeli" dizisinden birini alıntılamak için: Çok yavaş! ; p
Bay Xcoder

Tamam, benim fikrim daha önce yapılmamış olduğunu varsayarak oynanabilir bir versiyonuydu.
Shaggy

4
@Laikoni Bunun bir dupe olduğunu düşünmüyorum, çünkü bu daha esnek bir giriş ve çıkışa ve ayrıca boş kutulara sahip ve bu da girişin geçerli bir kart olduğunu varsaymanıza izin veriyor.
Outgolfer Erik

1
@Joshua Bu bir Tic-tac-toe oyunu yapmakla ilgilidir. Bu bir not vermekle ilgilidir.
DonielF

Yanıtlar:


6

Jöle ,  16 15  14 bayt

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

Değerleri olan bir liste listesini (satırlar veya sütunlar) kabul eden monadik bir bağlantı:

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

Sonuçların döndürülmesi:

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

Not: için sıfır değerini kullanarak _ve eşit ama zıt değerleri Xve Obu değer (burada 0.155) aralığında olabilir (1/6, 1/7)(her iki uçta da özel) - Sadece tam olarak gösterilebilen kayan nokta sonucu verdiğini de aralıktaki bir değere seçti kazanmak için.

Çevrimiçi deneyin!

Nasıl?

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)

Evet, bence herhangi bir ezoterik dil cevabının bir açıklaması olmalı (ve normal diller için de açıklamaları görmek istiyorum!)
Jonathan Allan

Eklediğiniz için teşekkürler! Çok iyi bir yaklaşım, düşündüğümden çok daha akıllıca ... Güzel
Bay Xcoder

6

Javascript (ES6), 103 87 bayt

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

Giriş

  • X şu şekilde temsil edilir: 1
  • O şu şekilde temsil edilir: 2
  • _ şu şekilde temsil edilir: 0

Çıktı

  • X kazançları şu şekilde temsil edilir: "111"
  • O kazanmaları şu şekilde temsil edilir: "000"
  • Kravat şu şekilde temsil edilir: "T"

açıklama

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

Test senaryoları

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


"Programınız 3 farklı, tutarlı ve boş olmayan değer üretebilmelidir", böylece bağlantı için boş dize çıktısı alamazsınız.
RedClover

1
@ Soou Kötülük, kuralların bu kısmını kaçırdım.
Herman L

4

Jöle , 18 bayt

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

Çevrimiçi deneyin!

X= 1, O= -1, _= 0
X kazanır = [1, 1, 1], O kazanır = [-1, -1, -1], Kravat = Her birinde 0
3 elemandan oluşan 3 listenin listesi olarak girilir (1, -1, 0).


Wow Nice ... Golf işiniz bittiğinde, lütfen I / O değerlerini ve bir açıklama ekleyin :-)
Bay Xcoder

İşte biraz daha kısa bir testle benzer bir yaklaşım. Alır X= 1, O= 2, _= 3, döner 1(X kazanç), 2(O kazanç) ya da 3(bağlantı).
Arnauld

@Kısalma için teşekkürler
Erik Outgolfer

3

Python 3 , 73 bayt

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

Çevrimiçi deneyin!


Python 2 , 100 95 92 87 82 77 bayt

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

Çevrimiçi deneyin!


Girdiyi yeni satırdan ayrılmış bir dize olarak alır XO_

Çıktılar:

  • {'XXX'}için X,
  • {'OOO'} için O
  • {} kravat için

Dizeyi satır sütunlarına ve köşegenlerine dilimleyerek çalışır:

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

sonra 'XXX've 'OOO'dilimlere karşı kontrol edilir.

Girdiyi yeni satırdan ayrılmış bir dize olarak alır XO_

Çıktılar:

  • {'XXX'}için X,
  • {'OOO'} için O
  • {} kravat için

Dizeyi satır sütunlarına ve köşegenlerine dilimleyerek çalışır:

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

sonra 'XXX've 'OOO'dilimlere karşı kontrol edilir.


Python dilimleme FTW Neyse, 81 bayt çalışmalı diye düşünüyorum.
totallyhuman

@icrieverytim [2::2]dilimleri verir 3579, [2:8:2]verir357
TFeld

Python 3, 73 bayt .
Jonathan Frech

3

R, 118 116115 bayt

İki kullanıcı için @ user2390246'ya teşekkürler .

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

Hafifçe soluksuz:

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
 }

İade XX kazanır eğer, OO kazanır ve eğer Tbir kravat durumunda.

Çevrimiçi deneyin!


1
M[c(3,5,7)]karşı diyagonal için daha kısa
user2390246

3

Perl 5 , 58 bayt

56 bayt kodu + 2 fpr -p0.

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

Çevrimiçi deneyin!

Çıktılar Xve Okazançlar için veya Tbir kravat için. Hepsini bir kerede test etmek için bir grup üstbilgi / altbilgi kodu içerir.


Alternatif, 58 bayt

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

Çevrimiçi deneyin!


2

Python 2 , 124 118 117 115 bayt

  • Outgolfer Erik sayesinde altı bayt tasarruf etti ; virgül kullanmaktan kaçınmak için bir dize kullanmak.
  • Bay Xcoder sayesinde bir bayt kurtardı ; golf [j*3:j*3+3]için [j*3:][:3].
  • Dizeyi sıkıştırmak için sihirli bir sayı kullanarak iki bayt kaydedildi.
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]

Çevrimiçi deneyin!

Giriş / Çıkış değerleri

  • X olarak temsil edilir 1
  • O olarak temsil edilir 2
  • _ olarak temsil edilir None

[8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6]->map(int,'8036147258048246')
Outgolfer Erik

@EriktheOutgolfer Teşekkürler. Ben bir dize ortasında map(ord,"...")bir nulbayt işe yaramadı rağmen, kullanarak tamsayı listesini golf çalışıyordu ...
Jonathan Frech

117 bayt . [j*3:j*3+3]olduğunu [j*3:][:3]. Bir yan not j*3+3olarak -~j*3, aynıdır , ancak bu 118 bayttır.
Bay Xcoder

01234567
@JonathanFrech

1
@ Mr.Xcoder Teşekkürler. Bugün yeni bir dilimleme golf öğrendim.
Jonathan Frech

2

Python 3 , 173 bayt

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)

Çevrimiçi deneyin!

  • Matrisi olarak giriş 1 == X, 0 == O, -1 == _

  • Tek bir değer olarak çıktı: 2 == X, 1 == O, 0 == TIE

Outgolfer Erik sayesinde -8 bayt


İlk satırı lambda x:h(x,1)*2or+h(x,0)-8 baytlık 0 == TIE(ve daha güzel imo olan) ile değiştirebilirsiniz.
Outgolfer Erik

@EriktheOutgolfer harika, teşekkürler
HyperNeutrino

2

PHP, 70 bayt

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

Varsayımlar -n(tercüman varsayılanları). Ek olarak, bir olarak sayılan gerektirir -R( <code>her girdi satırı için yürüt ).

Giriş tek bir satıra alınır (tüm boşluklar kaldırılmış durum hariç, sorun tanımındaki gibi).

Çıktı şu şekildedir: 1→ X Kazanır, -1→ O Kazanır, 0→ Bağla.

Çevrimiçi deneyin!


Dizelerin tamamına sahip olmanıza gerek yoktur, çıktı değerlerinizi seçebilirsiniz. 'X Wins'olarak değiştirilebilir 'X'(hatta bir tam sayı - hatta 1). Aynısı 'O wins've için de geçerlidir Tie. Olduğu söyleniyor, 109 bayt .
Bay Xcoder

@ Mr.Xcoder açıklama için teşekkürler.
primo

1

Retina , 49 bayt

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

Çevrimiçi deneyin! Bağlantı, verilen test senaryolarını bu formata çeviren bir başlık içermesine rağmen, girdiyi s ile ayrılmış üç kişilik üç grup halinde 9 Xs, Os veya -s'lik 11 karakterlik bir dize olarak alır ;. Eşleşen üç karakterin eşit uzaklıkta olmasını sağlamak için kazanan bir çizgiyi doğrudan bir dengeleme grubu kullanarak eşleştirerek çalışır. (Uygun mesafeler 0 (yatay çizgi), 4 (ters diyagonal), 5 (dikey çizgi) veya 6 (diyagonal); diğer mesafeler ;dizginin dışına çarpar veya uzanır.)


1

Java 8, 112 108 106 104 90 102 93 bayt

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

Nedeniyle yerine sadece ikisi .. diyagonal birini kontrol etme hata düzeltme için 12 bayt (90 → 102)
kullanılarak -9 bayt (→ 93 102) replaceAllyerine matches.

Biçimdeki giriş XOX OX_ O_X , çıktı X, Oya T.

Açıklama:

Burada deneyin.

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)

Açıklama 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)

0

Retina , 127 bayt

.*(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
..+
_

Çevrimiçi deneyin!

... sanırım bu kaba kuvvet diyebilirsin ... Bunun bir değeri olabileceğini düşündüm ...


0

Retina , 51 bayt

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

Port benim Java 8 cevap . Biçiminde Girdi XOX OX_ O_X, çıktı X, Oya T.

Açıklama:

Burada deneyin.

.*(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

0

J, 34 bayt

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

Ungolfed:

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

açıklama

Kodlama:

X = 2
O = 3
_ = 1

Üst düzey stratejimiz, her biri sıraları olası bir kazanç olan bir matris oluşturmaktır. Birinci satır çapraz / satır 2 çapraz \, sonraki üç satır satır ve son üç satır sütundur. Bu bölüm (Öğe Değişikliği kullanılarak }) ifadesi ile gerçekleştirilir :

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

Sonunda her bir satırın GCD'sini alıyoruz:

+./"1

Kodlamamız sayesinde, boş olan herhangi bir satır 1 GCD'ye sahip olacaktır, ayrıca X ve Os'ın herhangi bir karışımını içeren herhangi bir satır olacaktır, çünkü 2 ve 3 eşzamanlıdır. Bundan sonra tek yapmamız gereken maksimum elementi bulmak:>./

Oyun bir beraberlik ise 1 olacaktır. Eğer bir oyuncu kazanırsa, o oyuncunun numarası olacaktır.

Çevrimiçi deneyin!


0

JavaScript, 66 bayt

([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)

Basit tutmak.

  • Girdi: 0Boş bir boşluğa, 1X'e ve 2O'ya karşılık gelen bir dize ya da sayı ya da dize dizisi .
  • Çıktı: 0beraberlik 1için, X zafer 2için, O zafer için.

Genişletilmiş, hafifçe yorumladı:

( [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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.