Nhiệm vụ của bạn là thực hiện chiến lược Tetris cân bằng về điểm số và kích thước mã.
Trong phiên bản này, các tetrominoes của trò chơi được xoay và thả từ trên xuống thành một lưới gồm 20 hàng và 10 cột. Trong khi rơi, chúng không thể được xoay hoặc di chuyển theo chiều ngang. Như thường lệ, một mảnh rơi dừng lại khi nó chạm đến đáy của lưới hoặc khi chuyển động đi xuống tiếp theo sẽ gây ra va chạm với một hình vuông đã bị chiếm đóng.
Khi n
các đường ngang được lấp đầy hoàn toàn, chúng sụp đổ đồng thời, lưới được bổ sung với n
các đường trống ở trên cùng và điểm số được tăng thêm 2 n -1 điểm. Với n
= 1,2,3,4 tương ứng 1,3,7,15 điểm. Sau khi các dòng biến mất, một số khối có thể vẫn trôi nổi trong không khí (không có " phản ứng chuỗi trọng lực ").
Khi không có chỗ cho mảnh hiện tại xuất hiện ở nơi mong muốn, lưới sẽ bị xóa, mảnh hiện tại bị bỏ qua và trò chơi tiếp tục với mảnh tiếp theo như hiện tại. Không có hình phạt cho điều đó.
Bạn nên đọc một luồng các loại mảnh và quyết định làm thế nào để xoay chúng và nơi để thả chúng. Nhìn về phía trước cho mảnh tiếp theo (chỉ một) được cho phép: bạn có thể nhìn vào mảnh i+1
trước khi trả lời i
, nhưng bạn phải quyết định số phận i
trước khi nhìn vào i+2
. Không có cái nhìn phía trước có sẵn ngoài phần cuối cùng của đầu vào.
Các loại Tetromino và phép quay của chúng được mã hóa theo bảng sau:
type 0 1 2 3 4 5 6
O I Z J L S T
┌────┬────┬────┬────┬────┬────┬────┐
rotation 0 │## │# │## │ # │# │ ## │### │
│## │# │ ## │ # │# │## │ # │
│ │# │ │## │## │ │ │
│ │# │ │ │ │ │ │
├────┼────┼────┼────┼────┼────┼────┤
1 │## │####│ # │### │ # │# │# │
│## │ │## │ # │### │## │## │
│ │ │# │ │ │ # │# │
│ │ │ │ │ │ │ │
├────┼────┼────┼────┼────┼────┼────┤
2 │## │# │## │## │## │ ## │ # │
│## │# │ ## │# │ # │## │### │
│ │# │ │# │ # │ │ │
│ │# │ │ │ │ │ │
├────┼────┼────┼────┼────┼────┼────┤
3 │## │####│ # │# │### │# │ # │
│## │ │## │### │# │## │## │
│ │ │# │ │ │ # │ # │
│ │ │ │ │ │ │ │
└────┴────┴────┴────┴────┴────┴────┘
Đầu vào là nhị phân - một chuỗi các byte có phần dư khi chia cho 7 nên được hiểu là các OIZJLST
tetrominoes. Chúng sẽ xảy ra với cùng một xác suất (ngoại trừ một vài loại đầu tiên có thể xuất hiện thường xuyên hơn một chút do 256 không phải là bội số của 7, nhưng điều đó không đáng kể). Đầu vào có thể từ stdin hoặc từ một tệp có tên "i" hoặc được truyền dưới dạng đối số. Bạn có thể đọc tất cả các đầu vào cùng một lúc, miễn là bạn đảm bảo tuân thủ các hạn chế về phía trước.
Đầu ra cũng là nhị phân - một chuỗi các byte có cùng độ dài với đầu vào. Nó có thể là thiết bị xuất chuẩn hoặc tệp có tên "o" hoặc kết quả từ một chức năng. Mỗi byte mã hóa r*16 + x
, trong đó r
vòng quay mong muốn và x
là chỉ số dựa trên 0 của cột trong đó hình vuông ngoài cùng bên trái của tetromino được xoay sẽ đi. Những cái đó r
và x
phải hợp lệ, nghĩa là 0 ≤ r ≤ 3
, và 0 ≤ x ≤ 10-w
đâu w
là chiều rộng của mảnh tương ứng.
Chương trình của bạn phải có tính xác định - với cùng một đầu vào, nó phải tạo ra chính xác cùng một đầu ra. Sử dụng PRNG là được miễn là nó được tạo thành.
Tổng số điểm là số điểm từ trò chơi trừ đi kích thước mã của bạn tính bằng byte. Vui lòng sử dụng tệp sau (64kiB tiếng ồn giả ngẫu nhiên) làm đầu vào: https://gist.github.com/ngn/857bf2c99bfafc649b8eaa1e361e75e4/raw/880f29bd790638aa17f51229c105e7bb
Tập lệnh python2 / python3 sau đây đọc các tệp "i" và "o" từ thư mục hiện tại, phát lại trò chơi và in điểm số (vui lòng nhớ trừ kích thước mã của bạn khỏi điểm số):
a = [0] * 23 # grid (1square=1bit, 1row=1int, LSB is left, 3 empty rows on top)
# O I Z J L S T tetrominoes
t = [[[3,3],[1,1,1,1],[3,6], [2,2,3],[1,1,3],[6,3], [7,2] ],
[[3,3],[15], [2,3,1],[7,4], [4,7], [1,3,2],[1,3,1]],
[[3,3],[1,1,1,1],[3,6], [3,1,1],[3,2,2],[6,3], [2,7] ],
[[3,3],[15], [2,3,1],[1,7], [7,1], [1,3,2],[2,3,2]]]
tw = [[2,1,3,2,2,3,3],[2,4,2,3,3,2,2],[2,1,3,2,2,3,3],[2,4,2,3,3,2,2]] # widths
th = [[2,4,2,3,3,2,2],[2,1,3,2,2,3,3],[2,4,2,3,3,2,2],[2,1,3,2,2,3,3]] # heights
score = 0
for p, rx in zip(bytearray(open('i', 'rb').read()),
bytearray(open('o', 'rb').read())):
p %= 7; r = rx >> 4; x = rx & 15 # p:piece type, r:rotation, x:offset
b = [u << x for u in t[r][p]] # as a bit-matrix (list of ints)
bw = tw[r][p]; bh = th[r][p] # width and height
y = 0 # drop it
while y <= 23 - bh and all((a[y + i] & b[i]) == 0 for i in range(bh)):
y += 1
y -= 1
if y < 3: # no room?
a = [0] * len(a) # clear the grid and carry on
else:
for i in range(bh): # add the piece to the grid
a[y + i] |= b[i]
n = 0
for i in reversed(range(bh)): # collapse full lines
if a[y + i] == (1 << 10) - 1:
n += 1; del a[y + i]; a = [0] + a
score += (1 << n) - 1
print(score)
Chương trình C sau đây cũng nhanh hơn nhiều nhưng nó được đảm bảo chỉ hoạt động trên Linux:
#include<stdio.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/stat.h>
#define F(i,n,b...)for(i=0;i<n;i++){b;}
typedef int I;typedef char C;
I a[23],t[]={
51,4369,99,802,785,54,39,51,15,306,71,116,561,305,
51,4369,99,275,547,54,114,51,15,306,113,23,561,562};
C*th="2423322213223324233222132233";
I main(){
struct stat h;stat("i",&h);I i,j,k,l=h.st_size,z=0;
C*mi=mmap(0,l,1,1,open("i",0,0),0),*mo=mmap(0,l,1,1,open("o",0,0),0);
F(k,l,
I p=(mi[k]&255)%7,r=3&mo[k]>>4,q=r*7+p,x=mo[k]&15,y=0,h=th[q]-'0',b[4];
F(i,h,b[i]=(t[q]>>(4*i)&15)<<x)
while(y<=23-h){I u=0;F(i,h,u|=a[y+i]&b[i])if(u)break;y++;}
if(--y<3){F(i,23,a[i]=0)continue;}
F(i,h,a[y+i]|=b[i])
I n=0;F(i,23,n+=a[i]==1023)
if(n){j=23;F(i,20,a[j]=a[22-i];j-=a[j]!=1023)F(i,j,a[i]=0);z+=(1<<n)-1;})
printf("%d\n",z);return 0;}
Tổng số điểm cao nhất chiến thắng. Sơ hở tiêu chuẩn bị cấm.