Tic-Tac-Toe - X hay O?


14

Lý lịch

Bỏ qua "Nhiệm vụ" nếu bạn quen thuộc với Tic-Tac-Toe (Tôi nghĩ hầu hết là vậy!)

Tic-Tac-Toe là một trò chơi hai người nổi tiếng. Nó bao gồm một bảng 3x3 được lấp đầy dần bởi hai người chơi (làm rõ bên dưới); Người chơi đầu tiên sử dụng nhân vật Xvà người khác sử dụng O. Người chiến thắng là người đầu tiên nhận được 3 ký tự liên tiếp và giống hệt nhau ( Xhoặc O), theo chiều ngang, chiều dọc hoặc đường chéo. Trong trường hợp bảng được lấp đầy và không ai trong số những người chơi quản lý để có được ba nhân vật liên tiếp như đã giải mã ở trên, trò chơi kết thúc bằng hòa. Lưu ý rằng có thể có những điểm trống ở cuối trò chơi, trong trường hợp một trong hai người chơi thắng tổng cộng dưới 9 lần di chuyển (điều này không thể xảy ra trong trường hợp hòa).

Bài tập

Đưa ra một bảng Tic-Tac-Toe ở cuối trò chơi (dưới dạng chuỗi, ma trận, danh sách phẳng gồm 9 giá trị được sắp xếp, bất kỳ định dạng hợp lý nào khác), xác định ai thắng trò chơi.

  • Đầu vào sẽ bao gồm các giá trị riêng biệt và nhất quán , một cho X, một cho Ovà một giá trị khác đại diện cho một điểm trống.

  • Chương trình của bạn sẽ có thể xuất ra 3 giá trị riêng biệt, nhất quán và không trống: một trong trường hợp Xthắng, một giá trị khác trong trường hợp Othắng hoặc một giá trị khác nếu người chơi bị ràng buộc.

    Vui lòng chỉ định các giá trị này trong câu trả lời của bạn. Bạn có thể giả định rằng đầu vào sẽ là một bảng Tic-Tac-Toe hợp lệ.

Các trường hợp thử nghiệm

X, O, _Là những giá trị đầu vào ở đây; X wins, O winsTielà cho đầu ra.

X O X
O X _
O _ X

Đầu ra : X wins.

X _ O
X O _
X O X

Đầu ra : X wins.

X O X
_ O X
_ O _

Đầu ra : O wins.

X O X
O O X
X X O

Đầu ra : Tie.


Như thường lệ, tất cả các quy tắc tiêu chuẩn của chúng tôi áp dụng. Đây là , mã ngắn nhất tính theo byte trong mọi ngôn ngữ sẽ thắng!


2
Hãy ra khỏi não của tôi! Theo nghĩa đen, chỉ có một ý tưởng cho một thử thách Noughts & Crosses rằng tôi sẽ đến Sanbox vào thứ Hai. Sau đó, tôi mở trang web và thấy điều này!
Xù xì

1
@Shaggy Để trích dẫn ai đó từ loạt bài "Nhanh và tức giận": Quá chậm! ; p
Ông Xcoder

Không sao, ý tưởng của tôi là phiên bản có thể chơi được, giả sử rằng chưa được thực hiện.
Xù xì

4
@Laikoni Tôi không nghĩ đó là bản sao, vì cách này có đầu vào và đầu ra linh hoạt hơn và cũng có các ô trống, và điều này cũng cho phép bạn cho rằng đầu vào là một bảng hợp lệ.
Erik the Outgolfer

1
@Joshua Đó là về việc tạo ra một trò chơi Tic-tac-toe. Đây là về chấm điểm một.
DonielF

Câu trả lời:


6

Thạch ,  16 15  14 byte

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

Một liên kết đơn âm chấp nhận danh sách các danh sách (các hàng - hoặc cột) với các giá trị:

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

Kết quả trả về:

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

Lưu ý: sử dụng giá trị 0 cho _và giá trị bằng nhau nhưng ngược lại cho XO, giá trị này (ở đây 0.155) có thể nằm trong phạm vi (1/6, 1/7)(không bao gồm ở cả hai đầu) - Tôi chỉ chọn một giá trị trong phạm vi đó cho kết quả điểm nổi có thể biểu thị chính xác cho các trường hợp thắng.

Hãy thử trực tuyến!

Làm sao?

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)

Vâng, tôi nghĩ rằng bất kỳ câu trả lời ngôn ngữ bí truyền nào cũng cần có lời giải thích (và tôi cũng muốn xem giải thích cho các ngôn ngữ bình thường!)
Jonathan Allan

Cảm ơn đã thêm nó! Cách tiếp cận rất tốt, cách thông minh hơn những gì tôi đã nghĩ ... Đẹp
Ông 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]

Đầu vào

  • X được biểu diễn dưới dạng 1
  • O được biểu diễn dưới dạng 2
  • _ được biểu diễn dưới dạng 0

Đầu ra

  • X thắng được thể hiện là "111"
  • O thắng được thể hiện là "000"
  • Cà vạt được thể hiện là "T"

Giải trình

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

Các trường hợp thử nghiệm

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


"Chương trình của bạn sẽ có thể xuất 3 giá trị riêng biệt, nhất quán và không trống ", vì vậy bạn không thể xuất chuỗi trống để buộc.
RedClover

1
@Soaku Xấu của tôi, tôi đã bỏ lỡ một phần của các quy tắc.
Herman L

4

Thạch , 18 byte

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

Hãy thử trực tuyến!

X= 1, O= -1, _= 0
X thắng = [1, 1, 1], O thắng = [-1, -1, -1], Tie = 0
Nhập dưới dạng danh sách 3 danh sách gồm 3 phần tử trong (1, -1, 0)mỗi.


Wow Nice ... Khi bạn chơi golf xong, vui lòng thêm các giá trị I / O và một lời giải thích :-)
Ông Xcoder

Đây là một cách tiếp cận tương tự với một bài kiểm tra ngắn hơn một chút. Takes X= 1, O= 2, _= 3, trả về 1(X thắng), 2(O thắng) hoặc 3(hòa).
Arnauld

@Arnauld cảm ơn vì đã rút ngắn
Erik the Outgolfer

3

Con trăn 3 , 73 byte

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

Hãy thử trực tuyến!


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

Hãy thử trực tuyến!


Đưa đầu vào dưới dạng một chuỗi phân tách dòng mới của XO_

Đầu ra:

  • {'XXX'} cho X,
  • {'OOO'} cho O
  • {} cho một cái cà vạt

Hoạt động bằng cách cắt chuỗi thành cột hàng và đường chéo:

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

sau đó 'XXX''OOO'được kiểm tra đối với các lát.

Đưa đầu vào dưới dạng một chuỗi phân tách dòng mới của XO_

Đầu ra:

  • {'XXX'}cho X,
  • {'OOO'} cho O
  • {} cho một cái cà vạt

Hoạt động bằng cách cắt chuỗi thành cột hàng và đường chéo:

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

sau đó 'XXX''OOO'được kiểm tra đối với các lát.


Python cắt FTW Anyways, 81 byte , nên hoạt động, tôi nghĩ vậy.
hoàn toàn là

@icrieverytim [2::2]cắt 3579, trong khi [2:8:2]cho357
TFeld

Python 3, 73 byte .
Jonathan Frech

3

R, 118 116 115 byte

Cảm ơn @ user2390246 cho hai byte bổ sung.

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

Hơi vô dụng:

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
 }

Trả về Xnếu X thắng, Onếu O thắng và Ttrong trường hợp hòa.

Hãy thử trực tuyến!


1
M[c(3,5,7)]ngắn hơn cho đường chéo đối diện
user2390246

3

Perl 5 , 58 byte

Mã 56 byte + 2 fpr -p0.

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

Hãy thử trực tuyến!

Đầu ra XOcho chiến thắng, hoặcT cho một tie. Bao gồm một loạt mã tiêu đề / chân trang để kiểm tra tất cả cùng một lúc.


Thay thế, 58 byte

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

Hãy thử trực tuyến!


2

Python 2 , 124 118 117 115 byte

  • Đã lưu sáu byte nhờ Erik the Outgolfer ; sử dụng một chuỗi để tránh dấu phẩy.
  • Đã lưu một byte nhờ ông Xcoder ; chơi golf [j*3:j*3+3]để [j*3:][:3].
  • Đã lưu hai byte bằng cách sử dụng một số ma thuật để nén chuỗi.
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]

Hãy thử trực tuyến!

Giá trị đầu vào / đầu ra

  • X được đại diện như 1
  • O được đại diện như 2
  • _ được đại diện như None

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

@EriktheOutgolfer Cảm ơn. Tôi đã cố gắng đánh gôn danh sách số nguyên bằng cách sử dụng map(ord,"..."), mặc dù một nulbyte ở giữa chuỗi không hoạt động ...
Jonathan Frech

117 byte . [j*3:j*3+3][j*3:][:3]. Như một lưu ý phụ, j*3+3cũng giống như vậy -~j*3, nhưng đó cũng là 118 byte.
Ông Xcoder

@JonathanFrech Bạn dường như có thêm 01234567...
Erik the Outgolfer

1
@ Mr.Xcoder Cảm ơn. Đã học một môn đánh gôn mới ngày hôm nay.
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)

Hãy thử trực tuyến!

  • Đầu vào dưới dạng ma trận 1 == X, 0 == O, -1 == _

  • Đầu ra dưới dạng một giá trị: 2 == X, 1 == O, 0 == TIE

-8 byte nhờ Erik the Outgolfer


Bạn có thể thay thế dòng đầu tiên bằng lambda x:h(x,1)*2or+h(x,0)-8 byte và 0 == TIE(imo đẹp hơn).
Erik the Outgolfer

@EriktheOutgolfer thật tuyệt, cảm ơn
HyperNeutrino

2

PHP, 70 byte

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

Giả định -n(thông dịch mặc định). Ngoài ra yêu cầu -R(thực hiện<code> cho mỗi dòng đầu vào), được tính là một.

Đầu vào được lấy trên một dòng duy nhất (chính xác như trong mô tả vấn đề, ngoại trừ với tất cả khoảng trắng được loại bỏ).

Đầu ra là như sau: 1→ X Thắng, -1→ O Thắng, 0→ Tie.

Hãy thử trực tuyến!


Bạn không cần phải có toàn bộ chuỗi, bạn có thể chọn các giá trị đầu ra của mình. 'X Wins'có thể được thay đổi thành 'X'(hoặc thậm chí là một số nguyên - nói 1). Điều tương tự áp dụng cho 'O wins'Tie. Điều đó đang được nói, 109 byte .
Ông Xcoder

@ Mr.Xcoder cảm ơn đã làm rõ.
primo

1

Võng mạc , 49 byte

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

Hãy thử trực tuyến! Đưa đầu vào dưới dạng chuỗi 11 ký tự gồm 9 Xs, Os hoặc -s trong ba nhóm ba được phân tách bằng ;s, mặc dù liên kết bao gồm một tiêu đề giúp dịch các trường hợp thử nghiệm đã cho sang định dạng này. Hoạt động bằng cách khớp trực tiếp một dòng chiến thắng bằng cách sử dụng một nhóm cân bằng để đảm bảo rằng ba nhân vật phù hợp là tương đương nhau. (Khoảng cách phù hợp là 0 (đường ngang), 4 (đường chéo ngược), 5 (đường dọc) hoặc 6 (đường chéo); các khoảng cách khác sẽ chạm a ;hoặc kéo dài ra ngoài chuỗi.)


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) do sửa lỗi chỉ kiểm tra một đường chéo thay vì cả hai ..
-9 byte (102 → 93) bằng cách sử dụng replaceAllthay vìmatches .

Đầu vào ở định dạng XOX OX_ O_X, đầu ra X, Ohoặc T.

Giải trình:

Hãy thử nó ở đây.

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)

Regex giải thích:

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

Võng mạc , 51 byte

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

Cổng trả lời Java 8 của tôi . Đầu vào ở định dạng XOX OX_ O_X, đầu ra X, Ohoặc T.

Giải trình:

Hãy thử nó ở đây.

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

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

Ung dung:

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

Giải trình

Mã hóa:

X = 2
O = 3
_ = 1

Chiến lược cấp cao của chúng tôi trước tiên là tạo ra một ma trận mỗi hàng có khả năng giành chiến thắng. Hàng một là đường chéo /, hàng 2 là đường chéo \, ba hàng tiếp theo là các hàng và ba hàng cuối cùng là các cột. Phần này được thực hiện bằng cụm từ (sử dụng Mục sửa đổi }):

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

Cuối cùng, chúng tôi lấy GCD của mỗi hàng:

+./"1

Nhờ mã hóa của chúng tôi, bất kỳ hàng nào có khoảng trống sẽ có GCD là 1, cũng như bất kỳ hàng nào có chứa bất kỳ kết hợp X và Os nào, bởi vì 2 và 3 là nguyên tố cùng nhau. Vì vậy, tất cả những gì chúng ta cần làm tiếp theo là tìm phần tử tối đa:>./

Nếu trò chơi là hòa, nó sẽ là 1. Nếu người chơi thắng, đó sẽ là số của người chơi đó.

Hãy thử trực tuyến!


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)

Giữ cho nó đơn giản.

  • Đầu vào: Một chuỗi hoặc mảng số hoặc chuỗi 0tương ứng với một khoảng trắng, 1X và2 O.
  • Đầu ra: 0cho một tie, 1cho chiến thắng X, 2cho chiến thắng O.

Mở rộng, nhận xét nhẹ:

( [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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.