งานของคุณคือการใช้กลยุทธ์ Tetris ที่สมดุลในแง่ของคะแนนเทียบกับขนาดรหัส
ในเกม tetrominoes รุ่นนี้จะหมุนและวางจากด้านบนลงในตาราง 20 แถวและ 10 คอลัมน์ ในขณะที่ตกลงมาพวกเขาจะไม่สามารถหมุนหรือเคลื่อนที่ในแนวนอนได้ ตามปกติชิ้นส่วนที่ถูกปล่อยจะหยุดลงเมื่อถึงด้านล่างของกริดหรือเมื่อการเคลื่อนที่ลงไปอีกจะทำให้เกิดการชนกับสี่เหลี่ยมที่มีอยู่แล้ว
เมื่อn
เส้นแนวนอนได้รับการเติมเต็มอย่างสมบูรณ์พวกเขาจะยุบพร้อมกันตารางจะถูกเติมเต็มด้วยn
เส้นว่างที่ด้านบนและคะแนนจะเพิ่มขึ้น 2 n -1 จุด สำหรับn
= 1,2,3,4 นั่นคือ 1,3,7,15 คะแนนตามลำดับ หลังจากเส้นหายไปบางช่วงตึกอาจลอยอยู่ในอากาศ (ไม่มี " ปฏิกิริยาลูกโซ่แรงโน้มถ่วง ")
เมื่อไม่มีห้องว่างสำหรับชิ้นส่วนปัจจุบันที่จะปรากฏในตำแหน่งที่ต้องการกริดจะถูกล้างชิ้นส่วนปัจจุบันจะถูกละเว้นและเกมจะดำเนินการต่อโดยชิ้นส่วนถัดไปเป็นปัจจุบัน ไม่มีโทษสำหรับเรื่องนั้น
คุณควรอ่านประเภทของชิ้นส่วนและตัดสินใจว่าจะหมุนมันอย่างไรและจะวางที่ไหน มองไปข้างหน้าสำหรับชิ้นส่วนถัดไป (เพียงหนึ่ง) ที่ได้รับอนุญาต: คุณสามารถดูที่ชิ้นi+1
ก่อนที่จะตอบi
แต่คุณจะต้องได้ตัดสินใจชะตากรรมของก่อนที่จะมองหาที่i
i+2
ไม่มีการค้นหาล่วงหน้านอกเหนือจากส่วนสุดท้ายของอินพุต
ประเภท Tetromino และการหมุนจะถูกเข้ารหัสตามตารางต่อไปนี้:
type 0 1 2 3 4 5 6
O I Z J L S T
┌────┬────┬────┬────┬────┬────┬────┐
rotation 0 │## │# │## │ # │# │ ## │### │
│## │# │ ## │ # │# │## │ # │
│ │# │ │## │## │ │ │
│ │# │ │ │ │ │ │
├────┼────┼────┼────┼────┼────┼────┤
1 │## │####│ # │### │ # │# │# │
│## │ │## │ # │### │## │## │
│ │ │# │ │ │ # │# │
│ │ │ │ │ │ │ │
├────┼────┼────┼────┼────┼────┼────┤
2 │## │# │## │## │## │ ## │ # │
│## │# │ ## │# │ # │## │### │
│ │# │ │# │ # │ │ │
│ │# │ │ │ │ │ │
├────┼────┼────┼────┼────┼────┼────┤
3 │## │####│ # │# │### │# │ # │
│## │ │## │### │# │## │## │
│ │ │# │ │ │ # │ # │
│ │ │ │ │ │ │ │
└────┴────┴────┴────┴────┴────┴────┘
อินพุตเป็นไบนารี - ลำดับของไบต์ที่มีเศษเหลือเมื่อหารด้วย 7 ควรตีความว่าเป็นOIZJLST
tetrominoes พวกเขาจะเกิดขึ้นโดยมีความน่าจะเป็นแบบเดียวกัน (ยกเว้นว่าสองสามประเภทแรกอาจปรากฏขึ้นบ่อยขึ้นเนื่องจาก 256 ไม่ได้เป็นหลายตัวจาก 7 แต่ควรจะเล็กน้อย) อินพุตอาจมาจาก stdin หรือจากไฟล์ชื่อ "i" หรือส่งผ่านเป็นอาร์กิวเมนต์ คุณสามารถอ่านอินพุตทั้งหมดได้ในครั้งเดียวหากคุณแน่ใจว่าได้ปฏิบัติตามข้อ จำกัด การดูล่วงหน้า
เอาท์พุทเป็นแบบไบนารีเช่นกัน - ลำดับของไบต์ที่มีความยาวเท่ากันกับอินพุต มันอาจเป็น stdout หรือไฟล์ชื่อ "o" หรือผลลัพธ์จากฟังก์ชั่น แต่ละไบต์เข้ารหัสr*16 + x
ซึ่งr
เป็นการหมุนที่ต้องการและx
เป็นดัชนีที่ใช้ 0 ของคอลัมน์ที่สี่เหลี่ยมจัตุรัสซ้ายสุดของ tetromino ที่หมุนควรจะไป เหล่านั้นr
และx
จะต้องถูกต้องคือ0 ≤ r ≤ 3
และ0 ≤ x ≤ 10-w
ที่w
อยู่ความกว้างของชิ้นส่วนที่เกี่ยวข้อง
โปรแกรมของคุณจะต้องถูกกำหนดไว้ - รับอินพุตเดียวกันมันต้องสร้างผลลัพธ์ที่เหมือนกันทุกประการ การใช้ PRNG นั้นใช้ได้ตราบใดที่มันยังเป็นแบบเม็ด
คะแนนรวมคือคะแนนจากเกมลบด้วยขนาดรหัสของคุณเป็นไบต์ โปรดใช้ไฟล์ต่อไปนี้ (64kiB ของสัญญาณรบกวนหลอกหลอก) เป็นอินพุต: https://gist.github.com/ngn/857bf2c99bfafc649b8eaa1e489e75e4/raw/880f29bd790638aa17f51229c105e726bce60235/i
สคริปต์ python2 / python3 ต่อไปนี้อ่านไฟล์ "i" และ "o" จากไดเรกทอรีปัจจุบันรีเพลย์เกมและพิมพ์คะแนน (โปรดอย่าลืมลบขนาดรหัสของคุณจากคะแนน):
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)
ดังนั้นโปรแกรม C ที่เร็วกว่าต่อไปนี้ แต่รับประกันได้ว่าจะใช้งานได้บน 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;}
คะแนนรวมสูงสุดชนะ ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม