ダンジョンの地図を作ろう


9

昔、私がRPGのプレイに多くの時間を費やしていたとき、一部のプレイヤーが抱えていた問題の1つは、パーティーの動きを追跡して適切なマップを描くことでした。だから私はあなたたちがこの問題にどのように対処するのかをチェックするためのアイデアを思いつきます。

タスクは、(選択した構造体として渡される)方向の入力パラメーターリストを受け取り^v<>、ダンジョンのマップを表示する関数を記述することです。入力の例では、>>>vvv<<<^^^出力は次のようになります。

+----+               +----+
|    |               |>>>v|
| ++ |               |^++v|
| ++ |  because      |^++v|
|    |               |^<<<|
+----+               +----+

テストケース

>>>>>>vvvvv<<<<^^^>>v



 +-------+
 |       |
 +-+---+ |
   |   | |
   | + | |
   | +-+ |
   |     |
   +-----+


^^^^^vvv<<<^^vv>>>>>>>>vv>><<^^^^v>>>>v^<^

          +-+ 
       +-+| | +-++-+
       | || | | ++ ++
       | ++ +-+     |
       |        +-+ |
       +--+ +-+ +-+-+
          | | |   |
          +-+ +---+

ゴルフコードチャレンジなので最短コードが勝ちます。

幸せなゴルフ。

編集 遅い編集でごめんなさい、最近あまり時間がありませんでした。

地図は動きに基づいて生成されます。散歩中に訪れた廊下のみを含める必要があります。したがって、1つの大きな部屋を作成することは有効な答えにはなりません。

マップには3つの有効なシンボルがあります。

  • | 垂直壁
  • | 水平壁
  • + 垂直壁と水平壁の交点。

パスの最大長は255文字です(ただし、可能であれば自分で制限しないでください)。

その他のテストケース:

 ><><><><

 +--+
 |  |
 +--+

 >^<v

 +--+
 |  |
 |  |
 +--+

すべてが明確になったことを願っています。


3
タスクの説明を提供する必要があります。2つのテストケースは、一貫性があるように処理されることすらありません。最初のテストケースは、明確な理由なしに切断された領域を追加します。
— feersum

3
2番目の例には閉じた部屋がありますが、これは外側の境界線が長方形である必要があるために最初に考えたものですが、3番目の例はその考えに反しています。投稿する前に、サンドボックスを使用してチャレンジに関するフィードバックを取得してください。
— El'endiaスターマン2016

2
優秀な。ダンジョンがムーブメントからどのように構築されるかについては、はっきりと述べておくことをお勧めします。
— El'endiaスターマン

1
「地図を表示」とはどういう意味ですか?関数からマップを返すことはできますか?
— Paul Schmitz

3
これは面白いですね。編集して再び開く可能性はありますか?特に注意すべき点:例から見ると、出力の前後の余分な空白は気にしないように見えますが、明確にしておくとよいでしょう。また、壁の外観を明確に説明し、牛乳の質問に答えると、質問が十分に明確になります。あなたがカバーしていないと私が思うことの1つは、出力vvv>>^^^<<が生成するものです(クロス?パイプ?)
— Dave

回答:


3

JavaScript(ES6)、261 254 243バイト

s=>{v=Array(w=32);p=526;b=n=>v[n>>5]&(1<<(n&31));B=(n,i)=>b(p+n)|b(p-n)?i:0;[...0+s].map(c=>v[(p+=[0,1,-1,w,-w]['0><v^'.indexOf(c)])>>5]|=1<<(p&31));for(z='',p=0;p<w*w;z+=' |-+'[b(p)?0:B(1,1)|B(w,2)||B(31,3)|B(33,3)],p++%w||(z+=`
`));return z}

JSFiddle


あなたは削除することができますreturn置き換えることによって、;と,して{}と()
— Cyoce

@Cyoce- forそのように埋め込むことができないループがそこにあります。
— Arnauld 2016

次に、{とeval("を}で置き換えて")、戻りコード
— Cyoce

@Cyoce-残念ながら、文字通りの改行をエスケープする必要があると思います'\\n'。私が正しく数えると、実際には+1バイトになります。または、改行を評価に埋め込むより良い方法はありますか?
— Arnauld 2016

\nテンプレート文字列はリテラルの改行をサポートするため、必要なのはそれだけですが、それでも同じバイト数のままです。ああ
— Cyoce 2016

3

C、246バイト

n,y,*g,*p;main(c,v)char**v;{for(n=c*2+3,g=calloc(n*n,8),p=g+(n+1)*(c+1);c--;y=*v[c],p-=(y>70?n:1)*(y%5%4?-1:1))*p=1;for(y=n-1;--y;)for(c=n-1;c--;putchar(c?" |-++|-+"[*p?0:p[1]|p[-1]|(p[n]|p[-n])*2|(p[1+n]|p[1-n]|p[n-1]|p[-n-1])*4]:10))p=g+y*n+c;}

入力を個別の文字として受け取ります。次に例を示します。

./mapper '>' '>' '>' 'v' 'v' 'v' '<' '<' '<' '^' '^' '^'

またはより便利な、この(意図的に引用符で囲まれていない!)形式:

./mapper $(echo '>>>vvv<<<^^^' | fold -w1)

または(かなり非効率的な)ランダム入力の場合:

./mapper $(LC_CTYPE=C tr -dc '0-3' < /dev/urandom | tr '0123' '<>^v' | head -c 10 | fold -w1)

そして最後にawk、結果をトリミングするために使用すると、さらに大きくなる可能性があります。

./mapper $(LC_CTYPE=C tr -dc '0-3' < /dev/urandom | tr '0123' '<>^v' | head -c 500 | fold -w1) | awk '/[^ ]/{l=match($0,"\\+");if(l&&(l<L||!L))L=l;v[i++]=$0}END{for(;j<i;){l=v[j++];print substr(l,L,match(l," *$")-L)}}'

 +-----+
 |     |
 |     +-+  +-----+
 |       |+-+     |
++       +|      ++
|         |      |
|         +      +-+
+--+               |
 +-+               +--+
 |     ++             |
 +-+  +-++           +-+
   ++   |+--+          |
    +-+ | |        ++  |
     ++ | ++   + +--+ ++
     |  |  +---|      |
     |  |     ++  +---+
     ++ |-+   |   |
      | | +--+-+  |
      | +    +    |
      |        +--+
      +--------+

stdoutに出力します。マップの周囲にパディングが許可されているという事実を使用します(エッジの長さが2 * n + 1で、最終的な位置が中央になるマップを生成します)。

壊す

これは、引数を逆にループして逆に移動することで機能します。実際には、arg 0がプログラム名であるという事実を使用しています。名前は何でもかまいませんが、特別な処理を必要とせずに、最初と最後の両方のセル(およびその間のすべてのセル)にアクセスできます。

n,                                  // Size of internal grid
y,                                  // Loop counter / current character
*g,                                 // Internal grid memory
*p;                                 // Current working pointer
main(c,v)char**v;{                  // K&R style function declaration
    for(                            // Step 1: identify visited cells
        n=c*2+3,                    //  Set output grid size
        g=calloc(n*n,8),            //  Allocate map storage space
        p=g+(n+1)*(c+1);            //  Start at centre
        c--;                        //  Loop over directions in reverse
        y=*v[c],                    //  Get current direction
        p-=(y>70?n:1)*(y%5%4?-1:1)  //  Move in reverse
    )*p=1;                          //  Mark cell visited
    for(y=n-1;--y;)                 // For each row (except edges)
        for(c=n-1;c--;              //   For each column (except edges, +1 for \n)
            putchar(c?" |-++|-+"[   //   Print wall using lookup table
                *p?0:p[1]|p[-1]|(p[n]|p[-n])*2|(p[1+n]|p[1-n]|p[n-1]|p[-n-1])*4
            ]:10)                   //   Or newline
        )p=g+y*n+c;                 //   Set current cell (happens first)
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.