Tic Tac Toe galibi belirleme (yuvarlak tabanlı)


26

Biraz kod golf oynayalım!

Buradaki zorluk Tic-Tac-Toe oyununun galibi bulmak.

Bu, açık bir kazanan olan bir tahta vererek birçok kez yapıldı, ancak işte twist:

Hücreler bu şekilde numaralandırılmıştır:

1|2|3
-+-+-
4|5|6
-+-+-
7|8|9

Bunun gibi tam 9 hamle dizisi alırsınız:

{3, 5, 6, 7, 9, 8, 1, 2, 3}

Bu şu şekilde ayrıştırılır:

  • Oyuncu 1, hücre 3'ü işaretler
  • Oyuncu 2, hücre 5'i işaretler
  • Oyuncu 1, hücre 6'yı işaretler
  • Oyuncu 2, hücre 7'yi işaretler
  • Oyuncu 1, hücre 9'u işaretler
  • Oyuncu 1 kazandı

Not: Bir oyuncu kazandıktan sonra oyun durmaz, kaybeden oyuncunun kazanan oyuncudan sonra arka arkaya üç almayı başarması muhtemel olabilir, ancak yalnızca ilk galibiyet sayılır.

İşiniz şimdi 9 sayı almak ve giriş yapmak ve kazanan oyuncuyu ve kazanmanın gerçekleştiği turu almaktır. Eğer kimse kazanmazsa, seçtiğiniz bir şeyi sabit olarak alın. Herhangi bir standart ortalama / formatta girdi alabilir ve çıktı alabilirsiniz.

İyi eğlenceler!

İstenildiği gibi daha fazla örnek:

{2,3,4,5,6,7,1,8,9} => Player 2 wins in round 6
{1,2,4,5,6,7,3,8,9} => Player 2 wins in round 8
{1,2,3,5,4,7,6,8,9} => Player 2 wins in round 8

11
PPCG'ye Hoşgeldiniz! Bu güzel bir ilk yazı, ancak genellikle çok kısıtlayıcı giriş / çıkış biçimlerini sevmiyoruz . "Player X, Y turunda kazanır" ı kaldırmayı ve bir liste gibi makul bir formatta çıkmamıza izin verir [X, Y]misiniz? Beraberlik durumunda, bunun yerine başka bir tutarlı değer verebilir miyiz? Bunu tavsiye ediyorum, çünkü bu kesin dizgelerin basılması, golf oynamaya dahil değil. Gelecekteki meydan okuma fikirleri için, sanal alanı kullanmanızı öneririm . :-)
Bay Xcoder

Üzgünüm benim hatam. Bence şimdi doğru.
Grunzwanzling

Sona kadar olan mücadeleyi okuyun, bir çekiliş olabileceğini ve ne zaman olursa olsun seçtiğiniz bir şeyi çıktırabileceğinizi söylüyorum. 2. oyuncu 6. turda kazandığında {2,6}, hiç kimse kazanmadığında {0,0}.
Grunzwanzling

0 indeksli her şeyi kullanabilir miyiz? (hücreler, oyuncular, mermiler)
Arnauld

1
“Bunun gibi tam 9 hareket dizisi alıyorsunuz: {3, 5, 6, 7, 9, 8, 1, 2, 3}” - 3gerçekten iki kere görünmeli mi?
Jonathan Allan,

Yanıtlar:


8

Retina , 114 bayt

(.)(.)
$1O$2X
^
123;;456;;789¶X
{`(.)(.*¶)(.)\1
$3$2
}`.*(.)(.)*\1(?<-2>.)*(?(2)(?!))\1.*¶(..)*
$1$#3
.*¶
T
T`d`Rd

Çevrimiçi deneyin! Tic-Tac-Toe'ya verdiğim cevaba göre - X mi yoksa O mu? . Çıkışlar X<N>ilk oyuncu sonra kazanırsa Ndönüşler, O<N>ikinci oyuncu kazanır eğer, Tne kazanır eğer. Açıklama:

(.)(.)
$1O$2X
^
123;;456;;789¶X

Dahili bir tahta oluşturur ve her hareketi bir hamle olan oyuncu ile işaretler.

{`(.)(.*¶)(.)\1
$3$2

Bir hareket uygular.

}`.*(.)(.)*\1(?<-2>.)*(?(2)(?!))\1.*¶(..)*
$1$#3

Galibiyet için arama yapar ve biri bulunursa, tahtayı kazananla ve kalan hamle sayısı ile değiştirin.

.*¶
T

Eğer hamleler tükenirse ve kimse kazanmazsa, oyun bir beraberliktir.

T`d`Rd

Kalan hamlelerin sayısından turun sayısını hesapla.


4
Bu, burada gördüğüm daha şehvetli cevaplardan biri.
Lord Farquaad

6

MATL , 39 bayt

3:g&+XIx"IX@oXK@(XIt!yXdyPXd&hK=Aa?KX@.

Çıktı

  • 1ve Reğer kullanıcı 1, R turunda kazanırsa, ayrı hatlarda ;
  • 0ve Reğer kullanıcı 2 R turunda kazanırsa, ayrı hatlarda ;
  • Kimse kazanmazsa boş.

Çevrimiçi deneyin!Veya tüm test durumlarını doğrulayın .

açıklama

3:       % Push [1 2 3]
g        % Convert to logical. Gives [true true true]
&+       % Matrix of all pairs of additions. Gives a 3×3 matrix, which represents
         % the board in its initial state, namely all cells contain 2. This value
         % means "cell not used yet". 1 will represent "cell marked by user 1",
         % and 0 will represent "cell marked by user 2"
XI       % Copy into clipboard I
x        % Delete
"        % Implicit input: array with moves. For each move
  I      %   Push current board state
  X@     %   Push iteration index (starting at 1), that is, current round number
  o      %   Modulo 2: gives 1 or 0. This represents the current user
  XK     %   Copy into clipboard K
  @      %   Push current move ((that is, cell index)
  (      %   Write user identifier (1 or 0) into that cell. Cells are indexed
         %   linearly in column-major order. So the board is transposed compared
         %   to that in the challenge, but that is unimportant
  XI     %   Copy updated board into clipboard I
  t!     %   Duplicate and transpose
  y      %   Duplicate from below: push copy of board
  Xd     %   Extract main diagonal as a 3×1 vector
  y      %   Duplicate from below: push copy of transposed board
  PXd    %   Flip vertically and extract main diagonal. This is the anti-diagonal
         %   of the board
  &h     %   Concatenate stack horizontally. This concatenates the board (3×3),
         %   transposed board (3×3), main diagonal (3×1 vector) and anti-diagonal
         %   (3×1) into an 3×8 matrix
  K=     %   Push current user identifier. Test for equality with each entry of the
         %   3×8 matrix
  A      %   For each column, this gives true if all its entries are true. Note 
         %   that the first three columns in the 3×8 matrix are the board columns;
         %   the next three are the board rows; and the last two columns are the
         %   main diagonal and anti-diagonal. The result is a 1×8 vector
  a      %   True if any entry is true, meaning the current user has won
  ?      %   If true
    K    %     Push current user identifier
    X@   %     Push current round number
    .    %     Break for loop
         %   Implicit end
         % Implicit end
         % Implicit display

5

Javascript (ES6), 130 bayt

m=>m.reduce((l,n,i)=>l||(b[n-1]=p=i%2+1,"012,345,678,036,147,258,048,246".replace(/\d/g,m=>b[m]).match(""+p+p+p)&&[p,i+1]),0,b=[])

f=m=>m.reduce((l,n,i)=>l||(b[n-1]=p=i%2+1,"012,345,678,036,147,258,048,246".replace(/\d/g,m=>b[m]).match(""+p+p+p)&&[p,i+1]),0,b=[])
console.log(JSON.stringify(f([3,5,6,7,9,8,1,2,3])))
console.log(JSON.stringify(f([2,3,4,5,6,7,1,8,9])))
console.log(JSON.stringify(f([1,2,4,5,6,7,3,8,9])))
console.log(JSON.stringify(f([1,2,3,5,4,7,6,8,9])))

açıklama

m=>m.reduce((l,n,i)=>               // Reduce the input array with n as the current move
  l||(                              //  If there is already a winner, return it
  b[n-1]=p=i%2+1,                   //  Set the cell at b[n-1] to the current player p
  "012,345,678,036,147,258,048,246" //  For every digit in the list of possible rows:
    .replace(/\d/g,m=>b[m])         //   Replace it with the player at the cell
    .match(""+p+p+p)                //  If any of the rows is filled with p:
      &&[p,i+1]                     //   Return [p, current move]
),0,b=[])

Lütfen bir açıklama veya asılsız bir sürüm sunabilir misiniz? Çözümünüzü anlamak istiyorum.
Jack

4

Java (OpenJDK 8) , 445 bayt

int[] t(int[]m){int[][]f=new int[3][3];boolean z=false;for(int i=0;i<9;i++){f[m[i]%3][m[i]/3]=z?2:1;if(f[m[i]%3][0]==(z?2:1)&&f[m[i]%3][1]==(z?2:1)&&f[m[i]%3][2]==(z?2:1)||f[0][m[i]/3]==(z?2:1)&&f[1][m[i]/3]==(z?2:1)&&f[2][m[i]/3]==(z?2:1)||m[i]%3+m[i]/3==2&&f[0][2]==(z?2:1)&&f[1][1]==(z?2:1)&&f[2][0]==(z?2:1)||m[i]%3==m[i]/3&&f[0][0]==(z?2:1)&&f[1][1]==(z?2:1)&&f[2][2]==(z?2:1)){return(new int[]{(z?2:1),++i});}z=!z;}return(new int[]{0,0});}

Çevrimiçi deneyin!

Dönüş değeri {1,8}, oyuncu 1'in 8. turda kazandığı anlamına gelir.


5
Gereksiz tüm boşlukları kaldırmazsanız, bu çabanın golf eforu eksikliğinden dolayı geçersiz olduğu kabul edilir. Dahası, kendi mücadelenizi bu kadar hızlı yanıtlamanız kesinlikle tavsiye edilmez ve kodunuzu test edebileceğimiz bir TIO bağlantısı eklemek isteyebilirsiniz .
Bay Xcoder


Üzgünüm, yanlış şeyi kopyaladım. Aslında çok daha kısa
Grunzwanzling

Java sorusunda golf oynamak için ipuçlarını görebilirsiniz, bazı baytları kaldırın. Örneğin false, değiştirilebilir 1<0ve ilkinden sonraki boşluk ]kaldırılabilir.
user202729

442 bayt . Ayrıca "Başlık" ve "Altbilgi" bölümü TIO üzerinde var sebebi yorumun gerek kalmamasıdır //Code that was submittedve //End of code.
user202729

2

Kotlin , 236 bayt

i.foldIndexed(l()to l()){o,(a,b),p->fun f(i:(Int)->Int)=b.groupBy(i).any{(_,v)->v.size>2}
if(f{(it-1)/3}|| f{it%3}|| listOf(l(1,5,9),l(3,5,7)).any{b.containsAll(it)}){return p%2+1 to o}
b to a+p}.let{null}
fun l(vararg l:Int)=l.toList()

Beautified

    i.foldIndexed(l() to l()) { o, (a, b), p ->
        fun f(i: (Int) -> Int) = b.groupBy(i).any { (_, v) -> v.size > 2 }
        if (f { (it - 1) / 3 } || f { it % 3 } || listOf(l(1, 5, 9), l(3, 5, 7)).any { b.containsAll(it) }) {
            return p % 2 + 1 to o
        }
        b to a + p
    }.let { null }
fun l(vararg l:Int)= l.toList()

Ölçek

fun f(i: List<Int>): Pair<Int, Int>? =
i.foldIndexed(l()to l()){o,(a,b),p->fun f(i:(Int)->Int)=b.groupBy(i).any{(_,v)->v.size>2}
if(f{(it-1)/3}|| f{it%3}|| listOf(l(1,5,9),l(3,5,7)).any{b.containsAll(it)}){return p%2+1 to o}
b to a+p}.let{null}
fun l(vararg l:Int)=l.toList()

data class Test(val moves: List<Int>, val winner: Int, val move: Int)

val tests = listOf(
        Test(listOf(3, 5, 6, 7, 9, 8, 1, 2, 3), 1, 5),
        Test(listOf(2, 3, 4, 5, 6, 7, 1, 8, 9), 2, 6),
        Test(listOf(1, 2, 4, 5, 6, 7, 3, 8, 9), 2, 8),
        Test(listOf(1, 2, 3, 5, 4, 7, 6, 8, 9), 2, 8)
)

fun main(args: Array<String>) {
    tests.forEach { (input, winner, move) ->
        val result = f(input)
        if (result != winner to move) {
            throw AssertionError("$input ${winner to move} $result")
        }
    }
}

TIO

TryItOnline


1

Python 2 , 170 bayt

q=map(input().index,range(1,10))
z=zip(*[iter(q)]*3)
o='',
for l in[q[2:7:2],q[::4]]+z+zip(*z):
 r=[n%2for n in l];y=all(r)*2+1-any(r)
 if y:o+=[max(l)+1,y],
print min(o)

Çevrimiçi deneyin!veya Tüm test durumlarını deneyin

#swap cell number / turn
q=map(input().index,range(1,10))
#split in 3 parts (rows)
z=zip(*[iter(q)]*3)
#starting value for the list with the results
#since string are "greater" than lists, this will
#be the output value when there is a draw
o='',
#iterate over diagonals, rows and columns
for l in[q[2:7:2],q[::4]]+z+zip(*z):
 #use %2 to separate between player 1 and 2
 r=[n%2 for n in l]
 #store in y the value of the player if the trio is a valid win, 0 otherwise
 #it's a win if all moves are from the same player
 y=all(r)*2+1-any(r)
 #if y has a valid player, add the highest turn of the trio, and the player to o
 if y:o+=[max(l)+1,y],
#output the smaller turn of the valid winning trios
print min(o)


1

Python 3.6+, 137 bayt

n=m=c=z=0
for a in input():m+=1<<~-int(a);c+=1;z=z or f'{c&1}:{c}'*any(m&t==t for t in[7,56,448,73,146,292,273,84]);n,m=m,n
print(z or-1)

Çıkış formatı winner number:roundveya -1kravat içindir. Oyuncu 2, 0Oyuncu 1'dir 1. 1 indeksli kare sayıları bir undelze dize şeklinde giriş.


1

Jöle , 35 bayt

9s3,ZU$$;ŒD$€Ẏf€⁸L€3e
s2ZÇƤ€ZFTḢ;Ḃ$

Hareketlerin bir listesini [move, player]alan ve oyuncuların 1(ilk önce hareket eden) ve 0(ikinci kez hareket eden) olarak tanımlandığı bir listeye geri dönen bir monadik bağlantı .

Çevrimiçi deneyin!

Nasıl?

9s3,ZU$$;ŒD$€Ẏf€⁸L€3e - Link 1: any winning play?: list of player's moves:
9s3                   - (range of) nine split into threes = [[1,2,3],[4,5,6],[7,8,9]]
       $              - last two links as a monad:
      $               -   last two links as a monad:
    Z                 -     transpose = [[1,4,7],[2,5,8],[3,6,9]]
     U                -     upend     = [[7,4,1],[8,5,2],[9,6,3]]
   ,                  -  pair = [[[1,2,3],[4,5,6],[7,8,9]],[[7,4,1],[8,5,2],[9,6,3]]]
           $€         - last two links as a monad for €ach:
         ŒD           -   diagonals = [[1,5,9],[2,6],[3],[7],[4,8]] or [[7,5,3],[4,2],[1],[9],[8,6]]
        ;             -  concatenate = [[1,2,3],[4,5,6],[7,8,9],[1,5,9],[2,6],[3],[7],[4,8]] or [[7,4,1],[8,5,2],[9,6,3],[7,5,3],[4,2],[1],[9],[8,6]]
             Ẏ        - tighten = [[1,2,3],[4,5,6],[7,8,9],[1,5,9],[2,6],[3],[7],[4,8],[7,4,1],[8,5,2],[9,6,3],[7,5,3],[4,2],[1],[9],[8,6]]
                      -    i.e.:    row1    row2    row3    diag\   x     x   x   x     col1    col2    col3    diag/   x     x   x   x
                      -    where x's are not long enough to matter for the rest...
                ⁸     - chain's left argument, list of player's moves
              f€      - filter to keep those moves for €ach of those lists to the left
                 L€   - length of €ach result
                   3e - 3 exists in that? (i.e. were any length 3 when filtered down to only moves made?)

s2ZÇƤ€ZFTḢ;Ḃ$ - Main link: list of the moves  e.g. [2,3,4,5,6,7,1,8,9]
s2            - split into twos                    [[2,3],[4,5],[6,7],[1,8],[9]]
  Z           - transpose                          [[2,4,6,1,9],[3,5,7,8]]
    Ƥ€        - for Ƥrefixes of €ach:
   Ç          -   call last link (1) as a monad     [0,0,0,0,0] [0,0,1,1]
      Z       - transpose                          [[0,0],[0,0],[0,1],[0,1],[0]]
       F      - flatten                            [0,0,0,0,0,1,0,1,0]
        T     - truthy indices                     [          6   8  ]
         Ḣ    - head (if empty yields 0)           6
            $ - last two links as a monad:
           Ḃ  -   modulo by 2 (evens are player 2) 0
          ;   -   concatenate                      [6,0]

0

Python 2, 168 bayt

import itertools as z
f=lambda g:next(([i%2+1,i+1]for i in range(9) if any(c for c in z.combinations([[0,6,1,8,7,5,3,2,9,4][j]for j in g[i%2:i+1:2]],3)if sum(c)==15)),0)

Bir kravat için çıkışlar (oynatıcı, yuvarlak) veya 0.

Oyunu 3'e 3'lük sihirli bir kareyle eşleştirir ve 15'e kadar toplayan 3'lü veya 0'lık kümeleri arar.


0

Temiz , 244 ... 220 bayt

import StdEnv
f[a,b]i#k= \l=or[and[isMember(c+n)(take i l)\\c<-:"123147159357"%(j,j+2)]\\j<-[0,3..9]&h<-:"\0\0",n<-[h-h,h,h+h]]
|k a=(1,i*2-1)|i>4=(0,0)|k b=(2,i*2)=f[a,b](i+1)
@l=f(map(map((!!)l))[[0,2..8],[1,3..7]])1

Çevrimiçi deneyin!

İçine yinelenen dize hyazdırılamaz karakterleri içerir ve buna eşittir "\003\001\000\000".


0

Python 2 , 140 136 134 bayt

lambda a,i=0:i<9and(any(set(a[i%2:i+1:2])>=set(map(int,t))for t in'123 456 789 147 258 369 159 357'.split())and(i%2+1,i+1)or f(a,i+1))

Çevrimiçi deneyin!

EDIT: 4 bayt + 2 bayt Thgolfer Eric'e.

Kazanan yoksa bir demet (playerNumber, roundNumber) veya False verir.



@Erik - Yah, bunu çoktan yapmalıydım; ama griple savaşıyorum ve gözlerim acıyor :). Teşekkürler!
Chas Brown,

Pekala, çabuk iyileş. :)
Outgolfer Erik,
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.