टेट्रिस रणनीति


18

आपका कार्य स्कोर बनाम कोड आकार के संदर्भ में एक टेट्रिस रणनीति को लागू करना है।

खेल के इस संस्करण में टेट्रोमिनो को 20 पंक्तियों और 10 स्तंभों के ग्रिड में ऊपर से घुमाया और गिराया जाता है। गिरते समय, उन्हें घुमाया नहीं जा सकता है या क्षैतिज रूप से स्थानांतरित नहीं किया जा सकता है। हमेशा की तरह, एक गिरा हुआ टुकड़ा बंद हो जाता है जब यह ग्रिड के नीचे तक पहुंच जाता है या जब आगे की ओर नीचे की गति पहले से ही कब्जे वाले वर्ग के साथ टकराव का कारण होगी।

जब nक्षैतिज रेखाएं पूरी तरह से भर जाती हैं, तो वे एक साथ गिर जाती हैं, nशीर्ष पर खाली लाइनों के साथ ग्रिड को फिर से भर दिया जाता है , और स्कोर को 2 एन -1 अंक द्वारा बढ़ाया जाता है। n= 1,2,3,4 के लिए क्रमशः 1,3,7,15 अंक हैं। लाइनों के गायब होने के बाद, कुछ ब्लॉक हवा में तैरते रह सकते हैं (कोई " गुरुत्वाकर्षण श्रृंखला प्रतिक्रिया " नहीं है)।

जब वांछित होने के लिए वर्तमान टुकड़े के लिए कोई कमरा उपलब्ध नहीं होता है, तो ग्रिड को मंजूरी दे दी जाती है, वर्तमान टुकड़े को अनदेखा कर दिया जाता है, और खेल अगले टुकड़े के रूप में चालू रहता है। उसके लिए कोई दंड नहीं है।

आपको टुकड़ों के प्रकारों की एक धारा को पढ़ना चाहिए और यह तय करना चाहिए कि उन्हें कैसे घुमाना है और उन्हें कहां छोड़ना है। अगले टुकड़ा (सिर्फ एक) के लिए देखो आगे की अनुमति है: आप टुकड़ा देख सकते हैं i+1का जवाब देने से पहले i, लेकिन आप के भाग्य का फैसला किया है चाहिए iपर देख से पहले i+2। इनपुट के अंतिम टुकड़े से परे कोई लुक-फॉरवर्ड उपलब्ध नहीं है।

टेट्रोमिनो प्रकार और उनके घुमाव निम्नलिखित तालिका के अनुसार एन्कोड किए गए हैं:

        type 0    1    2    3    4    5    6
             O    I    Z    J    L    S    T
            ┌────┬────┬────┬────┬────┬────┬────┐
 rotation 0 │##  │#   │##  │ #  │#   │ ## │### │
            │##  │#   │ ## │ #  │#   │##  │ #  │
            │    │#   │    │##  │##  │    │    │
            │    │#   │    │    │    │    │    │
            ├────┼────┼────┼────┼────┼────┼────┤
          1 │##  │####│ #  │### │  # │#   │#   │
            │##  │    │##  │  # │### │##  │##  │
            │    │    │#   │    │    │ #  │#   │
            │    │    │    │    │    │    │    │
            ├────┼────┼────┼────┼────┼────┼────┤
          2 │##  │#   │##  │##  │##  │ ## │ #  │
            │##  │#   │ ## │#   │ #  │##  │### │
            │    │#   │    │#   │ #  │    │    │
            │    │#   │    │    │    │    │    │
            ├────┼────┼────┼────┼────┼────┼────┤
          3 │##  │####│ #  │#   │### │#   │ #  │
            │##  │    │##  │### │#   │##  │##  │
            │    │    │#   │    │    │ #  │ #  │
            │    │    │    │    │    │    │    │
            └────┴────┴────┴────┴────┴────┴────┘

इनपुट बाइनरी है - बाइट्स का एक क्रम जिसका OIZJLSTअवशेष 7 से विभाजित होने पर टेट्रोमिनो के रूप में व्याख्या की जानी चाहिए । वे लगभग एक ही संभावना के साथ घटित होंगे (सिवाय इसके कि पहले कुछ प्रकार बहुत अधिक बार दिखाई दे सकते हैं क्योंकि 256 7 के एक से अधिक नहीं होने के कारण, लेकिन यह नगण्य होना चाहिए)। इनपुट स्टडिन से हो सकता है या "i" नामक फ़ाइल से या एक तर्क के रूप में पारित किया जा सकता है। आप एक ही बार में सभी इनपुट पढ़ सकते हैं, बशर्ते आप लुक-फ़ॉरवर्ड प्रतिबंध का पालन करना सुनिश्चित करें।

आउटपुट बाइनरी भी है - इनपुट के समान लंबाई के बाइट्स का एक क्रम। यह stdout या "o" नामक फ़ाइल या किसी फ़ंक्शन से परिणाम हो सकता है। प्रत्येक बाइट एन्कोड करता है r*16 + x, जहां rवांछित घुमाव है और xस्तंभ का 0-आधारित सूचकांक है जहां घुमाए गए टेट्रोमिनो के बाएं वर्ग को जाना चाहिए। उन rऔर xमान्य होना चाहिए, यानी 0 ≤ r ≤ 3और0 ≤ x ≤ 10-w , जहां wइसी टुकड़ा की चौड़ाई है।

आप कार्यक्रम निर्धारक होना चाहिए - एक ही इनपुट को देखते हुए, इसे बिल्कुल उसी आउटपुट का उत्पादन करना होगा। PRNG का उपयोग करना तब तक ठीक है जब तक कि यह कांस्टेबल बीज नहीं है।

कुल स्कोर खेल के अंक से बाइट्स में आपके कोड का आकार है। कृपया इनपुट के रूप में निम्न फ़ाइल (छद्म यादृच्छिक ध्वनि के 64kiB) का उपयोग करें: https://gist.github.com/ngn/857bf2c99bfafc649b8eaa1e489e75e4/raw/880f29bd790638aa1712f51229c105e726cece60235i

निम्नलिखित 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)

तो निम्नलिखित बहुत तेजी से सी कार्यक्रम करता है, लेकिन यह केवल लिनक्स पर काम करने की गारंटी है:

#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;}

उच्चतम कुल स्कोर जीतता है। मानक खामियों को मना किया जाता है।


जब वर्तमान टुकड़े के लिए कोई कमरा उपलब्ध नहीं है, जहां वांछित है तो आइए देखें कि क्या मैं इसे सही ढंग से समझता हूं। उदाहरण के लिए, यदि बाईं ओर का कॉलम पूरी तरह से भरा हुआ है और प्रोग्राम वहां अगला टुकड़ा रखना चाहता है, तो यह ग्रिड को साफ करने के लिए मजबूर करेगा, भले ही कहीं और कमरा हो। क्या वो सही है?
अरनौलद

@ अर्नुलद हाँ, सही है
ngn

क्या i फाइल के लिए ऑप्टिमाइज़ करना ठीक है ? अच्छी चुनौती, BTW!
अरनौलद

हां, यह मेरे / dev / urandom से आता है, इसलिए मुझे उम्मीद नहीं है कि इसमें शोषक पैटर्न होंगे। धन्यवाद :)
ngn

1
अधिक स्पष्ट: यह हमारे कोड में दुकान सहायक डेटा जो के लिए विशिष्ट है कानूनी है मैं जैसे, "इस कदम # 147 के बजाय एक टेट्रिस के लिए इंतज़ार कर पर स्पष्ट 2 लाइनों, अन्यथा ढेर बहुत अधिक जाना होगा?" (यह 'के साथ टुकड़ा मैं + 2 इनपुट फ़ाइल से मत देखो' संघर्ष के लिए प्रतीत नहीं होता।)
Arnauld

जवाबों:


7

सी, स्कोर: 4136 (4290 - 154 बाइट्स)

#include <stdio.h>
main(){int c,p=0,t[]={7,9,21,0,0,51,1,32,16,48,0,33,0,32,16,49};for(;(c=getchar())>=0;putchar(c)){c%=7;c=t[!c||!(10%c)?c:2*c+p++%4];}}

यह विचार है कि ब्लॉक S, Z, O, I निश्चित स्थानों और घुमावों का उपयोग करता है:

                  |
      s     z     |
      s s z z # # |
        s z   # # |
0 1 2 3 4 5 6 7 8 9

बाकी - जे, एल, टी - कुछ चक्रीय रोटेशन के साथ पहले तीन कॉलम में पैक किए जाते हैं।

Ungolfed संस्करण:

#include <stdio.h>
int main() {
    int c,p=0,t[] = {7,9,21,51, 1,32,16,48, 16,48,0,33, 0,32,16,49 };
    while ((c=getchar())!=EOF) {
            switch(c%7) {
            case 0: c = t[0]; break;
            case 1: c = t[1]; break;
            case 2: c = t[2]; break;
            case 3: c = t[4+p++%4]; break;
            case 4: c = t[8+p++%4]; break;
            case 5: c = t[3]; break;
            case 6: c = t[12+p++%4]; break;
            }
            putchar(c);
    }
    return 0;
}

सरल और कुशल - अच्छी तरह से किया!
21
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.