টেট্রিসের একটি খেলায় সেরা পদক্ষেপটি সন্ধান করুন


10

আমি টেট্রিসকে অনেক পছন্দ করি তবে আমি এতে খুব একটা ভাল না। আমি একবার দেখতে চাই যে স্পেসশিপটি আমার নিজের চোখের সামনে তুলে ফেলছে! এবং যেহেতু কম্পিউটারগুলি সমস্ত কিছুতে দুর্দান্ত, তাই আমার পক্ষে এটি চালানোর জন্য একটি প্রোগ্রাম তৈরি করা একমাত্র সম্ভাব্য সমাধান ... আপনি যদি আমার জন্য কিছু না করেন তবে!

একটি টেট্রোমিনো (চার স্কোয়ার দিয়ে তৈরি আকৃতি) এবং খেলার ক্ষেত্রের মানচিত্র দেওয়া, আপনি টেট্রোমিনো এমনভাবে স্থাপন করতে পারেন যে এটি সর্বাধিক সংখ্যক রেখাকে স্কোর করে (সারিগুলির সর্বাধিক সংখ্যাকে সম্পূর্ণ ব্লকগুলিতে পূর্ণ করে তোলে) এবং সর্বনিম্ন সংখ্যা তৈরি করে এর নতুন গর্ত (একটি খালি জায়গা যে করতে পারবে না মাঠ উপরের "দেখতে" 1 )।

ইনপুট

ইনপুটটিতে একটি একক লাইনে এমন একটি অক্ষর থাকবে যা ড্রপিং টেট্রোমিনোকে উপস্থাপন করবে এবং তারপরে 10 * 18 গ্রিড 2 স্পেস ( ) এবং আরও চিহ্নগুলি ( +) উপস্থাপন করবে।

চরিত্রটি টেট্রিসে পাওয়া সাতটি বেস টেট্রোমিনোসের কোনওটির প্রতিনিধিত্ব করে। টুকরো সব 90 ডিগ্রি ঘোরানো যেতে পারে, কিন্তু উল্টানো হয় না। সমস্ত টিট্রোমিনো এবং তাদের ঘূর্ণন নিম্নরূপ:

         #
S =  ##  ##
    ##    #

          #
Z = ##   ##
     ##  #

    #   ###  ##
L = #   #     #    #
    ##        #  ###

     #  ###  ##
J =  #    #  #     #
    ##       #   ###

          #   #   #
T = ###  ##  ###  ##
     #    #       #

O = ##
    ##

    #
I = #  ####
    #
    #

গ্রিডটি +পূর্ব-স্থাপন করা ব্লকগুলি সহ টেট্রিসের প্লেয়িং ফিল্ডের প্রতিনিধিত্ব করে । সুতরাং, একটি উদাহরণ ইনপুট নিম্নলিখিত হতে পারে:

I











+       ++
+    +++++
++ +++++++
++ +++++++
++ +++++++
++ +++++++
++++++ +++

আউটপুট

আপনার আউটপুট ইনপুটটির মতো হবে তবে আদর্শ অবস্থানে থাকা টেট্রোমিনো সহ। #পূর্ব-স্থাপন করা ব্লকগুলি থেকে আলাদা করার জন্য টেট্রোমিনোকে প্রতিনিধিত্ব করা উচিত । এগুলি ছাড়াও, আপনি xL yHকোনও নতুন লাইনে আপনার অবস্থানটি আকারে কতগুলি লাইন / গর্ত তৈরি করে তা আউটপুটও করতে হবে।

উপরে বর্ণিত উদাহরণের আউটপুটটি নিম্নলিখিত 3 হবে :

I











+       ++
+    +++++
++#+++++++
++#+++++++
++#+++++++
++#+++++++
++++++ +++
4L 0H

আপনি কেবল সেরা ফলাফল (গুলি) আউটপুট দিতে পারবেন; দুই বা ততোধিক ক্ষেত্রে একই স্কোর দেওয়ার ক্ষেত্রে, আপনি তাদের সমস্ত আউটপুট দিতে হবে (ফাঁকা রেখার দ্বারা পৃথক)। প্রথমে স্কোর করা (উতরোত্তর) এর সংখ্যা অনুসারে বাছাই করে সর্বোত্তম ফলাফল নির্ধারণ করা হবে, তারপরে তৈরি নতুন গর্তের সংখ্যা (আরোহণ)। সুতরাং, 1L 1Hতুলনায় একটি ভাল স্কোর 0L 0H

আমি বিভিন্ন ইনপুট এবং প্রত্যাশিত আউটপুট (গুলি) এর একটি তালিকা তৈরিতে কাজ করব যা আপনি আপনার প্রোগ্রামটির বিরুদ্ধে পরীক্ষা করতে পারেন। এই স্থান দেখুন।

বিধি এবং বিশৃঙ্খলা

  • এটি , তাই সংক্ষিপ্ততম সঠিক প্রয়োগের জয়।
  • ইনপুট / আউটপুট এমন কোনও মাধ্যম হতে পারে যা আপনার টার্গেট ল্যাঙ্গুয়েজের (যেমন ফাইল, স্টিডিন / স্টাডআউট, পাঠ্য অঞ্চল) উপযুক্ত করে।
  • যদি আপনার টার্গেট ল্যাঙ্গুয়েজ একাধিক লাইন ইনপুট সমর্থন করে না (বা এটি করতে অসুবিধা হয়) তবে আপনি পরিবর্তে ইনপুটটির প্রতিটি লাইন কমা দিয়ে ( ,) করতে পারেন।
  • আপনি গ্রিডের কোনও ফাঁকা লাইনের আউটপুট বাদ দিতে পারেন।
  • মনে রাখবেন যে টেট্রোমিনো উপর থেকে পড়ে - আপনি টুকরোটি "ভূগর্ভস্থ" নাও রাখতে পারেন। সুতরাং আপনি ধরে নিতে পারেন যে টুকরোটির সমস্ত সম্ভাব্য প্লেসমেন্টগুলি "পৃষ্ঠ-স্তর" (যেমন পিস এবং বোর্ডের শীর্ষের মধ্যে কোনও ব্লক নেই) থাকবে।
  • ধরে নিন যে এমন কোনও পরিস্থিতি কখনই আসবে না যেখানে আপনাকে বাধ্য হয়ে কোনও খেলা শেষ করতে হবে (স্থাপন করা টেট্রোমিনো মাঠের শীর্ষ-কেন্দ্রে স্পর্শ করে)।
  • আউটপুটে অভিন্ন সমাধানগুলি অবশ্যই বাদ দিতে হবে (উদাহরণস্বরূপ, আপনি যদি সহজেই Oটুকরোটি ঘোরান তবে 3 টি সমাধান আউটপুট রয়েছে )।

1 আমি সচেতন যে এটি কিছু ভুল ধনাত্মক তৈরি করবে তবে এটি সরলকরণ ification

2 এটি গেম বয় সংস্করণে ব্যবহৃত গ্রিড আকার।

3 হ্যাঁ, 0Hসঠিক। আবার যাচাই করুন, আমি বললাম নতুন গর্ত; ^)


যদি কোনও টুকরোটি 1 টি নতুন গর্ত সৃষ্টি করে তবে 2 টি লাইন স্কোর করে বনাম কেবল 1 লাইন করে?
নাথান মেরিল

প্রথমে লাইনের সংখ্যা অনুসারে বাছাই করুন। 2 লাইন> 1 লাইন, তাই এটি গর্তের সংখ্যা যাই হোক না কেন তা জয়ী হয়।
শান ল্যাথাম

2
আপনি যদি একটি গর্ত মুক্ত করেন তবে এটি আপনাকে -1 এইচ দেয়?
ওভাররেেক্টর

এইচএম, আমি এটি ভাবিনি - এটি নিষ্পাপ গর্ত সংজ্ঞার ফলে ঘটতে পারে। হ্যাঁ, আমার ধারণা এটি হবে।
শান ল্যাথাম

আমার সমাধানে আমি গর্তগুলি মুক্ত করার বিষয়টি বিবেচনা করি নি। আমি সমস্যার সংজ্ঞাটি এমনভাবে বুঝতে পেরেছিলাম যে বিদ্যমান ব্লকগুলিকে সংশোধন করা উচিত নয়। সুতরাং কোনও সম্পূর্ণ লাইন অপসারণ করা উচিত এবং কোনও গর্ত মুক্ত করা উচিত নয়।
মিকাইল শেখ 5'14

উত্তর:


3

সি 1009 বাইট

#include <stdio.h>
#define L for(n=0;n<18;++n)
int T[19]={54,561,99,306,785,23,547,116,802,71,275,116,39,562,114,305,51,4369,15},W[19]={3,2,3,2,2,3,2,3,2,3,2,3,3,2,3,2,2,1,4},O[7]={0,2,4,8,12,16,17},R[7]={2,2,4,4,4,1,2},G[18],F[24],t=0,I,x,y,S[99],X[99],Y[99],N[99],s,M=0,i,j,k,l,m,n,h,c;char B[99],*C="SZLJTOI";void A(){for(m=0;m<24;++m)F[m]=0;for(m=0;m<4;++m)F[y+m]=(T[I]>>(m*4)&15)<<x;}void D(){S[s]=0;L S[s]+=(G[n]|F[n])==1023;S[s]=200*(S[s])+199;for(m=0;m<10;++m){l=0;L{h=(G[n]|F[n])&1<<m;l|=h;S[s]-=l&&!h;}}}int E(){A();c=0;L c|=G[n]&F[n];return !c;}int main(){S[0]=0;gets(B);while(C[t]!=B[0])++t;I=O[t];L{G[n]=0;gets(B);for(m=0;m<10;++m)G[n]|=(B[m]=='+')?(1<<m):0;}s=0;D();for(i=0;i<R[t];++i){for(x=0;x<10-W[I];x++){y=0;while(E())y++;--y;++s;A();D();if(S[s]>M)M=S[s];X[s]=x;Y[s]=y;N[s]=I;}I++;}for(i=1;i<s;++i)if(S[i]==M){j=i;x=X[i];y=Y[i];I=N[i];A();for(n=1;n<18;++n){for(m=0;m<10;++m)printf((G[n]&1<<m)!=0?"+":((F[n]&1<<m)!=0?"#":" "));printf("\n");}}printf("%dL %dH\n",S[j]/200,S[0]%200-S[j]%200);}

এখানে বর্ণহীন সংস্করণ

#include <stdio.h>

int tiles[19] = {54,561,99,306,785,23,547,116,802,71,275,116,39,562,114,305,51,4369,15};
int widths[19] = {3,2,3,2,2,3,2,3,2,3,2,3,3,2,3,2,2,1,4};
char *codes = "SZLJTOI";
int offsets[7] = {0,2,4,8,12,16,17};
int transformations[7] = {2,2,4,4,4,1,2};
int gameField[18], tileField[24];

int i,j,k,l,m,n,h;
char buffer[99];
int tile=0, tileIndex;
int xpos, ypos;
int scores[99], xplacements[99], yplacements[99], tindex[99];
int scoreIndex, maxScore=0;

void readGame()
{
  gets(buffer);
  while (codes[tile]!=buffer[0]) ++tile;
  tileIndex = offsets[tile];
  for (n=0;n<18;++n)
  {
    gameField[n] = 0;
    gets(buffer);
    for (m=0; m<10;++m)
      gameField[n] |= (buffer[m]=='+')?(1<<m):0;
  }
}

void writeGame()
{
  for (n=1;n<18;++n)
  {
    for (m=0; m<10;++m)
      printf( (tileField[n] & 1<<m) != 0 ? "#" :((gameField[n] & 1<<m) != 0 ? "+" :" "));
    printf("\n");
  }
}

void placeTile()
{
  for (m=0;m<24;++m) tileField[m] = 0;
  for (m=0;m<4;++m) 
    tileField[ypos+m] = (tiles[tileIndex]>>(m*4) & 15) << xpos;
}

void score()
{
  scores[scoreIndex] = 0;
  for (n=0;n<18;++n) 
    if ((gameField[n] | tileField[n])==1023) scores[scoreIndex]++;

  scores[scoreIndex] = 200*(scores[scoreIndex]) + 199;

  for (m=0;m<10;++m)
  {
    l=0;
    for (n=0;n<18;++n)
    {
      h = (gameField[n] | tileField[n]) & 1<<m;
      l |= h;
      scores[scoreIndex] -= l && !h;
    }
  }
}

int noCollision()
{
  placeTile();
  int coll = 0;
  for (n=0;n<18;++n) coll |= gameField[n] & tileField[n];
  return !coll;
}

int main()
{ scores[0] = 0;
  readGame();
  scoreIndex = 0;
  score();
  for (i=0; i<transformations[tile]; ++i)
  {
    for (xpos=0; xpos<10-widths[tileIndex]; xpos++)
    {
      ypos = 0;
      while (noCollision()) ypos++;
      --ypos;
      ++scoreIndex;
      placeTile();
      score();
      if (scores[scoreIndex]>maxScore) maxScore=scores[scoreIndex];
      xplacements[scoreIndex] = xpos;
      yplacements[scoreIndex] = ypos;
      tindex[scoreIndex] = tileIndex;
    }
    tileIndex++;
  }

  for (i=1;i<scoreIndex; ++i) 
    if (scores[i]==maxScore)
    {
      j=i;
      xpos = xplacements[i];
      ypos = yplacements[i];
      tileIndex = tindex[i];
      placeTile();
      writeGame();
    }

  printf("%dL %dH\n", scores[j]/200, scores[0]%200-scores[j]%200);
}

আমি দেখেছি যে দীর্ঘতম কোডের মূল উত্স সম্ভবত টাইলগুলির সংজ্ঞা হবে। সুতরাং আমি তাদের 4x4 বিট অ্যারে বিট নিদর্শন হিসাবে উপস্থাপন করার সিদ্ধান্ত নিয়েছি। এটি 16 টি বিটের ফলাফল যা সহজেই একটি একক মধ্যে ফিট করে inttilesঅ্যারে 7 টাইলস 19 সম্ভব ঘুর্ণন জন্য সব নিদর্শন ঝুলিতে।

সংকলন করার সময়, হ্রাস করা সতর্কতাটিকে উপেক্ষা করুন gets। আমি জানি এটি কিন্তু ইনপুট থেকে কোনও লাইন পড়ার সবচেয়ে সংক্ষিপ্ততম উপায়।


গ্লোবাল স্কেলে, আপনি intএটি অনুমান হিসাবে ড্রপ করতে পারেন । আপনার printfsএকমাত্র আউটপুট একাধিক একক অক্ষর। আপনি putcharকয়েকটি অক্ষর সংরক্ষণের সমতুল্য এগুলি প্রতিস্থাপন করতে সক্ষম হতে পারেন । উদাহরণস্বরূপ, :) এ পরিবর্তন printf("\n")করাputchar(10)
জোশ

আপনি যদি একটি নতুন লাইন চান তবে পুটস ("") আরও খাটো। এছাড়াও আপনি রিটার্ন ব্যবহার করতে পারেন! সি (কোনও স্থান নেই)। প্রথমবার যখন আপনি লুপের জন্য একটি সূচক ব্যবহার করেন, আপনি ভেরিয়েবলগুলি বিশ্বব্যাপী ঘোষিত হওয়ায় আপনি আরম্ভটি 0 থেকে বাদ দিতে পারেন। এছাড়াও, আমি মনে করি আপনি কেবলমাত্র E ফাংশনটি একবার ব্যবহার করেছেন তাই এটি কেবল ইনলাইন করা সম্ভব।
অ্যালকিমিস্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.