Machen wir eine Karte des Dungeons

9

Vor langer Zeit, als ich mehr Zeit mit Rollenspielen verbrachte, bestand eines der Probleme einiger Spieler darin, die Partybewegung zu verfolgen und die richtige Karte zu zeichnen. Also habe ich eine Idee, um zu überprüfen, wie ihr mit diesem Problem umgeht.

Aufgabe ist es, eine Funktion zu schreiben, die als Eingabeparameter Liste der Richtungen (als Struktur Ihrer Wahl übergeben) verwendet ^v<>, Karte des Dungeons anzuzeigen. Im Beispiel für Eingabe: >>>vvv<<<^^^Ausgabe ist:

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

Testfälle

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



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


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

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

Da es sich um eine Golfcode-Herausforderung handelt, gewinnt der kürzeste Code.

Viel Spaß beim Golfen.

BEARBEITEN Entschuldigung für die späte Bearbeitung, ich hatte in letzter Zeit nicht viel Zeit.

Die Karte wird basierend auf der Bewegung generiert. Es sollte nur Korridore enthalten, die während des Spaziergangs besucht wurden. Daher ist die Schaffung eines großen Raums keine gültige Antwort.

Die Karte enthält drei gültige Symbole:

  • | vertikale Wand
  • | horizontale Wand
  • + Schnittpunkt von vertikaler und horizontaler Wand.

Die maximale Länge des Pfades beträgt 255 Zeichen (aber wenn Sie können, beschränken Sie sich nicht).

Weitere Testfälle:

 ><><><><

 +--+
 |  |
 +--+

 >^<v

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

Ich hoffe jetzt ist alles klar.

user902383
quelle
3
Sie müssen eine Beschreibung der Aufgabe bereitstellen. Die beiden Testfälle werden nicht einmal auf eine Weise behandelt, die konsistent erscheint - der erste fügt ohne ersichtlichen Grund einen getrennten Bereich hinzu.
Feersum
3
Ihr zweites Beispiel hat einen abgeschlossenen Raum, was ich anfangs dachte, weil der äußere Rand rechteckig sein sollte, aber das dritte Beispiel widerlegt diese Idee. Bitte benutze die Sandbox , um vor dem Posten Feedback zu einer Herausforderung zu erhalten.
El'endia Starman
2
Ausgezeichnet. Ich würde immer noch vorschlagen, explizit anzugeben, wie der Dungeon aus den Bewegungen aufgebaut ist.
El'endia Starman
1
Was meinst du mit "Karte anzeigen"? Ist das Zurückgeben der Karte von einer Funktion zulässig?
Paul Schmitz
3
Das sieht interessant aus. Gibt es eine Chance zur Bearbeitung, um es wieder zu öffnen? Besonders zu beachtende Dinge: Aus den Beispielen geht hervor, dass es Ihnen nichts ausmacht, zusätzliche Leerzeichen um die Ausgabe herum zu verwenden, aber es wäre gut, dies zu klären. Auch wenn Sie das Erscheinungsbild der Wand explizit beschreiben und die Frage der Milch beantworten, sollte die Frage ausreichend klar sein. Eine Sache, von der ich denke, dass Sie sie nicht behandelt haben, ist, welche Ausgabe vvv>>^^^<<(Kreuze? Rohre?) Produzieren würde
Dave

Antworten:

3

Javascript (ES6), 261 254 243 Bytes

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

Arnauld
quelle
Sie können das entfernen, returnindem Sie das ;mit ,und das {}mit ()
ersetzen
@Cyoce - Es gibt dort eine forSchleife, die auf diese Weise nicht eingebettet werden kann.
Arnauld
Ersetzen Sie dann das {mit eval("und }mit "), um den Rückgabecode zu entfernen. codegolf.stackexchange.com/a/80967/41042
Cyoce
@Cyoce - Leider denke ich, ich müsste dem wörtlichen Zeilenumbruch entkommen, als '\\n'ob ich das tue. Wenn ich richtig zähle, führt das tatsächlich zu +1 Byte. Oder gibt es eine bessere Möglichkeit, den Zeilenumbruch in die Bewertung einzubetten?
Arnauld
Sie würden nur brauchen, \nda Vorlagenzeichenfolgen wörtlich neue Zeilen unterstützen, aber das würde es immer noch bei der gleichen Byteanzahl belassen. Na
ja
3

C 246 Bytes

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

Übernimmt die Eingabe als separate Zeichen, zum Beispiel:

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

Oder bequemer dieses (absichtlich nicht zitierte!) Format:

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

Oder für (ziemlich ineffiziente) zufällige Eingaben:

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

Und schließlich awkbedeutet das Zuschneiden des Ergebnisses, dass wir viel größer werden können:

./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)}}'

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

Ausgaben an stdout. Verwendet die Tatsache, dass das Auffüllen der Karte zulässig ist (erzeugt eine Karte mit einer Kantenlänge von 2 * n + 1, wobei die endgültige Position in der Mitte liegt).

Nervenzusammenbruch

Dies funktioniert, indem die Argumente in umgekehrter Reihenfolge durchlaufen und in umgekehrter Reihenfolge verschoben werden. Es wird tatsächlich die Tatsache verwendet, dass arg 0 der Programmname ist. Es spielt keine Rolle, wie der Name lautet, aber es ermöglicht uns, sowohl die erste als auch die letzte Zelle (sowie alle dazwischen liegenden Zellen) zu besuchen, ohne dass eine besondere Behandlung erforderlich ist.

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)
}
Dave
quelle