কোনও ছদ্মবেশীর জন্য একটি মানচিত্র তৈরি করুন


10

আজ, আমরা কোনও রোগেলাইক আরপিজির জন্য একটি মানচিত্র তৈরি করব!

উদাহরণ মানচিত্র:

##########
####    F#
####    ##
##    C#C#
#     ## #
# C   #E #
####  #  #
#        #
#P       #
##########

#দেয়াল Pহয়, প্লেয়ারের আরম্ভের অবস্থান, Fএটি সমাপ্তি হওয়া উচিত, Cসংগ্রহ করা যায় এমন মুদ্রা এবং Eলড়াই করা যেতে পারে এমন শত্রু।

মানচিত্রের বিশদকরণ:

  • উচ্চতা এবং প্রস্থ উভয়ই 10 এবং 39 এর মধ্যে হওয়া উচিত। উচ্চতার সমান প্রস্থের দরকার নেই।
  • মানচিত্রের সীমানা দেয়াল দিয়ে পূরণ করা উচিত।
  • P নীচে বাম কোণে স্থাপন করা উচিত।
  • F উপরের ডান কোণে স্থাপন করা উচিত।
  • সেখানে 1 থেকে 3 শত্রু হওয়া উচিত।
  • 2 এবং 4 কয়েনের মধ্যে থাকা উচিত।
  • মাঝখানে কিছু পরিমাণ দেয়াল থাকা উচিত। একটা পথ থেকে পেতে হওয়া উচিত Pপ্রতিটি থেকে C, EএবংF , মনে রেখে যে প্লেয়ার তির্যকভাবে সরাতে পারবেন না।
  • প্রতিটি সম্ভাব্য সংমিশ্রণের কিছুটা ঘটনার সম্ভাবনা থাকা উচিত।

বিধি

  • সবচেয়ে কম বাইট প্রোগ্রাম জিতেছে।
  • আপনার প্রোগ্রামটির কোনও ইনপুট নেওয়া উচিত নয়।
  • আপনার প্রোগ্রামটি ত্রুটির সাথে প্রস্থান করতে পারে না (অ-প্রাণঘাতী আউটপুট STDERRঠিক আছে, তবে মানচিত্র তৈরির পরে আমাদের দুর্বৃত্তের মতো ক্রাশ থাকতে পারে না!)
  • একটি একক পেছনের নতুন লাইনের অনুমতি এবং ট্রেলিং স্পেসের অনুমতি রয়েছে।
  • অন্য কোনও আউটপুট অনুমোদিত নয়।

3
এটা রগুয়েলাইক, শুধু এফআই।
Rɪᴋᴇʀ

2
আপনি কি "প্রতিটি সম্ভাব্য সংমিশ্রণের সমান সম্ভাবনা থাকা উচিত" তা পরিষ্কার করতে পারেন? আপনি কি আক্ষরিকভাবে বোঝাতে চাইছেন যে সমস্ত বৈধ মানচিত্র (বিশেষত, সমস্ত মানচিত্র যেখানে পি সমস্ত সি / ই / এফএসে পৌঁছতে পারে) সমান সম্ভাবনার সাথে অবশ্যই ঘটতে পারে? যদি তা হয় তবে মনে হয় একমাত্র সম্ভাব্য অ্যালগরিদম হ'ল এলোমেলোভাবে অভিন্ন মানচিত্র তৈরি করা এবং তারপরে যা ঘটেছিল অবধি অবৈধ মানচিত্রগুলি বর্জন করে পি সমস্ত কিছুতে পৌঁছতে পারে তা পরীক্ষা করে দেখুন।
গ্রেগ মার্টিন

আপনি কি আরও পরিষ্কার করতে পারেন - "মাঝখানে কিছু পরিমাণ দেয়াল থাকা উচিত", আমি যদি সারাক্ষণ কেবল 2 টি দেয়াল রাখি তবে কী হবে?
গুরুপদ মামাদাপুর

1
@ গ্রেগমার্টিন আমি এটিকেও পরিবর্তন করব "প্রতিটি সম্ভাব্য বিন্যাসে সংঘটিত হওয়ার সুযোগ থাকা উচিত", সমান সুযোগের প্রয়োজন হয় না।
পাভেল

2
প্রাচীর দ্বারা পরিবেষ্টিত অদম্য খালি স্কোয়ার সম্পর্কে কী? এটি কি বৈধ বিন্যাস বা এগুলি পুরোপুরি এড়ানো উচিত? (অন্য কথায়: প্রতিটি খালি চৌকোটি কি
পৌঁছনীয়

উত্তর:


5

পার্ল, 293 বাইট

-9 বাইটস @ ডোম হেস্টিংসকে ধন্যবাদ

{$==7+rand 30;@r=$"=();@a=((C)x4,(E)x3,("#")x1369,(" ")x1369);for$i(0..7+rand 30){$r[$i][$_]=splice@a,rand@a,1for 0..$=}$r[0][$=]=F;$r[-1][0]=P;$_=$r=join$/,$v="#"x($=+=3),(map"#@$_#",@r),$v;1while$r=~s/F(.{$=})?[^#F]/F$1F/s||$r=~s/[^#F](.{$=})?F/F$1F/s;$r!~/[CEP]/&&/C.*C/s&&/E/?last:redo}say

-Eএটি চালানোর জন্য পতাকা যুক্ত করুন :

perl -E '{$==7+rand 30;@r=$"=();@a=((C)x4,(E)x3,("#")x1369,(" ")x1369);for$i(0..7+rand 30){$r[$i][$_]=splice@a,rand@a,1for 0..$=}$r[0][$=]=F;$r[-1][0]=P;$_=$r=join$/,$v="#"x($=+=3),(map"#@$_#",@r),$v;1while$r=~s/F(.{$=})?[^#F]/F$1F/s||$r=~s/[^#F](.{$=})?F/F$1F/s;$r!~/[CEP]/&&/C.*C/s&&/E/?last:redo}say'

তবে এটি চালাতে দীর্ঘ সময় লাগে, সুতরাং পরিবর্তে আমি এই সংস্করণটি ব্যবহার করার পরামর্শ দিচ্ছি:

perl -E '{${$_}=8+rand 30for"=","%";@r=$"=();@a=((C)x4,(E)x3,("#")x($v=rand $=*$%),(" ")x($=*$%-$v));for$i(0..$%-1){$r[$i][$_]=splice@a,rand@a,1for 0..$=-1}$r[0][$=-1]=F;$r[$%-1][0]=P;$_=$r=join$/,$v="#"x($=+=2),(map"#@$_#",@r),$v;1while$r=~s/F(.{$=})?[^#F]/F$1F/s||$r=~s/[^#F](.{$=})?F/F$1F/s;$r!~/[CEP]/&&/C.*C/s&&/E/?last:redo}say'

এটি অনলাইন চেষ্টা করুন!

ব্যাখ্যা

{ # একটি ব্লক প্রবেশ করুন (যা লুপ হিসাবে ব্যবহৃত হয়) { $ == 7 + র‌্যান্ড 30 ; # এলোমেলোভাবে মানচিত্র প্রস্থ -2 নির্বাচন # (-2 কারণ আমরা এখনো সীমানা অন্তর্ভুক্ত করবেন না) @r = $ ; "# রিসেট @r, এবং সেট $ = ()" থেকে undef @a = ( # তৈরি বোর্ডে ( সি ) x4 , # 4 কয়েন 'সি' ( ) x3 , # 3 শত্রু 'ই' ( "#" ) x1369 , # 37 * 37 '#' ( বোর্ডে থাকা চরিত্রের একটি তালিকা                     
                       
                                     
    
                                 
                               
                               
                          
     "" ) x1369 ); # 37 * 37 শূণ্যস্থান জন্য $ i এর ( 0..7 + + রান্ড 30 ) # 2D মানচিত্র তৈরি (7 + + রান্ড 30 উচ্চতা, যা এইমাত্র উৎপন্ন হয় হয়) জন্য $: _ ( 0. $ = - 1 ) { 
        $ r [ $ i ] [ $ _ ] = # সূচক [$ i] [$ _] প্রাপ্ত ... 
           স্প্লাইস @ এ , র্যান্ড @ এ , 1 # .. আগে উত্পন্ন তালিকা থেকে একটি এলোমেলো চরিত্র # (চরিত্রটি হ'ল তারপরে তালিকা থেকে অপসারণ করা হয়েছে 'স্প্লাইস' এর জন্য ধন্যবাদ) } } 
    $ r [                    
                     
                                     
                                       
      
     0 ] [ $ =] = এফ ; # সমাপ্ত সেলটি যোগ করুন - 
    r [- 1 ] [ 0 ] = পি ; # শুরুর ঘরটি যোগ করুন 
    $ _ = $ আর                                               = # এখানে আমরা মানচিত্রের একটি স্ট্রিং উপস্থাপনা উত্পন্ন করি 
          $ /, # নতুন উপাদানগুলির সাথে নিম্নলিখিত উপাদানগুলিতে যোগদান করুন 
            $ v = "#" x ( $ = + = 3 ), # প্রথম # লাইন শুধুমাত্র ( ম্যাপ "# @ $: _ #" , @r ), # শুরুতে এবং প্রতিটি লাইনে শেষে একটি # যোগ                                                               
                       
            $ v ; # শেষ লাইন                        

    1 ততক্ষণে # নীচের রেজেক্স প্রতিটি অ্যাক্সেসযোগ্য কক্ষকে F 
       $ r = ~ s / F (। { $ = =}) দিয়ে প্রতিস্থাপন করবে ? [^ # F ] / F $ 1F / s   # একটি ঘর ডান বা নীচে একটি ঘর এফ সেল প্রতিস্থাপন করা হয়েছে   || # বা 
       $ আর = ~ এস / [^ # এফ ] (। { $ =})? এফ / এফ $ 1 এফ / এস ; # বামে বা একটি এফ কোষের শীর্ষে একটি ঘর replaced 
    r ! ~ / [সিইপি] / # প্রতিস্থাপন করা হয়েছে যদি মানচিত্রে সি, ই বা পি না থাকে (যার অর্থ তারা সকলেই অ্যাক্সেসযোগ্য ছিল) &&                
                                            
      / সি.এ.সি.সি / এস          # এবং কমপক্ষে 2 টি মুদ্রা && / ই / আছে ? # এবং 1 শত্রু শেষ : # মানচিত্রটি বৈধ, আমরা লুপটি আবারও প্রস্থান করব # আবার শুরু করুন } 
বলুন                      # এবং বোর্ডটি মুদ্রণ করুন
                  
                   
                    

এটি চালাতে দীর্ঘ সময় লাগে, কারণ আমরা যে তালিকা থেকে এলোমেলোভাবে বোর্ডে রাখার জন্য অক্ষরগুলি বেছে নিয়েছি ( @a) এতে 1369 হোয়াইটস্পেস #এবং কেবল 4 টি মুদ্রা এবং 3 শত্রু রয়েছে। সুতরাং প্রস্থ এবং উচ্চতার আকার যদি ছোট হয় তবে প্রচুর জায়গা রয়েছে এবং #মুদ্রা এবং শত্রুদের সাথে তুলনা করা যায়, তাই সম্ভবত এটি সম্ভবত এলোমেলো মানচিত্র বৈধ হবে না likely (তালিকা হল: কেন "অপ্টিমাইজ" সংস্করণ দ্রুততর এটা তালিকা যেখান থেকে আমরা অক্ষর বাছাই শুধু একটু মানচিত্র চেয়ে বড় @a=((C)x4,(E)x3,("#")x($v=rand $=*$%),($")x($=*$%-$v)): একটি র্যান্ডম সংখ্যা $vএর #(মানচিত্রে আকার নিকৃষ্ট), এবং size of the map - $vঅনুসরণকারী শূণ্যস্থান)।


আমি আসলে পার্ল জানি না, তবে সিনট্যাক্স হাইলাইট করে আপনার ($ ") x $ = ** 2) এর সাথে তুলনামূলক একটি উক্তি পাওয়া গেছে বলে মনে হচ্ছে ;.আর হাইলাইট করা সঠিকভাবে কাজ করে না এবং এটি একটি বৈশিষ্ট্য। এছাড়াও , হোয়াইটস্পেস অ্যাক্সেসযোগ্য হতে পারে
পাভেল

1
@ পাভেল $"একটি আইনী পার্ল পরিবর্তনশীল, তবে সিনট্যাক্স হাইলাইট করা এটি সম্পর্কে জানে না, এজন্য এটি দেখতে এটির মতো দেখাচ্ছে। ঠিক আছে, আমি না পারা যায় না এমন জায়গাগুলি সম্পর্কে মন্তব্য মুছব।
দাদা

5

পিএইচপি, 422 417 415 309 373 369 364 361 বাইট

function w($p){global$r,$h,$w;for($q=$p;$r[$q]<A;)for($r[$p=$q]=" ";($q=$p+(1-(2&$m=rand()))*($m&1?:$w))%$w%($w-1)<1|$q/$w%$h<1;);}$r=str_pad("",($w=rand(10,39))*$h=rand(10,39),"#");$r[$w*2-2]=F;w($p=$q=$w*(--$h-1)+1);$r[$p]=P;for($c=rand(2,4);$i<$c+rand(1,3);$p=rand($w,$h*$w))if($r[$p]<A&&$p%$w%($w-1)){w($p);$r[$p]=EC[$i++<$c];w($p);}echo chunk_split($r,$w);

লাইনব্রেক ছাড়াই একটি স্ট্রিংয়ে চালিত হয়; অতিরিক্তগুলির মধ্যে এলোমেলো পাথ খনন করে। সাথে চালাও -r

দ্রষ্টব্য: পাথগুলি এলোমেলো দিক দিয়ে চলার মাধ্যমে তৈরি করা হয়েছে। প্রতিটি পদক্ষেপের জন্য দিকনির্দেশের পছন্দটি বেশিরভাগ মানচিত্র তৈরি করে যা প্রশস্ত উন্মুক্ত; এবং উদাহরণস্বরূপ মানচিত্রটি উপস্থিত হওয়ার খুব কম সম্ভাবনা রয়েছে; কিন্তু এটা হয় সম্ভব।

ভাঙ্গন

// aux function: randomly walk away from $p placing spaces, stop when a special is reached
function w($p)
{global$r,$h,$w;
    for($q=$p;
        $r[$q]<A;                               // while $q is not special
    )
        for($r[$p=$q]=" ";                          // 3. replace with space
            ($q=$p+(1-(2&$m=rand()))*($m&1?:$w))    // 1. pick random $q next to $p
            %$w%($w-1)<1|$q/$w%$h<1;                // 2. that is not on the borders
        );
}

// initialize map
$r=str_pad("",
    ($w=rand(10,39))*$h=rand(10,39) // random width and height
    ,"#");                          // fill with "#"
$r[$w*2-2]=F;                       // place Finish
w($p=$q=$w*(--$h-1)+1);             // build path from Player position to F
// $h is now height -1 !
$r[$p]=P;                           // place Player

// place Coins ans Enemies
for($c=rand(2,4);$i<$c+rand(1,3);   // while $i has not reached no. of coins+no. of enemies
    $p=rand($w,$h*$w))              // pick a random position
    if($r[$p]<A&&$p%$w%($w-1))      // that is neither special nor out of bounds
    {
        w($p);                      // build path from there to another special
        $r[$p]=EC[$i++<$c];         // place this special
        w($p);      // additional path to allow special in the middle of a dead end tunnel
    }

// insert linebreaks and print
echo chunk_split($r,$w);

আপনার ব্যাখ্যায় আপনি 39 এবং উচ্চতা এবং প্রস্থটি 39 এ উত্পাদন করছেন না
পাভেল

@ পাভেল স্থির; লক্ষ্য করার জন্য ধন্যবাদ
টিটাস


@ পাভেল আপনাকে কোডটি ঘিরে থাকা দরকার<?php .... ?>
দাদা

1
ঠিক আছে, আমি এটি করেছি এবং আমি লক্ষ্য করেছি যে নিয়মিত আয়তক্ষেত্রাকার অংশে দেয়ালগুলি উত্পন্ন হয়। এটি উদাহরণ মানচিত্রের মতো কিছু তৈরি করতে সক্ষম হওয়া উচিত। এটি সর্বদা Eএস উত্পাদন করে না ।
পাভেল

3

সি # (ভিজ্যুয়াল সি # ইন্টারেক্টিভ সংকলক) , 730 বাইট

var R=new Random();for(;;){char P='P',C='C',E='E',Q='#';int w=R.Next(8,37),h=R.Next(8,37),H=h,t,g=99,W,i,j,r;string l,s,p=new string(Q,w+2);var m=new List<string>();for(;H>0;H--){l="";for(W=w;W>0;W--){r=R.Next(999);l+=r<3?C:r<6?E:r<g?Q:' ';}m.Add(l);}m[0]=m[0].Substring(0,w-1)+'F';m[h-1]=P+m[h-1].Substring(1);s=String.Join("#\n#",m);t=s.Split(E).Length-1;if(t<1||t>3)continue;t=s.Split(C).Length-1;if(t<2||t>4)continue;while(g>0){g--;for(i=0;i<h;i++)for(j=0;j<w;j++)if(m[i][j]!=Q&&m[i][j]!=P&&(i>0&&m[i-1][j]==P)||(i<h-1&&m[i+1][j]==P)||(j>0&&m[i][j-1]==P)||(j<w-1&&m[i][j+1]==P))m[i]=m[i].Substring(0,j)+P+m[i].Substring(j+1,w-j-1);}if(String.Join("",m).Split(E,C,'F').Length>1)continue;Console.Write(p+"\n#"+s+"#\n"+p);break;}

এটি অনলাইন চেষ্টা করুন!

Ungolfed:

var R = new Random();
for (;;)
{
    char P = 'P', C = 'C', E = 'E', poundSymbol = '#';
    int width = R.Next(8, 37), height = R.Next(8, 37), HeightTemp = height, testVariable, goThroughLoop = 99, WidthTemp, i, j, rand;
    string line, strMap, poundSymbolPadding = new string(poundSymbol, width + 2);

    var map = new List<string>(); //initialize map
    for (; HeightTemp > 0; HeightTemp--)
    {
        line = "";
        for (WidthTemp = width; WidthTemp > 0; WidthTemp--)
        {
            rand = R.Next(999);
            //add a character randomly.  Re-use the goThroughLoop variable here, which gives approx. 1 wall per 10 spaces.
            line += rand < 3 ? C : rand < 6 ? E : rand < goThroughLoop ? poundSymbol : ' ';
        }
        map.Add(line);
    }
    //add finish and player
    map[0] = map[0].Substring(0, width - 1) + 'F';
    map[height - 1] = P + map[height - 1].Substring(1);

    strMap = String.Join("#\n#", map);
    //check proper # of enemies, regenerate if invalid
    testVariable = strMap.Split(E).Length - 1;
    if (testVariable < 1 || testVariable > 3)
        continue;
    //check proper # of coins, regenerate if invalid
    testVariable = strMap.Split(C).Length - 1;
    if (testVariable < 2 || testVariable > 4)
        continue;
    //map out areas Player can access.  Iterates until all accessible places have been marked as such.
    while (goThroughLoop > 0)
    {
        goThroughLoop--;
        for (i = 0; i < height; i++)
            for (j = 0; j < width; j++)
                if (map[i][j] != poundSymbol && map[i][j] != P && ((i > 0 && map[i - 1][j] == P) || (i < height - 1 && map[i + 1][j] == P) || (j > 0 && map[i][j - 1] == P) || (j < width - 1 && map[i][j + 1] == P)))
                    //mark this space as accessible
                    map[i] = map[i].Substring(0, j) + P + map[i].Substring(j + 1, width - j - 1);
    }
    //if player cannot access all features (defeated enmies, collected coins, arrived at finish), regenerate map.
    if (String.Join("", map).Split(E, C, 'F').Length > 1)
        continue;

    //output our final map
    Console.Write(poundSymbolPadding + "\n#" + strMap + "#\n" + poundSymbolPadding);

    break;
}

সম্পাদনা: 8 বাইট সংরক্ষণ করা, প্লেয়ারের অ্যাক্সেসযোগ্য টেস্ট লুপটিকে 99 পুনরাবৃত্তিতে লক করে কিছুটা কম দক্ষ করে তুলেছেন। আমি জানি এটি এখানে অন্য উত্তরগুলির সাথে সত্যিই প্রতিযোগিতা করবে না, তবে আমি মজা করছি!


@ গ্রেগমার্টিন এখন এফ # ;-) এ প্রয়োগ করার আপনার পালা
বেঁস জোফুল

2
সাবডমিনেন্টের কাছে একটি সহজ মড্যুলেশন, কোনও সমস্যা নেই :)
গ্রেগ মার্টিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.