Code Golf: Chơi Tetris


83

Những thứ cơ bản:

Hãy xem xét các tetrominoes và sân chơi trống sau:

                                            0123456789
    IOZTLSJ []
                                           []
    # ## ## ### # ## # []
    # ## ## # # # ## # []
    # ## ## []
    # []
                                           [==========]

Kích thước của sân chơi là cố định. Các số ở trên cùng chỉ ở đây để cho biết số cột (cũng xem đầu vào).

Đầu vào:

1 . Bạn được cung cấp một sân chơi cụ thể (dựa trên điều trên) có thể đã được lấp đầy một phần bằng các tetrominoes (điều này có thể nằm trong một tệp riêng hoặc được cung cấp qua stdin).

Đầu vào mẫu:

[]
[]
[]
[]
[# # #]
[## ######]
[==========]

2 . Bạn được cung cấp một chuỗi mô tả (được phân tách bằng dấu cách) mà tetromino để chèn (và thả xuống) tại cột nào. Tetrominoes không cần phải được xoay. Đầu vào có thể được đọc từ stdin.

Đầu vào mẫu:

T2 Z6 I0 T7

Bạn có thể giả định rằng đầu vào là 'được định dạng tốt' (hoặc tạo ra hành vi không xác định khi nó không phải).

Đầu ra

Hiển thị trường kết quả (các dòng 'đầy đủ' phải biến mất) và in số điểm (mỗi dòng bị rớt chiếm 10 điểm).

Đầu ra mẫu dựa trên đầu vào mẫu ở trên:

[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10

Người chiến thắng:

Giải pháp ngắn nhất (theo số ký tự mã). Các ví dụ sử dụng rất hay. Chúc bạn chơi gôn vui vẻ!

Chỉnh sửa : đã thêm một phần thưởng +500danh tiếng để thu hút thêm sự chú ý đến những nỗ lực tốt đẹp mà người trả lời đã thực hiện (và có thể là một số giải pháp mới cho câu hỏi này) ...


5
@omouse: kiểm tra meta.stackoverflow.com - golf đang thường cho phép (theo mẫu wiki cộng đồng)
ChristopheD

18
@omouse: Đó là những gì để đóng biểu quyết. Việc lôi kéo người kiểm duyệt ở đây bằng cách gắn cờ câu hỏi có lẽ sẽ không khiến bạn trở nên nổi tiếng, với điều kiện hết lần này đến lần khác cộng đồng đã (miễn cưỡng) cho phép chơi gôn mã tồn tại (xem thẻ mã gôn và các cuộc thảo luận meta; nó không có gì mới) .
Mark Peters

8
@omouse: Lạc đề! = spam. Ngay cả khi bạn không thể bỏ phiếu để đóng, thì cờ spam đó đã không được mời.
BoltClock

3
Tôi đang đợi một cuộc tham gia APL! Tôi sẽ đặt cược ông có thể làm điều đó trong 3,5 ký tự
n8wrl

3
Các kích thước phải được cố định, nhưng đầu vào mẫu và trường trống có chiều cao khác nhau. Chiều cao được cho là bao nhiêu?
Nabb

Câu trả lời:


27

GolfScript - 181 ký tự

Dòng mới là không cần thiết. Đầu ra là đầu ra tiêu chuẩn, mặc dù một số lỗi xuất hiện trong stderr.
\10nên thay bằng ký tự ASCII tương ứng để chương trình là 181 ký tự.

{):X!-{2B{" #"=}%X" ":f*+-1%}%:P;:>.{\!:F;>P{\(@{3&\(@.2$&F|:F;|}%\+}%\+F![f]P+:P
;}do;{"= "&},.,7^.R+:R;[>0="#"/f*]*\+}0"R@1(XBc_""~\10"{base}:B/3/~4*"nIOZTLSJR "
";:"*~;n%)n*~ 10R*+n*

I / O mẫu:

$ cat inp
[          ]
[          ]
[          ]
[          ]
[ #    #  #]
[ ## ######]
[==========]
T2 Z6 I0 T7
$ cat inp|golfscript tetris.gs 2>/dev/null
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10

Nén Tetromino:
Các miếng được lưu trữ dưới dạng ba chữ số 8 cơ số. Đây là một biểu diễn nhị phân đơn giản, ví dụ T=[7,2,0], S=[6,3,0], J=[2,2,3]. [1]được sử dụng cho Iphần trong nén, nhưng điều này được đặt rõ ràng thành [1,1,1,1]sau (tức là 4*trong mã). Tất cả các mảng này được nối thành một mảng duy nhất, mảng này được chuyển đổi thành một số nguyên và sau đó là một chuỗi (cơ số 126 để giảm thiểu các ký tự không in được, độ dài và không gặp phải utf8). Chuỗi này là rất ngắn: "R@1(XBc_".

Quá trình giải nén diễn ra đơn giản. Đầu tiên chúng tôi thực hiện chuyển đổi cơ sở 126, sau đó là chuyển đổi cơ sở 8 ( "~\10"{base}/tức là lặp lại "~\10"và thực hiện chuyển đổi cơ sở cho từng phần tử). Mảng kết quả được chia thành các nhóm 3, mảng cho Ilà fixed ( 3/~4*). Sau đó, chúng tôi chuyển đổi từng phần tử thành cơ số 2 và (sau khi loại bỏ số không) thay thế mỗi chữ số nhị phân bằng ký tự của chỉ số đó trong chuỗi " #"( 2base{" #"=}%...-1%- lưu ý rằng chúng tôi cần đảo ngược mảng nếu không 2sẽ trở thành "# "thay vì " #").

Định dạng
bảng / miếng, thả các miếng Bảng chỉ đơn giản là một mảng các chuỗi, mỗi chuỗi cho mỗi dòng. Ban đầu không có công việc nào được thực hiện về điều này, vì vậy chúng tôi có thể tạo nó với n/(đầu vào. Các quân cờ cũng là một mảng các chuỗi, được đệm bằng khoảng trắng ở bên trái cho vị trí X của chúng, nhưng không có dấu cách ở cuối. Các mảnh được thả xuống bằng cách đặt trước vào mảng và liên tục kiểm tra xem có va chạm hay không.

Kiểm tra va chạm được thực hiện bằng cách lặp lại tất cả các ký tự trong mảnh và so sánh với ký tự có cùng vị trí trên bàn cờ. Chúng tôi muốn coi #+ =#+ #là va chạm, vì vậy chúng tôi kiểm tra xem ((piecechar & 3) & boardchar) có phải là khác không. Trong khi thực hiện lặp lại này, chúng tôi cũng cập nhật (bản sao của) bảng với ((piecechar & 3) | boardchar), đặt giá trị chính xác cho các cặp #+ , + #, + [. Chúng tôi sử dụng bảng cập nhật này nếu có va chạm sau khi di chuyển quân cờ xuống hàng khác.

Loại bỏ các hàng đã lấp đầy khá đơn giản. Chúng tôi loại bỏ tất cả các hàng "= "&trả về false. Một hàng đã điền sẽ không có =hoặc , vì vậy kết hợp sẽ là một chuỗi trống, tương đương với sai. Sau đó, chúng tôi đếm số hàng đã bị loại bỏ, thêm số lượng vào điểm số và thêm vào đó nhiều "[ ... ]"s. Chúng tôi tạo điều này một cách nhỏ gọn bằng cách lấy hàng đầu tiên của lưới và thay thế #bằng .

Phần thưởng
Vì chúng tôi tính toán bảng trông như thế nào ở mỗi vị trí của quân cờ khi nó rơi xuống, chúng tôi có thể giữ chúng trên ngăn xếp thay vì xóa chúng! Với tổng cộng ba ký tự nhiều hơn, chúng ta có thể xuất ra tất cả các vị trí này (hoặc hai ký tự nếu chúng ta có các trạng thái bảng có khoảng cách đơn).

{):X!-{2B{" #"=}%X" ":f*+-1%}%:P;:>.{>[f]P+:P(!:F;{\(@{3&\(@.2$&F|:F;|}%\+}%\+F!}
do;{"= "&},.,7^.R+:R;[>0="#"/f*]*\+}0"R@1(XBc_""~\10"{base}:B/3/~4*"nIOZTLSJR "
";:"*~;n%)n*~ ]{n*n.}/10R*

Một số cuộc chơi gôn mã cực đoan đang diễn ra ngay tại đây (tôi không nghĩ rằng điều này có thể được thực hiện trong ít hơn 200 ký tự). Công việc tốt!
ChristopheD

8
Kinh ngạc. Tôi ước tôi hiểu GolfScript. Chờ đã ... không, tôi không.
P Daddy

26

Perl, 586 523 483 472 427 407 404 386 387 356 353 ký tự

(Cần Perl 5.10 cho //toán tử hoặc đã xác định ).

Lấy tất cả đầu vào từ stdin. Vẫn cần chơi gôn nghiêm túc.
Lưu ý rằng ^ Q đại diện cho ASCII 17 (DC1 / XON), ^ C đại diện cho ASCII 3 và ^ @ đại diện cho ASCII 0 (NUL).

while(<>){push@A,[split//]if/]/;while(/\w/g){for$i(0..6){for($f=0,$j=4;$j--;){$c=0;map{if($_){$i--,$f=$j=3,redo if$A[$k=$i+$j][$C=$c+$'+1]ne$";$A[$k][$C]="#"if$f}$c++}split//,unpack"b*",chr vec"3^@'^@c^@^Q^C6^@\"^C^Q^Q",index(OTZLSJI,$&)*4+$j,4;$s+=10,@A[0..$k]=@A[$k,0..$k-1],map{s/#/ /}@{$A[0]},$i++if 9<grep/#/,@{$A[$k]}}last if$f}}}print+(map@$_,@A),$s//0,$/

Phiên bản nhận xét:

while(<>){
    # store the playfield as an AoA of chars
    push@A,[split//]if/]/;
    # while we're getting pieces
    while(/\w/g){
            # for each line of playfield
            for$i(0..6){
                    # for each line of current piece
                    for($f=0,$j=4;$j--;){
                            # for each column of current piece
                            $c=0;
                            map{
                                    if($_){
                                            # if there's a collision, restart loop over piece lines
                                            # with a mark set and playfield line decremented
                                            $i--,$f=$j=3,redo if$A[$k=$i+$j][$C=$c+$'+1]ne$";
                                            # if we already found a collision, draw piece
                                            $A[$k][$C]="#"if$f
                                    }
                                    $c++
                            # pieces are stored as a bit vector, 16 bits (4x4) per piece,
                            # expand into array of 1's and 0's
                            }split//,unpack"b*",chr vec"3^@'^@c^@^Q^C6^@\"^C^Q^Q",index(OTZLSJI,$&)*4+$j,4;
                            # if this playfield line is full, remove it. Done by array slicing
                            # and substituting all "#"'s in line 0 with " "'s
                            $s+=10,@A[0..$k]=@A[$k,0..$k-1],map{s/#/ /}@{$A[0]},$i++if 9<grep/#/,@{$A[$k]}
                    }
                    # if we found a collision, stop iterating over the playfield and get next piece from input
                    last if$f
            }
    }
}
# print everything
print+(map@$_,@A),$s//0,$/

Chỉnh sửa 1: một số trò chơi gôn nghiêm trọng, sửa lỗi đầu ra.
Chỉnh sửa 2: một số nội tuyến, hợp nhất hai vòng thành một để tiết kiệm ròng (cuộn trống ...) 3 ký tự, chơi gôn sai.
Chỉnh sửa 3: một số loại bỏ biểu thức con phổ biến, hợp nhất liên tục một chút và điều chỉnh regex.
Chỉnh sửa 4: thay đổi biểu diễn của tetrominoes thành một vector bit được đóng gói, chơi gôn sai.
Chỉnh sửa 5: dịch trực tiếp hơn từ chữ tetromino sang chỉ mục mảng, sử dụng các ký tự không in được, chơi gôn sai.
Chỉnh sửa 6: sửa lỗi hàng đầu, được giới thiệu trong r3 (chỉnh sửa 2), được phát hiện bởi Nakilon. Sử dụng nhiều ký tự không thể in hơn.
Chỉnh sửa 7: sử dụng vecđể lấy dữ liệu tetromino. Tận dụng lợi thế của thực tế là sân chơi có kích thước cố định. iftuyên bố =>ifsửa đổi, việc hợp nhất các vòng của chỉnh sửa 2 bắt đầu có hiệu quả. Sử dụng //cho trường hợp 0 ​​điểm.
Chỉnh sửa 8: sửa một lỗi khác, được giới thiệu trong r6 (chỉnh sửa 5), ​​được phát hiện bởi Nakilon.
Chỉnh sửa 9: không tạo tham chiếu mới khi xóa các dòng, chỉ di chuyển tham chiếu xung quanh thông qua cắt mảng. Hợp nhất hai mapthành một. Regex thông minh hơn. "Thông minh hơn" for. Chơi gôn khác.
Chỉnh sửa 10: mảng tetromino nội tuyến, thêm phiên bản nhận xét.


Hoạt động rất tốt (và đã có số lượng ký tự tốt cho vấn đề không hề nhỏ này). Một điểm đặc biệt nhỏ là perl của tôi (perl, v5.10.0 được xây dựng cho darwin-thread-multi-2level) dường như in kết quả hai lần (đầu vào được đưa vào).
ChristopheD

@ChristopheD: đã sửa lỗi đầu ra trùng lặp, tôi đang in bên trong vòng lặp chính của mình, nhưng chỉ cho các dòng không có sân chơi. Bạn có thể có một dòng mới quá nhiều :)
ninjalj

4 ký tự nữa để đánh bại python !!
Vivin Paliath

1
Tôi vẫn chưa từ bỏ perl! xD (Mặc dù tôi muốn thấy một số giải pháp khác nữa bởi bây giờ ..)
chọc

@Nakilon: Bắt tốt! Bạn có một trường hợp thử nghiệm đẹp ở đó.
ninjalj

24

Ruby - 427 408 398 369 359

t=[*$<]
o=0
u=->f{f.transpose}
a=u[t.reverse.join.scan /#{'( |#)'*10}/]
t.pop.split.map{|w|m=(g='I4O22Z0121T01201L31S1201J13'[/#{w[0]}\d+/].scan(/0?\d/).zip a.drop w[1].to_i).map{|r,b|(b.rindex ?#or-1)-r.size+1}.max
g.map{|r,b|b.fill ?#,m+r.size,r.to_i}
v=u[a]
v.reject!{|i|i-[?#]==[]&&(o+=10;v)<<[' ']*10}
a=u[v]}
puts u[a].reverse.map{|i|?[+i*''+?]},t[-1],o

Giải pháp rất hay! Tôi sẽ phải xem xét cách bạn mã hóa chính xác các biểu mẫu terominoes (theo cách này trông rất nhỏ gọn).
ChristopheD

3
Tôi thực sự muốn xem giải thích mở rộng về mã này. Nó trông thật bệnh hoạn ... không thể xoay sở được.
Nils Riedemann

1
@Nils Riedemann, tôi viết lời giải thích ngay bây giờ, nhưng tôi đang nghĩ đến việc đăng nó ngay bây giờ hoặc sau khi người chiến thắng công bố) Dù sao thì một khi tôi sẽ đăng và trả lời tất cả các câu hỏi, bởi vì đó là một wiki cộng đồng với ý tưởng chính là hữu ích)
Nakilon

Trên ruby ​​1.9.2dev của Debian (2010-07-30), trường hợp thử nghiệm của bạn không thành công tại paste.org.ru/?6ep1on . Ngoài ra, nó luôn mở rộng sân chơi thành mười dòng?
ninjalj

@ninjalj, ruby ​​1.9.2p0 (2010-08-18) [i386-mingw32] paste.org.ru/?1qnjhj Trông ổn. Chiều rộng của 10 là một tiêu chuẩn Tetris, tôi cho là vậy.
Nakilon

17

Bash shell script ( 301 304 ký tự)


CẬP NHẬT: Đã sửa lỗi liên quan đến các mảnh kéo dài đến hàng trên cùng. Ngoài ra, kết quả đầu ra hiện được gửi đến chuẩn và như một phần thưởng, bạn có thể chạy lại tập lệnh để tiếp tục chơi trò chơi (trong trường hợp đó, bạn phải tự cộng tổng điểm).

Điều này bao gồm các ký tự không in được, vì vậy tôi đã cung cấp một kết xuất hex. Lưu nó dưới dạng tetris.txt:

0000000: 7461 696c 202d 3120 245f 7c7a 6361 743e  tail -1 $_|zcat>
0000010: 753b 2e20 750a 1f8b 0800 35b0 b34c 0203  u;. u.....5..L..
0000020: 5590 516b 8330 10c7 dff3 296e 4c88 ae64  U.Qk.0....)nL..d
0000030: a863 0c4a f57d 63b0 07f7 b452 88d1 b4da  .c.J.}c....R....
0000040: 1a5d 5369 91a6 df7d 899a d05d 5e72 bfbb  .]Si...}...]^r..
0000050: fbff 2fe1 45d5 0196 7cff 6cce f272 7c10  ../.E...|.l..r|.
0000060: 387d 477c c4b1 e695 855f 77d0 b29f 99bd  8}G|....._w.....
0000070: 98c6 c8d2 ef99 8eaa b1a5 9f33 6d8c 40ec  ...........3m.@.
0000080: 6433 8bc7 eeca b57f a06d 27a1 4765 07e6  d3.......m'.Ge..
0000090: 3240 dd02 3df1 2344 f04a 0d1d c748 0bde  2@..=.#D.J...H..
00000a0: 75b8 ed0f 9eef 7bd7 7e19 dd16 5110 34aa  u.....{.~...Q.4.
00000b0: c87b 2060 48a8 993a d7c0 d210 ed24 ff85  .{ `H..:.....$..
00000c0: c405 8834 548a 499e 1fd0 1a68 2f81 1425  ...4T.I....h/..%
00000d0: e047 bc62 ea52 e884 42f2 0f0b 8b37 764c  .G.b.R..B....7vL
00000e0: 17f9 544a 5bbd 54cb 9171 6e53 3679 91b3  ..TJ[.T..qnS6y..
00000f0: 2eba c07a 0981 f4a6 d922 89c2 279f 1ab5  ...z....."..'...
0000100: 0656 c028 7177 4183 2040 033f 015e 838b  .V.(qwA. @.?.^..
0000110: 0d56 15cf 4b20 6ff3 d384 eaf3 bad1 b9b6  .V..K o.........
0000120: 72be 6cfa 4b2f fb03 45fc cd51 d601 0000  r.l.K/..E..Q....

Sau đó, tại dấu nhắc lệnh bash, tốt hơn là với elvisthay vì vimcài đặt như vi:

$ xxd -r tetris.txt tetris.sh
$ chmod +x tetris.sh
$ cat << EOF > b
> [          ]
> [          ]
> [          ]
> [          ]
> [ #    #  #]
> [ ## ######]
> [==========]
> EOF
$ ./tetris.sh T2 Z6 I0 T7 2>/dev/null
-- removed stuff that is not in standard out --
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10

Làm thế nào nó hoạt động

Mã tự trích xuất tương tự như cách các chương trình thực thi được nén bằng gzexescript. Các mẩu Tetromino được biểu diễn dưới dạng chuỗi lệnh của trình soạn thảo vi. Đếm ký tự được sử dụng để phát hiện va chạm và đếm dòng được sử dụng để tính điểm.

Mã đã giải nén:

echo 'rej.j.j.:wq!m'>I
echo '2rejh.:wq!m'>O
echo '2rej.:wq!m'>Z
echo '3rejh1.:wq!m'>T
echo 'rej.j2.:wq!m'>L
echo 'l2rej2h.:wq!m'>S
echo 'lrej.jh2.:wq!m'>J
for t
do for y in `seq 1 5`
do echo -n ${y}jk$((${t:1}+1))l|cat - ${t:0:1}|vi b>0
grep ========== m>0||break
[ `tr -cd '#'<b|wc -c` = `tr -cd '#'<m|wc -c` ]||break
tr e '#'<m>n
done
cat n>b
grep -v '##########' b>m
$((S+=10*(`wc -l < b`-`wc -l < m`)))
yes '[          ]'|head -7|cat - m|tail -7>b
done
cat b
echo $S

Mã gốc trước khi chơi gôn:

#!/bin/bash

mkpieces() {
    pieces=('r@j.j.j.' '2r@jh.' '2r@j.' '3r@jh1.' 'r@j.j2.' 'l2r@j2h.' 'lr@j.jh2.')
    letters=(I O Z T L S J)

    for j in `seq 0 9`; do
        for i in `seq 0 6`; do
            echo "jk$(($j+1))l${pieces[$i]}:wq! temp" > ${letters[$i]}$j
        done
    done
}

counthashes() {
    tr -cd '#' < $1 | wc -c
}

droppiece() {
    for y in `seq 1 5`; do
        echo -n $y | cat - $1 | vi board > /dev/null
        egrep '={10}' temp > /dev/null || break
        [ `counthashes board` -eq `counthashes temp` ] || break
        tr @ "#" < temp > newboard
    done
    cp newboard board
}

removelines() {
    egrep -v '#{10}' board > temp
    SCORE=$(($SCORE + 10 * (`wc -l < board` - `wc -l < temp`)))
    yes '[          ]' | head -7 | cat - temp | tail -7 > board
}

SCORE=0
mkpieces
for piece; do
    droppiece $piece
    removelines
done
cat board
echo $SCORE

1
Một tệp bash, đang giải nén và đang chạy vi .. không chắc về tính hợp pháp của một thứ ghê tởm như vậy .. nhưng nó ấn tượng nhất, +1. kudo cho bạn thưa ngài.
Michael Anderson

Mất một thời gian dài để hoàn thành và sau đó tạo ra sai đầu ra cho trường hợp kiểm tra "T2 Z6 I0 T7 T2 Z6 T2 I5 I1 I0 T4 O8 T1 T6 T3 Z0 I9 I6 O7 T3 I2 O0 J8 L6 O7 O4 I3 J8 S6 O1 I0 O4 "(bảng giống như đầu vào ví dụ). Hơn nữa, hàng ngàn đường dây rác sẽ bị xáo trộn khi được đặt đường ống, và kết quả của bảng có lẽ sẽ đến đó.
Nabb

Sẽ nhanh hơn nhiều nếu Elvis được cài đặt thay vì Vim như vi.
PleaseStand

2
@Nabb: Tôi vừa khắc phục tất cả những vấn đề đó với chi phí chỉ có ba ký tự.
PleaseStand

Chà. Đó là một số lạm dụng bash khá ấn tượng.
P Daddy

13

Python: 504 519 ký tự

(Giải pháp Python 3) Hiện tại yêu cầu đặt đầu vào ở định dạng như được hiển thị ở trên cùng (mã đầu vào không được tính). Tôi sẽ mở rộng để đọc từ tệp hoặc stdin sau. Bây giờ hoạt động với một lời nhắc, chỉ cần dán đầu vào (tổng cộng 8 dòng).

R=range
f,p=[input()[1:11]for i in R(7)],p
for(a,b)in input().split():
 t=[' '*int(b)+r+' '*9for r in{'I':'#,#,#,#','O':'##,##','Z':'##, ##','T':'###, # ','L':'#,#,##','S':' ##,##','J':' #, #,##'}[a].split(',')]
 for r in R(6-len(t),0,-1):
  for i in R(len(t)):
   if any(a==b=='#'for(a,b)in zip(t[i],f[r+i])):break
  else:
   for i in R(0,len(t)):
    f[r+i]=''.join(a if b!='#'else b for(a,b)in zip(t[i],f[r+i]))
    if f[r+i]=='#'*10:del f[r+i];f[0:0]=[' '*10];p+=10
   break
print('\n'.join('['+r+']'for r in f[:7]),p,sep='\n')

Không chắc liệu tôi có thể tiết kiệm được nhiều hơn ở đó không. Khá nhiều ký tự bị mất từ ​​quá trình chuyển đổi thành trường bit, nhưng điều đó tiết kiệm được nhiều ký tự hơn là làm việc với chuỗi. Ngoài ra, tôi không chắc liệu mình có thể xóa thêm khoảng trắng ở đó hay không, nhưng tôi sẽ thử sau.
Sẽ không thể giảm nó nhiều hơn nữa; sau khi có giải pháp dựa trên trường bit, tôi đã chuyển đổi lại thành chuỗi, vì tôi đã tìm ra cách để nén nó nhiều hơn (lưu 8 ký tự trên trường bit!). Nhưng vì tôi đã quên bao gồm Lvà có một lỗi với số điểm bên trong, số lượng nhân vật của tôi chỉ tăng lên thở dài ... Có lẽ tôi tìm một cái gì đó sau đó để nén nó lại một chút, nhưng tôi nghĩ tôi gần cuối. Đối với mã gốc và mã nhận xét, hãy xem bên dưới:

Phiên bản gốc:

field = [ input()[1:11] for i in range(7) ] + [ 0, input() ]
# harcoded tetrominoes
tetrominoes = {'I':('#','#','#','#'),'O':('##','##'),'Z':('##',' ##'),'T':('###',' # '),'L':('#','#','##'),'S':(' ##','##'),'J':(' #',' #','##')}
for ( f, c ) in field[8].split():
    # shift tetromino to the correct column
    tetromino = [ ' ' * int(c) + r + ' ' * 9 for r in tetrominoes[f] ]

    # find the correct row to insert
    for r in range( 6 - len( tetromino ), 0, -1 ):
        for i in range( len( tetromino ) ):
            if any( a == b == '#' for (a,b) in zip( tetromino[i], field[r+i] ) ):
                # skip the row if some pieces overlap
                break
        else:
            # didn't break, insert the tetromino
            for i in range( 0, len( tetromino ) ):
                # merge the tetromino with the field
                field[r+i] = ''.join( a if b != '#' else b for (a,b) in zip( tetromino[i], field[r+i] ) )

                # check for completely filled rows
                if field[r+i] == '#' * 10:
                    # remove current row
                    del field[r+i]
                    # add new row
                    field[0:0] = [' '*10]
                    field[7] += 10
            # we found the row, so abort here
            break
# print it in the requested format
print( '\n'.join( '[' + r + ']' for r in field[:7] ) )
# and add the points = 10 * the number of redundant lines at the end
print( str( field[7] ) )

Tôi không nghĩ rằng điều này là chính xác. Không có quy tắc nào nói rằng chỉ dòng dưới cùng mới có thể biến mất, nhưng xét theo nhận xét của bạn, bạn chỉ kiểm tra dòng đó.
Michael Madsen

Vui lòng làm cho Đầu vào của bạn giống như trong một nhiệm vụ. Ý tôi là, nhập từ tệp hoặc STDIN.
Nakilon

6
Bạn có thích cách ngay cả mã Python được rút gọn vẫn có thể đọc được khá nhiều không?
EMP

@Evgeny, chỉ nếu đem so sánh với Perl hoặc Malbolge)
Nakilon

Ý tôi là "có thể đọc được" so với các câu trả lời chơi gôn mã khác!
EMP

13

Ruby 1.9, 357 355 353 339 330 310 309 ký tự

d=0
e=[*$<]
e.pop.split.map{|f|f="L\003\003\007J\005\005\007O\007\007Z\007\013S\013\007I\003\003\003\003T\017\005"[/#{f[j=0]}(\W*)/,1].bytes.map{|z|?\0+?\0*f[1].hex+z.to_s(2).tr("01"," #")[1,9]}
k,f,i=i,[p]+f,e.zip(f).map{|l,m|l.bytes.zip(m.to_s.bytes).map{|n,o|j|=n&3&q=o||0;(n|q).chr}*""}until j>0
e=[]
e+=k.reject{|r|r.sum==544&&e<<r.tr(?#,?\s)&&d+=10}}
puts e,d

Lưu ý rằng các phần \000thoát (bao gồm các byte rỗng trên dòng thứ ba) nên được thay thế bằng phần tương đương không in được thực tế của chúng.

Đầu vào mẫu:

[          ]
[          ]
[          ]
[          ]
[ #    #  #]
[ ## ######]
[==========]
T2 Z6 I0 T7

Sử dụng:

ruby1.9 tetris.rb < input

hoặc là

ruby1.9 tetris.rb input

Một cách khác để thả tetrominos và giữ tất cả thủy tinh trong mảng, thậm chí có đường viền ... đẹp. Bây giờ bạn sẽ là nhà lãnh đạo Ruby / Perl. Tái bút: Tôi không biết về ?\s.
Nakilon

12

C, 727 [...] 596 581 556 517 496 471 461 457 ký tự

Đây là lần chơi gôn mã đầu tiên của tôi, tôi nghĩ rằng số lượng ký tự có thể thấp hơn nhiều , sẽ rất tuyệt nếu những người chơi gôn có kinh nghiệm có thể cho tôi một số gợi ý.

Phiên bản hiện tại cũng có thể xử lý các sân chơi với các kích thước khác nhau. Đầu vào có thể có dấu ngắt dòng ở cả định dạng DOS / Windows và Unix.

Mã khá đơn giản trước khi tối ưu hóa, các tetrominoes được lưu trữ trong 4 số nguyên được hiểu là một mảng (7 * 3) x4 bit, sân chơi được lưu trữ nguyên trạng, các ô được bỏ và các dòng hoàn chỉnh bị xóa khi bắt đầu và sau mỗi gạch thả.

Tôi không chắc cách đếm các ký tự, vì vậy tôi đã sử dụng kích thước tệp của mã với tất cả các dấu ngắt dòng không cần thiết đã bị loại bỏ.

EDIT 596 => 581: Nhờ KitsuneYMG, mọi thứ ngoại trừ %lsgợi ý hoạt động hoàn hảo, ngoài ra, tôi nhận thấy putchthay vì putcharcó thể được sử dụng ( getchbằng cách nào đó không hoạt động) và loại bỏ tất cả các dấu ngoặc đơn trong #define G.

EDIT 581 => 556: Không hài lòng với vòng lặp còn lại forvà lồng nhau F, vì vậy có một số hợp nhất, thay đổi và loại bỏ các vòng lặp, khá khó hiểu nhưng chắc chắn đáng giá.

EDIT 556 => 517: Cuối cùng đã tìm ra cách tạo amảng int. Một số N;hợp nhất với c, không breakcòn nữa.

EDIT 496 => 471: Chiều rộng chiều cao của sân chơi đã được cố định ngay bây giờ.

EDIT 471 => 461: Các sửa đổi nhỏ, putcharđược sử dụng lại như putchkhông có chức năng tiêu chuẩn.

CHỈNH SỬA: Sửa lỗi, các dòng hoàn chỉnh đã bị xóa trước khi thả ô thay vì sau đó , vì vậy các dòng hoàn chỉnh có thể được để lại ở cuối. Sửa không thay đổi số lượng ký tự.

#define N (c=getchar())
#define G T[j%4]&1<<t*3+j/4
#define X j%4*w+x+j/4
#define F(x,m) for(x=0;x<m;x++)
#define W while
T[]={916561,992849,217,1},C[99],c,i,j,s,t,x,A,a[99],w=13;
main(){F(j,7)C["IJLSTZO"[j]]=j;
F(j,91)a[j]=N;
W(N>w){t=C[c];x=N-86;
W(c){F(j,12)if(G&&X>1?a[X]-32:0)c=0;
F(j,12)if(G&&X>w&&!c)a[X-w]=35;x+=w;}N;
F(i,6){A=0;t=i*w;F(x,w)A|=(a[t+x]==32);
if(!A){s++;F(j,t)a[t+w-j]=a[t-j];
x=1;W(a[x]-93)a[x++]=32;}}}
F(i,91)putchar(a[i]);printf("%i0",s);}

1
Bạn không thể định nghĩa for#define F(x,m) for(x=0;x++<m;)? Nó hoạt động trên C # ...: P
BrunoLM

@BrunoLM: Cảm ơn, nhưng điều này sẽ không hoạt động, fe sẽ F(x,3){printf("%i",x}in 12thay vì 012thay đổi này. Có thể thay đổi để for(x=-1;x++<m;), nhưng điều này không tiết kiệm bất cứ điều gì :)
schnaader

1
Nếu bạn đã viết mã chính xác, nếu bạn biên dịch dưới dạng C, bạn không cần phải bao gồm stdio.h (trừ khi tôi bỏ sót điều gì đó?). Lưu một vài ký tự :)

1
Bạn có thể thay thế định nghĩa của N bằng (c=getchar())và xóa tất cả c = N dòng lưu 6 ký tự. Trừ khi tôi sai về điều này, bạn sẽ nhận được t xuống 585
KitsuneYMG

1
kiểu mặc định cho int cũng cho các biến, ít nhất là cho C89.
ninjalj

8

Python 2.6+ - 334 322 316 ký tự

397 368 366 ký tự không nén

#coding:l1
exec'xÚEPMO!½ï¯ i,P*Ýlš%ì­‰=‰Ö–*†­þz©‰:‡—Lò¾fÜ”bžAù,MVi™.ÐlǃwÁ„eQL&•uÏÔ‹¿1O6ǘ.€LSLÓ’¼›î”3òšL¸tŠv[ѵl»h;ÁºŽñÝ0Àë»Ç‡ÛûH.ª€¼âBNjr}¹„V5¾3Dë@¼¡•gO. ¾ô6 çÊsÃЮürÃ1&›ßVˆ­ùZ`Ü€ÿžcx±ˆ‹sCàŽ êüRô{U¯ZÕDüE+³ŽFA÷{CjùYö„÷¦¯Î[0þøõ…(Îd®_›â»E#–Y%’›”ëýÒ·X‹d¼.ß9‡kD'.decode('zip')

Một dòng mới là bắt buộc và tôi đã tính nó là một ký tự.

Mumbo jumbo trên trang mã của trình duyệt có thể ngăn sao chép và dán thành công mã này, vì vậy bạn có thể tùy chọn tạo tệp từ mã này:

s = """
23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 45 50 4D 4F 03 21
10 BD EF AF 20 69 2C 50 2A 02 DD 6C 9A 25 EC AD 07 8D 89 07 3D 89 1C D6
96 2A 86 05 02 1B AD FE 7A A9 89 3A 87 97 4C F2 BE 66 DC 94 62 9E 41 F9
2C 4D 56 15 69 99 0F 2E D0 6C C7 83 77 C1 16 84 65 51 4C 26 95 75 CF 8D
1C 15 D4 8B BF 31 4F 01 36 C7 98 81 07 2E 80 4C 53 4C 08 D3 92 BC 9B 11
EE 1B 10 94 0B 33 F2 9A 1B 4C B8 74 8A 9D 76 5B D1 B5 6C BB 13 9D 68 3B
C1 BA 8E F1 DD 30 C0 EB BB C7 87 DB FB 1B 48 8F 2E 1C AA 80 19 BC E2 42
4E 6A 72 01 7D B9 84 56 35 BE 33 44 8F 06 EB 40 BC A1 95 67 4F 08 2E 20
BE F4 36 A0 E7 CA 73 C3 D0 AE FC 72 C3 31 26 9B DF 56 88 AD F9 5A 60 DC
80 FF 9E 63 78 B1 88 8B 73 43 E0 8E A0 EA FC 52 F4 7B 55 8D AF 5A 19 D5
44 FC 45 2B B3 8E 46 9D 41 F7 7B 43 6A 12 F9 59 F6 84 F7 A6 01 1F AF CE
5B 30 FE F8 F5 85 28 CE 64 AE 5F 9B E2 BB 45 23 96 59 25 92 9B 94 EB FD
10 D2 B7 58 8B 64 BC 2E DF 39 87 6B 44 27 2E 64 65 63 6F 64 65 28 27 7A
69 70 27 29
"""

with open('golftris.py', 'wb') as f:
    f.write(''.join(chr(int(i, 16)) for i in s.split()))

Thử nghiệm

intetris

[]
[]
[]
[]
[# # #]
[## ######]
[==========]
T2 Z6 I0 T7

Dòng mới phải là kiểu Unix (chỉ dành cho dòng). Một dòng mới ở cuối dòng cuối cùng là tùy chọn.

Để kiểm tra:

> python golftris.py <intetris
[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10

Mã này giải nén mã gốc và thực thi nó với exec. Mã được giải nén này nặng 366 ký tự và trông giống như sau:

import sys
r=sys.stdin.readlines();s=0;p=r[:1];a='[##########]\n'
for l in r.pop().split():
 n=int(l[1])+1;i=0xE826408E26246206601E>>'IOZTLSJ'.find(l[0])*12;m=min(zip(*r[:6]+[a])[n+l].index('#')-len(bin(i>>4*l&31))+3for l in(0,1,2))
 for l in range(12):
  if i>>l&2:c=n+l/4;o=m+l%4;r[o]=r[o][:c]+'#'+r[o][c+1:]
 while a in r:s+=10;r.remove(a);r=p+r
print''.join(r),s

Dòng mới là bắt buộc và mỗi dòng là một ký tự.

Đừng cố đọc mã này. Các tên biến được chọn ngẫu nhiên theo nghĩa đen để tìm kiếm độ nén cao nhất (với các tên biến khác nhau, tôi thấy có tới 342 ký tự sau khi nén). Một phiên bản dễ hiểu hơn sau:

import sys

board = sys.stdin.readlines()
score = 0
blank = board[:1] # notice that I rely on the first line being blank
full  = '[##########]\n'

for piece in board.pop().split():
    column = int(piece[1]) + 1 # "+ 1" to skip the '[' at the start of the line

    # explanation of these three lines after the code
    bits = 0xE826408E26246206601E >> 'IOZTLSJ'.find(piece[0]) * 12
    drop = min(zip(*board[:6]+[full])[column + x].index('#') -
               len(bin(bits >> 4 * x & 31)) + 3 for x in (0, 1, 2))

    for i in range(12):
        if bits >> i & 2: # if the current cell should be a '#'
            x = column + i / 4
            y = drop + i % 4
            board[y] = board[y][:x] + '#' + board[y][x + 1:]

    while full in board:      # if there is a full line,
        score += 10           # score it,
        board.remove(full)    # remove it,
        board = blank + board # and replace it with a blank line at top
        
print ''.join(board), score

Điểm mấu chốt nằm ở ba dòng khó hiểu mà tôi đã nói là tôi sẽ giải thích.

Hình dạng của các tetrominoes được mã hóa bằng số thập lục phân ở đó. Mỗi tetronimo được coi là chiếm một lưới ô 3x4, trong đó mỗi ô trống (dấu cách) hoặc đầy (dấu số). Mỗi phần sau đó được mã hóa bằng 3 chữ số thập lục phân, mỗi chữ số mô tả một cột 4 ô. Các chữ số có nghĩa nhỏ nhất mô tả các cột ngoài cùng bên trái và bit có nghĩa nhỏ nhất trong mỗi chữ số mô tả ô trên cùng trong mỗi cột. Nếu một bit là 0, thì ô đó trống, nếu không thì đó là '#'. Ví dụ: I tetronimo được mã hóa 00F, với bốn bit của chữ số có nghĩa nhỏ nhất được thiết lập để mã hóa bốn dấu hiệu số ở cột ngoài cùng bên trái và chữ T131, với bit trên cùng được đặt ở bên trái và bên phải, và hai bit trên cùng được đặt ở giữa.

Toàn bộ số thập lục phân sau đó được dịch chuyển một bit sang trái (nhân với hai). Điều này sẽ cho phép chúng tôi bỏ qua bit dưới cùng. Tôi sẽ giải thích lý do tại sao trong một phút.

Vì vậy, với phần hiện tại từ đầu vào, chúng tôi tìm chỉ mục trong số thập lục phân này, nơi 12 bit mô tả hình dạng của nó bắt đầu, sau đó chuyển nó xuống để các bit 1–12 (bỏ qua bit 0) của bitsbiến mô tả phần hiện tại.

Nhiệm vụ dropxác định có bao nhiêu hàng từ trên cùng của lưới mà mảnh sẽ rơi xuống trước khi hạ cánh trên các mảnh mảnh khác. Dòng đầu tiên cho biết có bao nhiêu ô trống ở đầu mỗi cột của sân chơi, trong khi dòng thứ hai tìm ô bị chiếm thấp nhất trong mỗi cột của quân cờ. Các zipchức năng trả về một danh sách các hàng, trong đó mỗi tuple bao gồm các n th tế bào từ mỗi mục trong danh sách đầu vào. Vì vậy, sử dụng bảng nhập liệu mẫu, zip(board[:6] + [full])sẽ trả về:

[
 ('[', '[', '[', '[', '[', '[', '['),
 (' ', ' ', ' ', ' ', ' ', ' ', '#'),
 (' ', ' ', ' ', ' ', '#', '#', '#'),
 (' ', ' ', ' ', ' ', ' ', '#', '#'),
 (' ', ' ', ' ', ' ', ' ', ' ', '#'),
 (' ', ' ', ' ', ' ', ' ', '#', '#'),
 (' ', ' ', ' ', ' ', ' ', '#', '#'),
 (' ', ' ', ' ', ' ', '#', '#', '#'),
 (' ', ' ', ' ', ' ', ' ', '#', '#'),
 (' ', ' ', ' ', ' ', ' ', '#', '#'),
 (' ', ' ', ' ', ' ', '#', '#', '#'),
 (']', ']', ']', ']', ']', ']', ']')
]

Chúng tôi chọn bộ từ danh sách này tương ứng với cột thích hợp và tìm chỉ mục của bộ đầu tiên '#'trong cột. Đây là lý do tại sao chúng tôi đã thêm một hàng "đầy đủ" trước khi gọi zip, để hàng đó indexsẽ có giá trị trả về hợp lý (thay vì đưa ra một ngoại lệ) khi cột này trống.

Sau đó, để tìm giá trị thấp nhất '#'trong mỗi cột của mảnh, chúng ta dịch chuyển và che dấu bốn bit mô tả cột đó, sau đó sử dụng binhàm để biến nó thành một chuỗi đơn vị và số không. Các binchức năng chỉ trả về bit có ý nghĩa, vì vậy chúng ta chỉ cần tính toán chiều dài của chuỗi này để tìm các tế bào bị chiếm đóng thấp nhất (hầu hết có ý nghĩa thiết lập bit). Các binchức năng cũng prepends '0b', vì vậy chúng ta phải trừ đó. Chúng tôi cũng bỏ qua bit ít quan trọng nhất. Đây là lý do tại sao số thập lục phân bị dịch chuyển sang trái một bit. Điều này là để giải thích cho các cột trống, mà các biểu diễn chuỗi sẽ có cùng độ dài với một cột chỉ có ô trên cùng đầy (chẳng hạn như phần T ).

Ví dụ, các cột của tôi tetromino, như đã đề cập trước đó, là F, 0, và 0. bin(0xF)'0b1111'. Sau khi bỏ qua '0b', chúng ta có độ dài là 4, đúng. Nhưng bin(0x0)0b0. Sau khi bỏ qua '0b', chúng ta vẫn có độ dài là '1, điều này không chính xác. Để giải thích cho điều này, chúng tôi đã thêm một bit bổ sung vào cuối, để chúng tôi có thể bỏ qua bit không quan trọng này. Do đó, +3đoạn mã có trong đó để tính độ dài thừa được chiếm bởi '0b'phần đầu và bit không đáng kể ở phần cuối.

Tất cả điều này xảy ra trong một biểu thức trình tạo cho ba cột ( (0,1,2)) và chúng tôi lấy minkết quả để tìm số hàng tối đa mà mảnh có thể thả xuống trước khi nó chạm vào bất kỳ cột nào trong ba cột.

Phần còn lại sẽ khá dễ hiểu bằng cách đọc mã, nhưng forvòng lặp sau các nhiệm vụ này sẽ thêm phần vào bảng. Sau đó, whilevòng lặp loại bỏ các hàng đầy đủ, thay thế chúng bằng các hàng trống ở trên cùng và tính điểm. Vào cuối, bảng và điểm số được in ra đầu ra.


6

Python, 298 ký tự

Đánh bại tất cả các giải pháp ngôn ngữ không bí truyền cho đến nay (Perl, Ruby, C, bash ...)


... và thậm chí không sử dụng mật khẩu nén mã.

import os
r=os.read
b='[%11c\n'%']'*99+r(0,91)
for k,v in r(0,99).split():
    t=map(ord,' -:G!.:; -:; !-.!"-. !". !./')['IJLOSTZ'.find(k)*4:][:4];v=int(v)-31
    while'!'>max(b[v+j+13]for j in t):v+=13
    for j in t:b=b[:v+j]+'#'+b[v+j+1:]
    b=b.replace('[##########]\n','')
print b[-91:],1060-10*len(b)/13

Trong ví dụ thử nghiệm

[          ]
[          ]
[          ]
[          ]
[ #    #  #]
[ ## ######]
[==========]
T2 Z6 I0 T7

nó xuất ra

[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10

Tái bút. sửa một lỗi do Nakilon chỉ ra với chi phí +5


Đó là một số mã khá ấn tượng. Sẽ mất thêm 14 ký tự để sửa nó ( ideone.com/zeuYB ), trừ khi có cách tốt hơn, nhưng thậm chí vẫn đánh bại mọi thứ trừ GolfScript và Bash. Đó chắc chắn là một giải pháp thông minh.
P Daddy

Vâng, hoàn toàn là một giải pháp rất tốt!
ChristopheD

@Nakilon: cảm ơn, rõ ràng đã bỏ lỡ điều đó. cố định @ giá 293-> 298
Nas Banov

@P Daddy, cảm ơn - tôi tìm thấy một cách để mang lại việc sửa chữa dưới bash & toolchain để giữ cho tôi lương thiện khi nói "tất cả các phi bí truyền" :)
Nas Banov

@Nabb: để giữ cho mã ngắn hơn, nó đã được viết với một số hạn chế. một cái gì đó như tối đa 33 tetrominos và 99 dòng giảm tối đa. Có thể dễ dàng gia hạn với giá +3. Hoặc với một mức giá thấp - thấp :), những hạn chế có thể được dỡ bỏ hoàn toàn. BTW, đây là một ví dụ tuyệt vời về cách có một bộ kiểm tra sẽ làm rõ spec (những gì tôi đã nghe lén ChristopherD trong ý kiến)
Nas Banov

5

Golfscript 260 ký tự

Tôi chắc rằng điều này có thể được cải thiện, tôi là người mới đối với Golfscript.

[39 26.2/0:$14{.(}:?~1?15?1?14 2??27?13.!14?2?27?14 1]4/:t;n/)\n*:|;' '/-1%.,:c;~{)18+:&;'XIOZTLSJX'\%~;,1-t\={{.&+.90>{;.}*|\=32=!{&13-:&;}*}%}6*{&+}/|{\.@<'#'+\)|>+}4*{'['\10*']'++}:
;n/0\~n+:|;0\{.'#'
={;)}{n+|+:|;}if\.}do;' '
n+\.@*|+\$+:$;.,1-<:|;}c*|n?$*

Cuối dòng có liên quan (không nên có một dòng ở cuối). Dù sao, đây là một số trường hợp thử nghiệm tôi đã sử dụng:

> cat init.txt 
[]
[]
[]
[]
[# # #]
[## ######]
[==========]
T2 Z6 I0 T7> cat init.txt | ruby golfscript.rb tetris.gsc
[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10

> cat init.txt
[]
[]
[]
[]
[# # #]
[## #####]
[==========]
I0 O7 Z1 S4> cat init.txt | ruby golfscript.rb tetris.gsc
[]
[]
[]
[#]
[### ####]
[### #####]
[==========]
10

> cat init.txt
[]
[]
[]
[## ###]
[# #]
[## ######]
[==========]
T7 I0 I3> cat init.txt | ruby golfscript.rb tetris.gsc
[]
[]
[]
[]
[# #]
[## # # #]
[==========]
20

Lưu ý rằng không có cuối dòng trong tệp đầu vào, một dòng cuối sẽ phá vỡ tập lệnh.


2
/ tôi coi GolfScript không phải là một ngôn ngữ thi đúng ... Nó chỉ là một thư viện, hình thẳng đến nhiệm vụ golf ... kích thước của thư viện này có thể được thêm vào kích thước của mã golfscript ...
Nakilon

4
@Nakilon - Bạn không thể nói điều gì đó tương tự về bất cứ thứ gì không được viết bằng ngôn ngữ máy thô? :) Trình thông dịch Python chỉ là một thư viện, hãy thêm kích thước của nó vào mục nhập của bạn. </sarcasm>
bta

2
@Nakilon: đó chỉ là thông dịch viên. Nó có thể được viết bằng bất kỳ ngôn ngữ nào khác; bạn vẫn sẽ nói rằng Golfscript không phải là một ngôn ngữ thực?
Michael Foukarakis

1
@Nabb: Cảm ơn, tôi nghĩ rằng có một số thủ thuật tôi đã bỏ qua ... Đừng cảm thấy tồi tệ, tôi cũng không hiểu mã của mình :).
coderaj

1
@Michael Foukarakis, trong 1 phút nữa tôi có thể viết thông dịch viên của riêng mình để giải quyết công việc này trong một ký tự, vậy thì sao?
Nakilon

4

O'Caml 809 782 ký tự

open String let w=length let c s=let x=ref 0in iter(fun k->if k='#'then incr x)s;!x open List let(@),g,s,p,q=nth,ref[],ref 0,(0,1),(0,2)let l=length let u=Printf.printf let rec o x i j=let a=map(fun s->copy s)!g in if snd(fold_left(fun(r,k)(p,l)->let z=c(a@r)in blit(make l '#')0(a@r)(i+p)l;if c(a@r)=z+l then r+1,k else r,false)(j-l x+1,true)x)then g:=a else o x i(j-1)and f x=let s=read_line()in if s.[1]='='then g:=rev x else f(sub s 1 10::x)let z=f [];read_line();;for i=0to w z/3 do o(assoc z.[i*3]['I',[p;p;p;p];'O',[q;q];'Z',[q;1,2];'T',[0,3;1,1];'L',[p;p;q];'S',[1,2;q];'J',[1,1;1,1;q]])(Char.code z.[i*3+1]-48)(l!g-1);let h=l!g in g:=filter(fun s->c s<>w s)!g;for i=1to h-(l!g)do incr s;g:=make 10' '::!g done;done;iter(fun r->u"[%s]\n"r)!g;u"[==========]\n";u"%d\n"(!s*10)

4

Lisp chung 667 657 645 ký tự

Lần đầu tiên tôi chơi golf mã, nên có lẽ còn nhiều thủ thuật mà tôi chưa biết. Tôi để lại một số dòng mới ở đó để giữ một số "khả năng đọc" còn lại (tôi tính các dòng mới là 2 byte, vì vậy việc xóa 6 dòng mới không cần thiết sẽ thu được thêm 12 ký tự).

Trong đầu vào, đầu tiên đặt các hình dạng sau đó đặt trường.

(let(b(s 0)m(e'(0 1 2 3 4 5 6 7 8 9)))
(labels((o(p i)(mapcar(lambda(j)(+ i j))p))(w(p r)(o p(* 13 r)))(f(i)(find i b))
(a(&aux(i(position(read-char)"IOZTLSJ")))(when i(push(o(nth i'((0 13 26 39)(0 1 13 14)(0 1 14 15)(0 1 2 14)(0 13 26 27)(1 2 13 14)(1 14 26 27)))(read))m)(a))))
(a)(dotimes(i 90)(if(find(read-char)"#=")(push i b)))(dolist(p(reverse m))
(setf b`(,@b,@(w p(1-(position-if(lambda(i)(some #'f(w p i)))e)))))
(dotimes(i 6)(when(every #'f(w e i))(setf s(1+ s)b(mapcar(lambda(k)(+(if(>(* 13 i)k)13(if(<=(* 13(1+ i))k)0 78))k))b)))))
(dotimes(i 6)(format t"[~{~:[ ~;#~]~}]
"(mapcar #'f(w e i))))(format t"[==========]
~a0"s)))

Thử nghiệm

T2 Z6 I0 T7
[          ]
[          ]
[          ]
[          ]
[ #    #  #]
[ ## ######]
[==========]
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10
NIL

Không quá ngắn, nhưng +1 cho sự xấu xí! Tôi tưởng tượng rằng đó là món súp bảng chữ cái sẽ trông như thế nào nếu nó đi kèm với dấu ngoặc đơn.
P Daddy

@P Daddy: Cảm ơn. Vâng, đó có thể là cách nó sẽ như thế nào :).
lpetru

2

Ruby 505 479 474 442 439 426 ký tự

Một nỗ lực đầu tiên. Đã làm điều đó với IronRuby. Tôi chắc rằng nó có thể được cải thiện, nhưng tôi thực sự nên hoàn thành một số công việc hôm nay!

p,q,r,s=(0..9),(0..2),(0..6),0
t=[*$<]
f=p.map{|a|g=0;r.map{|b|g+=2**b if t[6-b][a+1]==?#};g}
t.pop.split.map{|x|w,y=[15,51,306,562,23,561,113]["IOZTLSJ"=~/#{x[0]}/],x[1].to_i
l=q.map{|d|r.inject{|b,c|f[d+y]&(w>>(d*4)&15-c+1)>0?c:b}}.max
q.map{|b|f[b+y]|=w>>(b*4)&15-l}
r.map{i=f.inject{|a,b|a&b};f.map!{|a|b=i^(i-1);a=((a&~b)>>1)+(a&(b>>1))};s+=i>0?10:0}}
p.map{|a|r.map{|b|t[6-b][a+1]=f[a]&2**b>0??#:' '}}
puts t,s

Thử nghiệm

cat test.txt | ruby tetris.rb
[          ]
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10

Chỉnh sửa Bây giờ bằng cách sử dụng ruby ​​bình thường. Có đầu ra tường ..


Thêm một Rubist nữa, hay lắm! Nhưng hãy làm một tấm kính xung quanh những viên gạch.
Nakilon

1

Một cái khác trong Ruby, 573 546 ký tự

: **

Z={I:?#*4,J:'#,###',L:'###,#',O:'##,##',S:'#,##, #',Z:' #,##,#',T:' #,##, #'}
t=[*$<]
R=->s{s.reverse}
T=->m{m.transpose}
a = T[R[t].join.scan /.#{'(\D)'*10}.$/]
t.pop.split.each{|z|
t,o=Z[z[0].to_sym].split(',').map{|x|x.split //},z[1].to_i
r=0..t.size-1
y=r.map{|u|1+a[o+u].rindex(?#).to_i-t[u].count(' ')}.max
(0..3).each{|i|r.each{|j|t[j][i]==?#&&a[o+j][y+i]=t[j][i]}}}
s=0
a.each{|x|s=a.max_by(&:size).size;x[s-=1]||=' 'while s>0}
a=R[T[a].reject{|x|x*''=~/[#]{10}/&&s+=10}.map{|x|?[+x*''+?]}[0..6]]
puts (0..8-a.size).map{?[+' '*10+?]},a,s

Thử nghiệm:

cat test.txt | ruby 3858384_tetris.rb
[          ]
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10

Cố định vớia.each{|x|s=a.max_by(&:size).size;x[s-=1]||=' 'while s>0}
glebm
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.